From c52febe6b25a4898a49c721cac569528867ad426 Mon Sep 17 00:00:00 2001 From: Jon Bray Date: Fri, 26 Jul 2024 19:24:27 -0400 Subject: [PATCH] chore: remove `lib` folder to re-init submodules --- .gitmodules | 15 - lib/forge-std/.gitattributes | 1 - lib/forge-std/.github/workflows/ci.yml | 128 - lib/forge-std/.github/workflows/sync.yml | 31 - lib/forge-std/.gitignore | 4 - 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/forge-std/package.json | 16 - lib/forge-std/scripts/vm.py | 635 - lib/forge-std/src/Base.sol | 35 - lib/forge-std/src/Script.sol | 27 - lib/forge-std/src/StdAssertions.sol | 669 - lib/forge-std/src/StdChains.sol | 259 - lib/forge-std/src/StdCheats.sol | 817 - lib/forge-std/src/StdError.sol | 15 - lib/forge-std/src/StdInvariant.sol | 122 - lib/forge-std/src/StdJson.sol | 179 - lib/forge-std/src/StdMath.sol | 43 - lib/forge-std/src/StdStorage.sol | 473 - lib/forge-std/src/StdStyle.sol | 333 - lib/forge-std/src/StdToml.sol | 179 - lib/forge-std/src/StdUtils.sol | 226 - lib/forge-std/src/Test.sol | 33 - lib/forge-std/src/Vm.sol | 1763 -- lib/forge-std/src/console.sol | 1552 -- lib/forge-std/src/console2.sol | 4 - 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 - lib/forge-std/src/interfaces/IMulticall3.sol | 73 - lib/forge-std/src/mocks/MockERC20.sol | 234 - lib/forge-std/src/mocks/MockERC721.sol | 231 - lib/forge-std/src/safeconsole.sol | 13248 ---------------- lib/forge-std/test/StdAssertions.t.sol | 145 - lib/forge-std/test/StdChains.t.sol | 226 - lib/forge-std/test/StdCheats.t.sol | 618 - lib/forge-std/test/StdError.t.sol | 120 - lib/forge-std/test/StdJson.t.sol | 49 - lib/forge-std/test/StdMath.t.sol | 212 - lib/forge-std/test/StdStorage.t.sol | 463 - lib/forge-std/test/StdStyle.t.sol | 110 - lib/forge-std/test/StdToml.t.sol | 49 - lib/forge-std/test/StdUtils.t.sol | 342 - lib/forge-std/test/Vm.t.sol | 15 - .../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 - lib/forge-std/test/fixtures/test.json | 8 - lib/forge-std/test/fixtures/test.toml | 6 - lib/forge-std/test/mocks/MockERC20.t.sol | 441 - lib/forge-std/test/mocks/MockERC721.t.sol | 721 - .../.changeset/chilled-walls-develop.md | 5 - .../.changeset/chilly-humans-warn.md | 5 - .../.changeset/cold-cheetahs-check.md | 5 - .../.changeset/config.json | 12 - .../.changeset/cool-mangos-compare.md | 5 - .../.changeset/curvy-crabs-repeat.md | 5 - .../.changeset/dirty-cobras-smile.md | 5 - .../.changeset/eight-eyes-burn.md | 5 - .../.changeset/eleven-planets-relax.md | 5 - .../.changeset/flat-turtles-repeat.md | 5 - .../.changeset/fluffy-steaks-exist.md | 5 - .../.changeset/forty-dodos-visit.md | 5 - .../.changeset/friendly-nails-push.md | 5 - .../.changeset/gentle-bulldogs-turn.md | 5 - .../.changeset/gorgeous-badgers-vanish.md | 5 - .../.changeset/heavy-baboons-give.md | 5 - .../.changeset/kind-planets-cough.md | 5 - .../.changeset/light-news-listen.md | 5 - .../.changeset/lucky-crews-eat.md | 5 - .../.changeset/nervous-eyes-teach.md | 5 - .../.changeset/nervous-pans-grow.md | 5 - .../.changeset/nice-paws-pull.md | 5 - .../.changeset/odd-files-protect.md | 5 - .../.changeset/odd-lobsters-wash.md | 5 - .../.changeset/poor-chefs-cheat.md | 5 - .../.changeset/shiny-poets-whisper.md | 5 - .../.changeset/silver-swans-promise.md | 5 - .../.changeset/smart-bugs-switch.md | 5 - .../.changeset/spotty-falcons-explain.md | 5 - .../.changeset/spotty-queens-own.md | 5 - .../.changeset/strong-singers-talk.md | 5 - .../.changeset/thick-pumpkins-report.md | 5 - .../.changeset/thin-walls-drop.md | 5 - .../.changeset/twenty-feet-grin.md | 5 - .../.changeset/violet-moons-tell.md | 5 - .../.changeset/warm-sheep-cover.md | 5 - .../.changeset/wise-bobcats-speak.md | 5 - .../.changeset/witty-chicken-smile.md | 5 - .../.changeset/yellow-deers-walk.md | 5 - .../.changeset/yellow-moles-hammer.md | 5 - lib/openzeppelin-contracts/.codecov.yml | 15 - lib/openzeppelin-contracts/.editorconfig | 21 - lib/openzeppelin-contracts/.eslintrc | 20 - lib/openzeppelin-contracts/.githooks/pre-push | 7 - .../.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 | 50 - .../.github/actions/setup/action.yml | 22 - .../.github/actions/storage-layout/action.yml | 56 - .../.github/workflows/actionlint.yml | 18 - .../.github/workflows/changeset.yml | 28 - .../.github/workflows/checks.yml | 132 - .../.github/workflows/docs.yml | 19 - .../.github/workflows/formal-verification.yml | 86 - .../.github/workflows/release-cycle.yml | 212 - .../.github/workflows/upgradeable.yml | 34 - lib/openzeppelin-contracts/.gitignore | 66 - lib/openzeppelin-contracts/.gitmodules | 10 - lib/openzeppelin-contracts/.mocharc.js | 4 - lib/openzeppelin-contracts/.prettierrc | 15 - lib/openzeppelin-contracts/.solcover.js | 13 - lib/openzeppelin-contracts/CHANGELOG.md | 1037 -- lib/openzeppelin-contracts/CODE_OF_CONDUCT.md | 73 - lib/openzeppelin-contracts/CONTRIBUTING.md | 36 - lib/openzeppelin-contracts/FUNDING.json | 7 - lib/openzeppelin-contracts/GUIDELINES.md | 148 - lib/openzeppelin-contracts/LICENSE | 22 - lib/openzeppelin-contracts/README.md | 107 - lib/openzeppelin-contracts/RELEASING.md | 45 - lib/openzeppelin-contracts/SECURITY.md | 43 - lib/openzeppelin-contracts/audits/2017-03.md | 292 - lib/openzeppelin-contracts/audits/2018-10.pdf | Bin 1000527 -> 0 bytes .../audits/2022-10-Checkpoints.pdf | Bin 155606 -> 0 bytes .../audits/2022-10-ERC4626.pdf | Bin 204184 -> 0 bytes .../audits/2023-05-v4.9.pdf | Bin 485395 -> 0 bytes .../audits/2023-10-v5.0.pdf | Bin 910284 -> 0 bytes lib/openzeppelin-contracts/audits/README.md | 17 - lib/openzeppelin-contracts/certora/.gitignore | 1 - lib/openzeppelin-contracts/certora/Makefile | 54 - lib/openzeppelin-contracts/certora/README.md | 60 - .../access_manager_AccessManager.sol.patch | 97 - .../AccessControlDefaultAdminRulesHarness.sol | 46 - .../harnesses/AccessControlHarness.sol | 6 - .../harnesses/AccessManagedHarness.sol | 36 - .../harnesses/AccessManagerHarness.sol | 116 - .../harnesses/DoubleEndedQueueHarness.sol | 58 - .../harnesses/ERC20FlashMintHarness.sol | 36 - .../certora/harnesses/ERC20PermitHarness.sol | 16 - .../certora/harnesses/ERC20WrapperHarness.sol | 34 - .../harnesses/ERC3156FlashBorrowerHarness.sol | 13 - .../certora/harnesses/ERC721Harness.sol | 33 - .../harnesses/ERC721ReceiverHarness.sol | 11 - .../harnesses/EnumerableMapHarness.sol | 55 - .../harnesses/EnumerableSetHarness.sol | 35 - .../harnesses/InitializableHarness.sol | 23 - .../certora/harnesses/NoncesHarness.sol | 14 - .../certora/harnesses/Ownable2StepHarness.sol | 10 - .../certora/harnesses/OwnableHarness.sol | 10 - .../certora/harnesses/PausableHarness.sol | 18 - .../harnesses/TimelockControllerHarness.sol | 13 - .../certora/reports/2021-10.pdf | Bin 92882 -> 0 bytes .../certora/reports/2022-03.pdf | Bin 199401 -> 0 bytes .../certora/reports/2022-05.pdf | Bin 132223 -> 0 bytes lib/openzeppelin-contracts/certora/run.js | 160 - lib/openzeppelin-contracts/certora/specs.json | 110 - .../certora/specs/AccessControl.spec | 119 - .../specs/AccessControlDefaultAdminRules.spec | 464 - .../certora/specs/AccessManaged.spec | 34 - .../certora/specs/AccessManager.spec | 826 - .../certora/specs/DoubleEndedQueue.spec | 300 - .../certora/specs/ERC20.spec | 352 - .../certora/specs/ERC20FlashMint.spec | 55 - .../certora/specs/ERC20Wrapper.spec | 198 - .../certora/specs/ERC721.spec | 679 - .../certora/specs/EnumerableMap.spec | 333 - .../certora/specs/EnumerableSet.spec | 246 - .../certora/specs/Initializable.spec | 165 - .../certora/specs/Nonces.spec | 92 - .../certora/specs/Ownable.spec | 77 - .../certora/specs/Ownable2Step.spec | 108 - .../certora/specs/Pausable.spec | 96 - .../certora/specs/TimelockController.spec | 274 - .../certora/specs/helpers/helpers.spec | 12 - .../certora/specs/methods/IAccessControl.spec | 8 - .../IAccessControlDefaultAdminRules.spec | 36 - .../certora/specs/methods/IAccessManaged.spec | 5 - .../certora/specs/methods/IAccessManager.spec | 33 - .../certora/specs/methods/IERC20.spec | 11 - .../certora/specs/methods/IERC2612.spec | 5 - .../specs/methods/IERC3156FlashBorrower.spec | 3 - .../specs/methods/IERC3156FlashLender.spec | 5 - .../certora/specs/methods/IERC5313.spec | 3 - .../certora/specs/methods/IERC721.spec | 17 - .../specs/methods/IERC721Receiver.spec | 3 - .../certora/specs/methods/IOwnable.spec | 5 - .../certora/specs/methods/IOwnable2Step.spec | 7 - .../contracts/access/AccessControl.sol | 209 - .../contracts/access/IAccessControl.sol | 98 - .../contracts/access/Ownable.sol | 100 - .../contracts/access/Ownable2Step.sol | 65 - .../contracts/access/README.adoc | 45 - .../AccessControlDefaultAdminRules.sol | 396 - .../extensions/AccessControlEnumerable.sol | 82 - .../IAccessControlDefaultAdminRules.sol | 192 - .../extensions/IAccessControlEnumerable.sol | 31 - .../access/manager/AccessManaged.sol | 113 - .../access/manager/AccessManager.sol | 732 - .../access/manager/AuthorityUtils.sol | 32 - .../access/manager/IAccessManaged.sol | 32 - .../access/manager/IAccessManager.sol | 402 - .../contracts/access/manager/IAuthority.sol | 14 - .../contracts/finance/README.adoc | 14 - .../contracts/finance/VestingWallet.sol | 154 - .../contracts/finance/VestingWalletCliff.sol | 51 - .../contracts/governance/Governor.sol | 852 - .../contracts/governance/IGovernor.sol | 438 - .../contracts/governance/README.adoc | 175 - .../governance/TimelockController.sol | 472 - .../extensions/GovernorCountingFractional.sol | 193 - .../extensions/GovernorCountingSimple.sol | 102 - .../extensions/GovernorPreventLateQuorum.sol | 102 - .../extensions/GovernorSettings.sol | 112 - .../governance/extensions/GovernorStorage.sol | 115 - .../extensions/GovernorTimelockAccess.sol | 349 - .../extensions/GovernorTimelockCompound.sol | 167 - .../extensions/GovernorTimelockControl.sol | 170 - .../governance/extensions/GovernorVotes.sol | 64 - .../GovernorVotesQuorumFraction.sol | 110 - .../contracts/governance/utils/IVotes.sol | 59 - .../contracts/governance/utils/Votes.sol | 251 - .../contracts/interfaces/IERC1155.sol | 6 - .../interfaces/IERC1155MetadataURI.sol | 6 - .../contracts/interfaces/IERC1155Receiver.sol | 6 - .../contracts/interfaces/IERC1271.sol | 17 - .../contracts/interfaces/IERC1363.sol | 86 - .../contracts/interfaces/IERC1363Receiver.sol | 32 - .../contracts/interfaces/IERC1363Spender.sol | 26 - .../contracts/interfaces/IERC165.sol | 6 - .../interfaces/IERC1820Implementer.sol | 20 - .../contracts/interfaces/IERC1820Registry.sol | 112 - .../contracts/interfaces/IERC1967.sol | 24 - .../contracts/interfaces/IERC20.sol | 6 - .../contracts/interfaces/IERC20Metadata.sol | 6 - .../contracts/interfaces/IERC2309.sol | 19 - .../contracts/interfaces/IERC2612.sol | 8 - .../contracts/interfaces/IERC2981.sol | 23 - .../contracts/interfaces/IERC3156.sol | 7 - .../interfaces/IERC3156FlashBorrower.sol | 27 - .../interfaces/IERC3156FlashLender.sol | 41 - .../contracts/interfaces/IERC4626.sol | 230 - .../contracts/interfaces/IERC4906.sol | 20 - .../contracts/interfaces/IERC5267.sol | 28 - .../contracts/interfaces/IERC5313.sol | 16 - .../contracts/interfaces/IERC5805.sol | 9 - .../contracts/interfaces/IERC6372.sol | 17 - .../contracts/interfaces/IERC721.sol | 6 - .../interfaces/IERC721Enumerable.sol | 6 - .../contracts/interfaces/IERC721Metadata.sol | 6 - .../contracts/interfaces/IERC721Receiver.sol | 6 - .../contracts/interfaces/IERC777.sol | 200 - .../contracts/interfaces/IERC777Recipient.sol | 35 - .../contracts/interfaces/IERC777Sender.sol | 35 - .../contracts/interfaces/README.adoc | 82 - .../contracts/interfaces/draft-IERC1822.sol | 20 - .../contracts/interfaces/draft-IERC6093.sol | 161 - .../contracts/metatx/ERC2771Context.sol | 86 - .../contracts/metatx/ERC2771Forwarder.sol | 371 - .../contracts/metatx/README.adoc | 17 - .../contracts/mocks/AccessManagedTarget.sol | 34 - .../contracts/mocks/AccessManagerMock.sol | 21 - .../contracts/mocks/ArraysMock.sol | 127 - .../contracts/mocks/AuthorityMock.sol | 69 - .../contracts/mocks/Base64Dirty.sol | 19 - .../contracts/mocks/CallReceiverMock.sol | 73 - .../contracts/mocks/ConstructorMock.sol | 34 - .../contracts/mocks/ContextMock.sol | 35 - .../contracts/mocks/DummyImplementation.sol | 65 - .../contracts/mocks/EIP712Verifier.sol | 16 - .../contracts/mocks/ERC1271WalletMock.sol | 24 - .../ERC165/ERC165InterfacesSupported.sol | 58 - .../mocks/ERC165/ERC165MaliciousData.sol | 12 - .../mocks/ERC165/ERC165MissingData.sol | 7 - .../mocks/ERC165/ERC165NotSupported.sol | 5 - .../mocks/ERC165/ERC165ReturnBomb.sol | 18 - .../contracts/mocks/ERC2771ContextMock.sol | 28 - .../mocks/ERC3156FlashBorrowerMock.sol | 53 - .../contracts/mocks/EtherReceiverMock.sol | 17 - .../contracts/mocks/InitializableMock.sol | 130 - .../mocks/MerkleProofCustomHashMock.sol | 62 - .../contracts/mocks/MerkleTreeMock.sol | 44 - .../contracts/mocks/MulticallHelper.sol | 23 - .../MultipleInheritanceInitializableMocks.sol | 131 - .../contracts/mocks/PausableMock.sol | 31 - .../contracts/mocks/ReentrancyAttack.sol | 12 - .../contracts/mocks/ReentrancyMock.sol | 50 - .../mocks/ReentrancyTransientMock.sol | 50 - .../mocks/RegressionImplementation.sol | 61 - .../SingleInheritanceInitializableMocks.sol | 49 - .../contracts/mocks/Stateless.sol | 41 - .../contracts/mocks/StorageSlotMock.sol | 137 - .../contracts/mocks/TimelockReentrant.sol | 26 - .../contracts/mocks/UpgradeableBeaconMock.sol | 27 - .../contracts/mocks/VotesMock.sol | 42 - .../contracts/mocks/compound/CompTimelock.sol | 174 - .../governance/GovernorFractionalMock.sol | 14 - .../mocks/governance/GovernorMock.sol | 14 - .../GovernorPreventLateQuorumMock.sol | 46 - .../mocks/governance/GovernorStorageMock.sol | 79 - .../governance/GovernorTimelockAccessMock.sol | 70 - .../GovernorTimelockCompoundMock.sol | 69 - .../GovernorTimelockControlMock.sol | 69 - .../mocks/governance/GovernorVoteMock.sol | 20 - .../governance/GovernorWithParamsMock.sol | 51 - .../contracts/mocks/proxy/BadBeacon.sol | 11 - .../mocks/proxy/ClashingImplementation.sol | 19 - .../mocks/proxy/UUPSUpgradeableMock.sol | 35 - .../mocks/token/ERC1155ReceiverMock.sol | 74 - .../mocks/token/ERC1363ForceApproveMock.sol | 14 - .../mocks/token/ERC1363NoReturnMock.sol | 34 - .../mocks/token/ERC1363ReceiverMock.sol | 52 - .../mocks/token/ERC1363ReturnFalseMock.sol | 34 - .../mocks/token/ERC1363SpenderMock.sol | 47 - .../mocks/token/ERC20ApprovalMock.sol | 10 - .../mocks/token/ERC20DecimalsMock.sol | 17 - .../mocks/token/ERC20ExcessDecimalsMock.sol | 9 - .../mocks/token/ERC20FlashMintMock.sol | 26 - .../mocks/token/ERC20ForceApproveMock.sol | 13 - .../contracts/mocks/token/ERC20Mock.sol | 16 - .../mocks/token/ERC20MulticallMock.sol | 8 - .../mocks/token/ERC20NoReturnMock.sol | 28 - .../contracts/mocks/token/ERC20Reentrant.sol | 39 - .../mocks/token/ERC20ReturnFalseMock.sol | 19 - .../mocks/token/ERC20VotesLegacyMock.sol | 253 - .../mocks/token/ERC20VotesTimestampMock.sol | 29 - .../mocks/token/ERC4626LimitsMock.sol | 23 - .../contracts/mocks/token/ERC4626Mock.sol | 17 - .../mocks/token/ERC4626OffsetMock.sol | 17 - .../contracts/mocks/token/ERC4646FeesMock.sol | 40 - .../token/ERC721ConsecutiveEnumerableMock.sol | 42 - .../mocks/token/ERC721ConsecutiveMock.sol | 61 - .../mocks/token/ERC721ReceiverMock.sol | 47 - .../mocks/token/ERC721URIStorageMock.sol | 17 - .../contracts/package.json | 32 - .../contracts/proxy/Clones.sol | 124 - .../contracts/proxy/ERC1967/ERC1967Proxy.sol | 40 - .../contracts/proxy/ERC1967/ERC1967Utils.sol | 177 - .../contracts/proxy/Proxy.sol | 69 - .../contracts/proxy/README.adoc | 87 - .../contracts/proxy/beacon/BeaconProxy.sol | 57 - .../contracts/proxy/beacon/IBeacon.sol | 16 - .../proxy/beacon/UpgradeableBeacon.sol | 70 - .../proxy/transparent/ProxyAdmin.sol | 45 - .../TransparentUpgradeableProxy.sol | 117 - .../contracts/proxy/utils/Initializable.sol | 228 - .../contracts/proxy/utils/UUPSUpgradeable.sol | 147 - .../contracts/token/ERC1155/ERC1155.sol | 402 - .../contracts/token/ERC1155/IERC1155.sol | 123 - .../token/ERC1155/IERC1155Receiver.sol | 59 - .../contracts/token/ERC1155/README.adoc | 41 - .../ERC1155/extensions/ERC1155Burnable.sol | 28 - .../ERC1155/extensions/ERC1155Pausable.sol | 38 - .../ERC1155/extensions/ERC1155Supply.sol | 90 - .../ERC1155/extensions/ERC1155URIStorage.sol | 61 - .../extensions/IERC1155MetadataURI.sol | 20 - .../token/ERC1155/utils/ERC1155Holder.sol | 42 - .../token/ERC1155/utils/ERC1155Utils.sol | 87 - .../contracts/token/ERC20/ERC20.sol | 312 - .../contracts/token/ERC20/IERC20.sol | 79 - .../contracts/token/ERC20/README.adoc | 70 - .../token/ERC20/extensions/ERC1363.sol | 205 - .../token/ERC20/extensions/ERC20Burnable.sol | 39 - .../token/ERC20/extensions/ERC20Capped.sol | 56 - .../token/ERC20/extensions/ERC20FlashMint.sol | 134 - .../token/ERC20/extensions/ERC20Pausable.sol | 33 - .../token/ERC20/extensions/ERC20Permit.sol | 83 - .../token/ERC20/extensions/ERC20Votes.sol | 83 - .../token/ERC20/extensions/ERC20Wrapper.sol | 91 - .../token/ERC20/extensions/ERC4626.sol | 282 - .../token/ERC20/extensions/IERC20Metadata.sol | 26 - .../token/ERC20/extensions/IERC20Permit.sol | 90 - .../contracts/token/ERC20/utils/SafeERC20.sol | 185 - .../contracts/token/ERC721/ERC721.sol | 456 - .../contracts/token/ERC721/IERC721.sol | 135 - .../token/ERC721/IERC721Receiver.sol | 28 - .../contracts/token/ERC721/README.adoc | 67 - .../ERC721/extensions/ERC721Burnable.sol | 26 - .../ERC721/extensions/ERC721Consecutive.sol | 176 - .../ERC721/extensions/ERC721Enumerable.sol | 174 - .../ERC721/extensions/ERC721Pausable.sol | 37 - .../token/ERC721/extensions/ERC721Royalty.sol | 27 - .../ERC721/extensions/ERC721URIStorage.sol | 61 - .../token/ERC721/extensions/ERC721Votes.sol | 47 - .../token/ERC721/extensions/ERC721Wrapper.sol | 102 - .../ERC721/extensions/IERC721Enumerable.sol | 29 - .../ERC721/extensions/IERC721Metadata.sol | 27 - .../token/ERC721/utils/ERC721Holder.sol | 24 - .../token/ERC721/utils/ERC721Utils.sol | 48 - .../contracts/token/common/ERC2981.sol | 140 - .../contracts/token/common/README.adoc | 10 - .../contracts/utils/Address.sol | 151 - .../contracts/utils/Arrays.sol | 487 - .../contracts/utils/Base64.sol | 120 - .../contracts/utils/Context.sol | 28 - .../contracts/utils/Create2.sol | 94 - .../contracts/utils/Errors.sol | 31 - .../contracts/utils/Multicall.sol | 37 - .../contracts/utils/Nonces.sol | 46 - .../contracts/utils/Packing.sol | 1015 -- .../contracts/utils/Panic.sol | 55 - .../contracts/utils/Pausable.sol | 119 - .../contracts/utils/README.adoc | 131 - .../contracts/utils/ReentrancyGuard.sol | 87 - .../utils/ReentrancyGuardTransient.sol | 58 - .../contracts/utils/ShortStrings.sol | 123 - .../contracts/utils/SlotDerivation.sol | 161 - .../contracts/utils/StorageSlot.sol | 330 - .../contracts/utils/Strings.sol | 118 - .../contracts/utils/cryptography/ECDSA.sol | 174 - .../contracts/utils/cryptography/EIP712.sol | 160 - .../contracts/utils/cryptography/Hashes.sol | 29 - .../utils/cryptography/MerkleProof.sol | 479 - .../utils/cryptography/MessageHashUtils.sol | 86 - .../contracts/utils/cryptography/P256.sol | 316 - .../contracts/utils/cryptography/RSA.sol | 145 - .../utils/cryptography/SignatureChecker.sol | 50 - .../contracts/utils/introspection/ERC165.sol | 27 - .../utils/introspection/ERC165Checker.sol | 124 - .../contracts/utils/introspection/IERC165.sol | 25 - .../contracts/utils/math/Math.sol | 687 - .../contracts/utils/math/SafeCast.sol | 1163 -- .../contracts/utils/math/SignedMath.sol | 68 - .../contracts/utils/structs/BitMaps.sol | 60 - .../contracts/utils/structs/Checkpoints.sol | 606 - .../utils/structs/CircularBuffer.sol | 130 - .../utils/structs/DoubleEndedQueue.sol | 156 - .../contracts/utils/structs/EnumerableMap.sol | 913 -- .../contracts/utils/structs/EnumerableSet.sol | 378 - .../contracts/utils/structs/MerkleTree.sol | 171 - .../contracts/utils/types/Time.sol | 130 - .../vendor/compound/ICompoundTimelock.sol | 86 - .../contracts/vendor/compound/LICENSE | 11 - lib/openzeppelin-contracts/foundry.toml | 14 - .../fv-requirements.txt | 4 - lib/openzeppelin-contracts/hardhat.config.js | 124 - .../hardhat/async-test-sanity.js | 3 - .../hardhat/env-artifacts.js | 29 - .../hardhat/ignore-unreachable-warnings.js | 45 - .../hardhat/remappings.js | 18 - .../hardhat/skip-foundry-tests.js | 6 - .../hardhat/task-test-get-files.js | 25 - .../lib/erc4626-tests/ERC4626.prop.sol | 404 - .../lib/erc4626-tests/ERC4626.test.sol | 349 - .../lib/erc4626-tests/LICENSE | 661 - .../lib/erc4626-tests/README.md | 116 - .../lib/forge-std/.gitattributes | 1 - .../lib/forge-std/.github/workflows/ci.yml | 134 - .../lib/forge-std/.github/workflows/sync.yml | 29 - .../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 | 592 - .../lib/forge-std/lib/ds-test/src/test.t.sol | 417 - .../lib/forge-std/package.json | 16 - .../lib/forge-std/scripts/vm.py | 635 - .../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 | 248 - .../lib/forge-std/src/StdCheats.sol | 817 - .../lib/forge-std/src/StdError.sol | 15 - .../lib/forge-std/src/StdInvariant.sol | 107 - .../lib/forge-std/src/StdJson.sol | 183 - .../lib/forge-std/src/StdMath.sol | 43 - .../lib/forge-std/src/StdStorage.sol | 378 - .../lib/forge-std/src/StdStyle.sol | 333 - .../lib/forge-std/src/StdUtils.sol | 226 - .../lib/forge-std/src/Test.sol | 33 - .../lib/forge-std/src/Vm.sol | 1114 -- .../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/mocks/MockERC20.sol | 216 - .../lib/forge-std/src/mocks/MockERC721.sol | 221 - .../lib/forge-std/src/safeconsole.sol | 13248 ---------------- .../lib/forge-std/test/StdAssertions.t.sol | 1015 -- .../lib/forge-std/test/StdChains.t.sol | 216 - .../lib/forge-std/test/StdCheats.t.sol | 610 - .../lib/forge-std/test/StdError.t.sol | 120 - .../lib/forge-std/test/StdMath.t.sol | 212 - .../lib/forge-std/test/StdStorage.t.sol | 315 - .../lib/forge-std/test/StdStyle.t.sol | 110 - .../lib/forge-std/test/StdUtils.t.sol | 342 - .../lib/forge-std/test/Vm.t.sol | 15 - .../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 - .../lib/forge-std/test/mocks/MockERC20.t.sol | 441 - .../lib/forge-std/test/mocks/MockERC721.t.sol | 721 - .../lib/halmos-cheatcodes/LICENSE | 661 - .../lib/halmos-cheatcodes/README.md | 97 - .../lib/halmos-cheatcodes/src/SVM.sol | 35 - .../lib/halmos-cheatcodes/src/SymTest.sol | 11 - lib/openzeppelin-contracts/logo.svg | 15 - lib/openzeppelin-contracts/netlify.toml | 3 - lib/openzeppelin-contracts/package-lock.json | 11328 ------------- lib/openzeppelin-contracts/package.json | 89 - lib/openzeppelin-contracts/remappings.txt | 1 - lib/openzeppelin-contracts/renovate.json | 4 - .../scripts/checks/compare-layout.js | 20 - .../scripts/checks/compareGasReports.js | 247 - .../scripts/checks/coverage.sh | 18 - .../scripts/checks/extract-layout.js | 38 - .../scripts/checks/generation.sh | 6 - .../scripts/checks/inheritance-ordering.js | 54 - lib/openzeppelin-contracts/scripts/gen-nav.js | 41 - .../scripts/generate/format-lines.js | 16 - .../scripts/generate/run.js | 56 - .../scripts/generate/templates/Arrays.js | 392 - .../scripts/generate/templates/Arrays.opts.js | 3 - .../scripts/generate/templates/Checkpoints.js | 235 - .../generate/templates/Checkpoints.opts.js | 17 - .../generate/templates/Checkpoints.t.js | 138 - .../generate/templates/EnumerableMap.js | 275 - .../generate/templates/EnumerableMap.opts.js | 19 - .../generate/templates/EnumerableSet.js | 250 - .../generate/templates/EnumerableSet.opts.js | 12 - .../scripts/generate/templates/MerkleProof.js | 178 - .../generate/templates/MerkleProof.opts.js | 11 - .../scripts/generate/templates/Packing.js | 86 - .../generate/templates/Packing.opts.js | 3 - .../scripts/generate/templates/Packing.t.js | 48 - .../scripts/generate/templates/SafeCast.js | 139 - .../scripts/generate/templates/Slot.opts.js | 13 - .../generate/templates/SlotDerivation.js | 120 - .../generate/templates/SlotDerivation.t.js | 113 - .../scripts/generate/templates/StorageSlot.js | 133 - .../generate/templates/StorageSlotMock.js | 70 - .../scripts/generate/templates/conversion.js | 30 - .../scripts/git-user-config.sh | 6 - lib/openzeppelin-contracts/scripts/helpers.js | 7 - lib/openzeppelin-contracts/scripts/prepack.sh | 23 - .../scripts/prepare-docs.sh | 26 - .../scripts/release/format-changelog.js | 33 - .../scripts/release/synchronize-versions.js | 15 - .../scripts/release/update-comment.js | 34 - .../scripts/release/version.sh | 11 - .../release/workflow/exit-prerelease.sh | 8 - .../release/workflow/github-release.js | 48 - .../release/workflow/integrity-check.sh | 20 - .../scripts/release/workflow/pack.sh | 26 - .../scripts/release/workflow/publish.sh | 26 - .../scripts/release/workflow/rerun.js | 7 - .../workflow/set-changesets-pr-title.js | 17 - .../scripts/release/workflow/start.sh | 35 - .../scripts/release/workflow/state.js | 112 - .../scripts/remove-ignored-artifacts.js | 45 - .../scripts/solhint-custom/index.js | 84 - .../scripts/solhint-custom/package.json | 5 - .../scripts/update-docs-branch.js | 65 - .../scripts/upgradeable/README.md | 21 - .../scripts/upgradeable/patch-apply.sh | 19 - .../scripts/upgradeable/patch-save.sh | 18 - .../scripts/upgradeable/transpile-onto.sh | 54 - .../scripts/upgradeable/transpile.sh | 50 - .../scripts/upgradeable/upgradeable.patch | 361 - .../slither.config.json | 5 - lib/openzeppelin-contracts/solhint.config.js | 26 - lib/openzeppelin-contracts/test/TESTING.md | 3 - .../test/access/AccessControl.behavior.js | 874 - .../test/access/AccessControl.test.js | 19 - .../test/access/Ownable.test.js | 79 - .../test/access/Ownable2Step.test.js | 85 - .../AccessControlDefaultAdminRules.test.js | 32 - .../AccessControlEnumerable.test.js | 24 - .../test/access/manager/AccessManaged.test.js | 146 - .../access/manager/AccessManager.behavior.js | 257 - .../access/manager/AccessManager.predicate.js | 456 - .../test/access/manager/AccessManager.test.js | 2489 --- .../access/manager/AuthorityUtils.test.js | 102 - .../test/finance/VestingWallet.behavior.js | 87 - .../test/finance/VestingWallet.test.js | 65 - .../test/finance/VestingWalletCliff.test.js | 70 - .../test/governance/Governor.t.sol | 55 - .../test/governance/Governor.test.js | 992 -- .../governance/TimelockController.test.js | 1279 -- .../GovernorCountingFractional.test.js | 248 - .../extensions/GovernorERC721.test.js | 131 - .../GovernorPreventLateQuorum.test.js | 185 - .../extensions/GovernorStorage.test.js | 155 - .../extensions/GovernorTimelockAccess.test.js | 864 - .../GovernorTimelockCompound.test.js | 448 - .../GovernorTimelockControl.test.js | 504 - .../GovernorVotesQuorumFraction.test.js | 165 - .../extensions/GovernorWithParams.test.js | 245 - .../test/governance/utils/ERC6372.behavior.js | 25 - .../test/governance/utils/Votes.behavior.js | 325 - .../test/governance/utils/Votes.test.js | 102 - .../test/helpers/access-manager.js | 85 - .../test/helpers/account.js | 14 - .../test/helpers/constants.js | 4 - .../test/helpers/deploy.js | 14 - .../test/helpers/eip712-types.js | 52 - .../test/helpers/eip712.js | 45 - .../test/helpers/enums.js | 12 - .../test/helpers/governance.js | 198 - .../test/helpers/iterate.js | 36 - .../test/helpers/math.js | 33 - .../test/helpers/methods.js | 14 - .../test/helpers/random.js | 19 - .../test/helpers/storage.js | 48 - .../test/helpers/strings.js | 5 - .../test/helpers/time.js | 30 - .../test/helpers/txpool.js | 29 - .../test/metatx/ERC2771Context.test.js | 133 - .../test/metatx/ERC2771Forwarder.t.sol | 165 - .../test/metatx/ERC2771Forwarder.test.js | 461 - .../test/proxy/Clones.behaviour.js | 160 - .../test/proxy/Clones.t.sol | 60 - .../test/proxy/Clones.test.js | 95 - .../test/proxy/ERC1967/ERC1967Proxy.test.js | 23 - .../test/proxy/ERC1967/ERC1967Utils.test.js | 162 - .../test/proxy/Proxy.behaviour.js | 185 - .../test/proxy/beacon/BeaconProxy.test.js | 141 - .../proxy/beacon/UpgradeableBeacon.test.js | 55 - .../test/proxy/transparent/ProxyAdmin.test.js | 82 - .../TransparentUpgradeableProxy.behaviour.js | 357 - .../TransparentUpgradeableProxy.test.js | 28 - .../test/proxy/utils/Initializable.test.js | 216 - .../test/proxy/utils/UUPSUpgradeable.test.js | 120 - .../test/sanity.test.js | 27 - .../test/token/ERC1155/ERC1155.behavior.js | 763 - .../test/token/ERC1155/ERC1155.test.js | 213 - .../extensions/ERC1155Burnable.test.js | 66 - .../extensions/ERC1155Pausable.test.js | 105 - .../ERC1155/extensions/ERC1155Supply.test.js | 119 - .../extensions/ERC1155URIStorage.test.js | 70 - .../token/ERC1155/utils/ERC1155Holder.test.js | 56 - .../token/ERC1155/utils/ERC1155Utils.test.js | 299 - .../test/token/ERC20/ERC20.behavior.js | 260 - .../test/token/ERC20/ERC20.test.js | 199 - .../token/ERC20/extensions/ERC1363.test.js | 370 - .../ERC20/extensions/ERC20Burnable.test.js | 105 - .../ERC20/extensions/ERC20Capped.test.js | 55 - .../ERC20/extensions/ERC20FlashMint.test.js | 164 - .../ERC20/extensions/ERC20Pausable.test.js | 129 - .../ERC20/extensions/ERC20Permit.test.js | 109 - .../token/ERC20/extensions/ERC20Votes.test.js | 546 - .../ERC20/extensions/ERC20Wrapper.test.js | 203 - .../test/token/ERC20/extensions/ERC4626.t.sol | 41 - .../token/ERC20/extensions/ERC4626.test.js | 888 -- .../test/token/ERC20/utils/SafeERC20.test.js | 427 - .../test/token/ERC721/ERC721.behavior.js | 972 -- .../test/token/ERC721/ERC721.test.js | 23 - .../token/ERC721/ERC721Enumerable.test.js | 28 - .../ERC721/extensions/ERC721Burnable.test.js | 77 - .../ERC721/extensions/ERC721Consecutive.t.sol | 181 - .../extensions/ERC721Consecutive.test.js | 236 - .../ERC721/extensions/ERC721Pausable.test.js | 81 - .../ERC721/extensions/ERC721Royalty.test.js | 57 - .../extensions/ERC721URIStorage.test.js | 121 - .../ERC721/extensions/ERC721Votes.test.js | 194 - .../ERC721/extensions/ERC721Wrapper.test.js | 201 - .../token/ERC721/utils/ERC721Holder.test.js | 20 - .../token/ERC721/utils/ERC721Utils.test.js | 94 - .../test/token/common/ERC2981.behavior.js | 152 - .../test/utils/Address.test.js | 280 - .../test/utils/Arrays.t.sol | 31 - .../test/utils/Arrays.test.js | 223 - .../test/utils/Base64.t.sol | 34 - .../test/utils/Base64.test.js | 59 - .../test/utils/Context.behavior.js | 48 - .../test/utils/Context.test.js | 18 - .../test/utils/Create2.t.sol | 18 - .../test/utils/Create2.test.js | 190 - .../test/utils/Multicall.test.js | 72 - .../test/utils/Nonces.test.js | 75 - .../test/utils/Packing.t.sol | 681 - .../test/utils/Packing.test.js | 70 - .../test/utils/Panic.test.js | 37 - .../test/utils/Pausable.test.js | 90 - .../test/utils/ReentrancyGuard.test.js | 50 - .../test/utils/ShortStrings.t.sol | 109 - .../test/utils/ShortStrings.test.js | 64 - .../test/utils/SlotDerivation.t.sol | 228 - .../test/utils/SlotDerivation.test.js | 58 - .../test/utils/StorageSlot.test.js | 106 - .../test/utils/Strings.test.js | 180 - .../test/utils/cryptography/ECDSA.test.js | 213 - .../test/utils/cryptography/EIP712.test.js | 105 - .../utils/cryptography/MerkleProof.test.js | 213 - .../cryptography/MessageHashUtils.test.js | 68 - .../test/utils/cryptography/P256.t.sol | 135 - .../test/utils/cryptography/P256.test.js | 156 - .../test/utils/cryptography/RSA.helper.js | 17 - .../test/utils/cryptography/RSA.test.js | 97 - .../utils/cryptography/SigVer15_186-3.rsp | 3850 ----- .../cryptography/SignatureChecker.test.js | 61 - .../ecdsa_secp256r1_sha256_p1363_test.json | 3719 ----- .../test/utils/introspection/ERC165.test.js | 18 - .../utils/introspection/ERC165Checker.test.js | 245 - .../SupportsInterface.behavior.js | 145 - .../test/utils/math/Math.t.sol | 311 - .../test/utils/math/Math.test.js | 562 - .../test/utils/math/SafeCast.test.js | 159 - .../test/utils/math/SignedMath.t.sol | 80 - .../test/utils/math/SignedMath.test.js | 53 - .../test/utils/structs/BitMap.test.js | 149 - .../test/utils/structs/Checkpoints.t.sol | 332 - .../test/utils/structs/Checkpoints.test.js | 146 - .../test/utils/structs/CircularBuffer.test.js | 79 - .../utils/structs/DoubleEndedQueue.test.js | 102 - .../utils/structs/EnumerableMap.behavior.js | 151 - .../test/utils/structs/EnumerableMap.test.js | 65 - .../utils/structs/EnumerableSet.behavior.js | 116 - .../test/utils/structs/EnumerableSet.test.js | 61 - .../test/utils/structs/MerkleTree.test.js | 100 - .../test/utils/types/Time.test.js | 135 - lib/v2-core/.gitattributes | 1 - lib/v2-core/.github/stale.yml | 25 - lib/v2-core/.github/workflows/CI.yml | 37 - lib/v2-core/.gitignore | 2 - lib/v2-core/.mocharc.json | 6 - lib/v2-core/.prettierrc | 5 - lib/v2-core/.waffle.json | 24 - lib/v2-core/CITATION.cff | 15 - lib/v2-core/LICENSE | 674 - lib/v2-core/README.md | 24 - lib/v2-core/contracts/UniswapV2ERC20.sol | 94 - lib/v2-core/contracts/UniswapV2Factory.sol | 49 - lib/v2-core/contracts/UniswapV2Pair.sol | 201 - lib/v2-core/contracts/interfaces/IERC20.sol | 17 - .../contracts/interfaces/IUniswapV2Callee.sol | 5 - .../contracts/interfaces/IUniswapV2ERC20.sol | 23 - .../interfaces/IUniswapV2Factory.sol | 17 - .../contracts/interfaces/IUniswapV2Pair.sol | 52 - lib/v2-core/contracts/libraries/Math.sol | 23 - lib/v2-core/contracts/libraries/SafeMath.sol | 17 - lib/v2-core/contracts/libraries/UQ112x112.sol | 20 - lib/v2-core/contracts/test/ERC20.sol | 9 - lib/v2-core/package.json | 48 - lib/v2-core/test/UniswapV2ERC20.spec.ts | 116 - lib/v2-core/test/UniswapV2Factory.spec.ts | 86 - lib/v2-core/test/UniswapV2Pair.spec.ts | 284 - lib/v2-core/test/shared/fixtures.ts | 45 - lib/v2-core/test/shared/utilities.ts | 99 - lib/v2-core/tsconfig.json | 9 - lib/v2-core/yarn.lock | 7195 --------- lib/v3-core/.gitattributes | 1 - lib/v3-core/.github/stale.yml | 25 - .../.github/workflows/fuzz-testing.yml | 60 - lib/v3-core/.github/workflows/lint.yml | 32 - lib/v3-core/.github/workflows/mythx.yml | 65 - lib/v3-core/.github/workflows/tests.yml | 38 - lib/v3-core/.gitignore | 5 - lib/v3-core/.prettierrc | 5 - lib/v3-core/.solhint.json | 6 - lib/v3-core/.yarnrc | 1 - lib/v3-core/LICENSE | 100 - lib/v3-core/README.md | 66 - lib/v3-core/audits/abdk/audit.pdf | Bin 1149996 -> 0 bytes lib/v3-core/audits/tob/README.md | 166 - lib/v3-core/audits/tob/audit.pdf | Bin 573061 -> 0 bytes .../crytic/echidna/E2E_mint_burn.config.yaml | 16 - .../crytic/echidna/E2E_mint_burn.sol | 503 - .../crytic/echidna/E2E_swap.config.yaml | 10 - .../tob/contracts/crytic/echidna/E2E_swap.sol | 487 - .../crytic/echidna/Other.config.yaml | 7 - .../tob/contracts/crytic/echidna/Other.sol | 21 - .../tob/contracts/crytic/echidna/Setup.sol | 205 - .../tob/contracts/crytic/manticore/001.sol | 11 - .../tob/contracts/crytic/manticore/002.sol | 12 - .../tob/contracts/crytic/manticore/003.sol | 9 - lib/v3-core/bug-bounty.md | 76 - lib/v3-core/contracts/NoDelegateCall.sol | 27 - lib/v3-core/contracts/UniswapV3Factory.sol | 73 - lib/v3-core/contracts/UniswapV3Pool.sol | 869 - .../contracts/UniswapV3PoolDeployer.sol | 38 - .../contracts/interfaces/IERC20Minimal.sol | 52 - .../interfaces/IUniswapV3Factory.sol | 78 - .../contracts/interfaces/IUniswapV3Pool.sol | 24 - .../interfaces/IUniswapV3PoolDeployer.sol | 26 - lib/v3-core/contracts/interfaces/LICENSE | 445 - .../callback/IUniswapV3FlashCallback.sol | 18 - .../callback/IUniswapV3MintCallback.sol | 18 - .../callback/IUniswapV3SwapCallback.sol | 21 - .../interfaces/pool/IUniswapV3PoolActions.sol | 103 - .../pool/IUniswapV3PoolDerivedState.sol | 40 - .../interfaces/pool/IUniswapV3PoolEvents.sol | 121 - .../pool/IUniswapV3PoolImmutables.sol | 35 - .../pool/IUniswapV3PoolOwnerActions.sol | 23 - .../interfaces/pool/IUniswapV3PoolState.sol | 116 - lib/v3-core/contracts/libraries/BitMath.sol | 94 - .../contracts/libraries/FixedPoint128.sol | 8 - .../contracts/libraries/FixedPoint96.sol | 10 - lib/v3-core/contracts/libraries/FullMath.sol | 124 - lib/v3-core/contracts/libraries/LICENSE | 445 - lib/v3-core/contracts/libraries/LICENSE_MIT | 20 - .../contracts/libraries/LiquidityMath.sol | 17 - .../contracts/libraries/LowGasSafeMath.sol | 46 - lib/v3-core/contracts/libraries/Oracle.sol | 325 - lib/v3-core/contracts/libraries/Position.sol | 88 - lib/v3-core/contracts/libraries/SafeCast.sol | 28 - .../contracts/libraries/SqrtPriceMath.sol | 227 - lib/v3-core/contracts/libraries/SwapMath.sol | 98 - lib/v3-core/contracts/libraries/Tick.sol | 185 - .../contracts/libraries/TickBitmap.sol | 78 - lib/v3-core/contracts/libraries/TickMath.sol | 205 - .../contracts/libraries/TransferHelper.sol | 23 - .../contracts/libraries/UnsafeMath.sol | 17 - .../contracts/test/BitMathEchidnaTest.sol | 18 - lib/v3-core/contracts/test/BitMathTest.sol | 26 - .../contracts/test/FullMathEchidnaTest.sol | 67 - lib/v3-core/contracts/test/FullMathTest.sol | 22 - .../contracts/test/LiquidityMathTest.sol | 16 - .../test/LowGasSafeMathEchidnaTest.sol | 36 - .../contracts/test/MockTimeUniswapV3Pool.sol | 26 - .../test/MockTimeUniswapV3PoolDeployer.sol | 35 - .../contracts/test/NoDelegateCallTest.sol | 32 - .../contracts/test/OracleEchidnaTest.sol | 137 - lib/v3-core/contracts/test/OracleTest.sol | 100 - .../test/SqrtPriceMathEchidnaTest.sol | 232 - .../contracts/test/SqrtPriceMathTest.sol | 86 - .../contracts/test/SwapMathEchidnaTest.sol | 52 - lib/v3-core/contracts/test/SwapMathTest.sol | 37 - lib/v3-core/contracts/test/TestERC20.sol | 59 - .../contracts/test/TestUniswapV3Callee.sol | 142 - .../test/TestUniswapV3ReentrantCallee.sol | 56 - .../contracts/test/TestUniswapV3Router.sol | 91 - .../contracts/test/TestUniswapV3SwapPay.sol | 41 - .../contracts/test/TickBitmapEchidnaTest.sol | 47 - lib/v3-core/contracts/test/TickBitmapTest.sol | 40 - .../contracts/test/TickEchidnaTest.sol | 27 - .../contracts/test/TickMathEchidnaTest.sol | 22 - lib/v3-core/contracts/test/TickMathTest.sol | 34 - .../test/TickOverflowSafetyEchidnaTest.sol | 111 - lib/v3-core/contracts/test/TickTest.sol | 79 - .../contracts/test/UniswapV3PoolSwapTest.sol | 50 - .../contracts/test/UnsafeMathEchidnaTest.sol | 17 - lib/v3-core/echidna.config.yml | 74 - lib/v3-core/hardhat.config.ts | 68 - lib/v3-core/package.json | 59 - lib/v3-core/test/BitMath.spec.ts | 79 - lib/v3-core/test/FullMath.spec.ts | 182 - lib/v3-core/test/LiquidityMath.spec.ts | 44 - lib/v3-core/test/NoDelegateCall.spec.ts | 54 - lib/v3-core/test/Oracle.spec.ts | 798 - lib/v3-core/test/SqrtPriceMath.spec.ts | 379 - lib/v3-core/test/SwapMath.spec.ts | 324 - lib/v3-core/test/Tick.spec.ts | 329 - lib/v3-core/test/TickBitmap.spec.ts | 227 - lib/v3-core/test/TickMath.spec.ts | 166 - lib/v3-core/test/UniswapV3Factory.spec.ts | 177 - .../test/UniswapV3Pool.arbitrage.spec.ts | 373 - lib/v3-core/test/UniswapV3Pool.gas.spec.ts | 315 - lib/v3-core/test/UniswapV3Pool.spec.ts | 2043 --- lib/v3-core/test/UniswapV3Pool.swaps.spec.ts | 588 - lib/v3-core/test/UniswapV3Router.spec.ts | 133 - .../test/__snapshots__/BitMath.spec.ts.snap | 13 - .../__snapshots__/LiquidityMath.spec.ts.snap | 5 - .../__snapshots__/NoDelegateCall.spec.ts.snap | 3 - .../test/__snapshots__/Oracle.spec.ts.snap | 87 - .../__snapshots__/SqrtPriceMath.spec.ts.snap | 17 - .../test/__snapshots__/SwapMath.spec.ts.snap | 17 - .../__snapshots__/TickBitmap.spec.ts.snap | 19 - .../test/__snapshots__/TickMath.spec.ts.snap | 165 - .../UniswapV3Factory.spec.ts.snap | 7 - .../UniswapV3Pool.arbitrage.spec.ts.snap | 977 -- .../UniswapV3Pool.gas.spec.ts.snap | 169 - .../UniswapV3Pool.swaps.spec.ts.snap | 3541 ----- .../test/shared/checkObservationEquals.ts | 38 - lib/v3-core/test/shared/expect.ts | 8 - lib/v3-core/test/shared/fixtures.ts | 92 - lib/v3-core/test/shared/format.ts | 10 - lib/v3-core/test/shared/snapshotGasCost.ts | 27 - lib/v3-core/test/shared/utilities.ts | 258 - lib/v3-core/tsconfig.json | 13 - lib/v3-core/yarn.lock | 9271 ----------- lib/v3-periphery/.gitattributes | 1 - lib/v3-periphery/.github/stale.yml | 25 - lib/v3-periphery/.github/workflows/lint.yml | 33 - lib/v3-periphery/.github/workflows/tests.yml | 39 - lib/v3-periphery/.gitignore | 5 - lib/v3-periphery/.prettierignore | 1 - lib/v3-periphery/.prettierrc | 5 - lib/v3-periphery/.solhint.json | 6 - lib/v3-periphery/.yarnrc | 1 - lib/v3-periphery/LICENSE | 339 - lib/v3-periphery/README.md | 52 - lib/v3-periphery/audits/abdk/audit.pdf | Bin 990570 -> 0 bytes lib/v3-periphery/bug-bounty.md | 80 - .../contracts/NonfungiblePositionManager.sol | 400 - .../NonfungibleTokenPositionDescriptor.sol | 124 - lib/v3-periphery/contracts/SwapRouter.sol | 244 - lib/v3-periphery/contracts/V3Migrator.sol | 99 - .../contracts/base/BlockTimestamp.sol | 12 - .../contracts/base/ERC721Permit.sol | 86 - .../contracts/base/LiquidityManagement.sol | 90 - lib/v3-periphery/contracts/base/Multicall.sol | 28 - .../base/PeripheryImmutableState.sol | 18 - .../contracts/base/PeripheryPayments.sol | 70 - .../base/PeripheryPaymentsWithFee.sol | 55 - .../contracts/base/PeripheryValidation.sol | 11 - .../contracts/base/PoolInitializer.sol | 32 - .../contracts/base/SelfPermit.sol | 63 - .../contracts/examples/PairFlash.sol | 149 - .../contracts/interfaces/IERC20Metadata.sol | 18 - .../contracts/interfaces/IERC721Permit.sol | 32 - .../contracts/interfaces/IMulticall.sol | 13 - .../INonfungiblePositionManager.sol | 180 - .../INonfungibleTokenPositionDescriptor.sol | 17 - .../interfaces/IPeripheryImmutableState.sol | 12 - .../interfaces/IPeripheryPayments.sol | 28 - .../interfaces/IPeripheryPaymentsWithFee.sol | 29 - .../contracts/interfaces/IPoolInitializer.sol | 22 - .../contracts/interfaces/IQuoter.sol | 51 - .../contracts/interfaces/IQuoterV2.sol | 98 - .../contracts/interfaces/ISelfPermit.sol | 76 - .../contracts/interfaces/ISwapRouter.sol | 67 - .../contracts/interfaces/ITickLens.sol | 25 - .../contracts/interfaces/IV3Migrator.sol | 34 - .../interfaces/external/IERC1271.sol | 16 - .../external/IERC20PermitAllowed.sol | 27 - .../contracts/interfaces/external/IWETH9.sol | 13 - lib/v3-periphery/contracts/lens/Quoter.sol | 170 - lib/v3-periphery/contracts/lens/QuoterV2.sol | 273 - lib/v3-periphery/contracts/lens/README.md | 4 - lib/v3-periphery/contracts/lens/TickLens.sol | 42 - .../lens/UniswapInterfaceMulticall.sol | 39 - .../contracts/libraries/BytesLib.sol | 101 - .../libraries/CallbackValidation.sol | 36 - .../contracts/libraries/ChainId.sol | 13 - .../contracts/libraries/HexStrings.sol | 29 - .../contracts/libraries/LiquidityAmounts.sol | 137 - .../contracts/libraries/NFTDescriptor.sol | 477 - .../contracts/libraries/NFTSVG.sol | 406 - .../contracts/libraries/OracleLibrary.sol | 180 - lib/v3-periphery/contracts/libraries/Path.sol | 69 - .../contracts/libraries/PoolAddress.sol | 48 - .../contracts/libraries/PoolTicksCounter.sol | 96 - .../contracts/libraries/PositionKey.sol | 13 - .../contracts/libraries/PositionValue.sol | 167 - .../libraries/SqrtPriceMathPartial.sol | 62 - .../libraries/TokenRatioSortOrder.sol | 12 - .../contracts/libraries/TransferHelper.sol | 60 - .../contracts/test/Base64Test.sol | 16 - .../contracts/test/LiquidityAmountsTest.sol | 120 - .../contracts/test/MockObservable.sol | 48 - .../contracts/test/MockObservations.sol | 82 - .../MockTimeNonfungiblePositionManager.sol | 23 - .../contracts/test/MockTimeSwapRouter.sol | 19 - .../contracts/test/NFTDescriptorTest.sol | 75 - ...ungiblePositionManagerPositionsGasTest.sol | 18 - .../contracts/test/OracleTest.sol | 67 - lib/v3-periphery/contracts/test/PathTest.sol | 37 - .../test/PeripheryImmutableStateTest.sol | 8 - .../contracts/test/PoolAddressTest.sol | 30 - .../contracts/test/PoolTicksCounterTest.sol | 18 - .../contracts/test/PositionValueTest.sol | 57 - .../contracts/test/SelfPermitTest.sol | 9 - .../contracts/test/TestCallbackValidation.sol | 15 - lib/v3-periphery/contracts/test/TestERC20.sol | 10 - .../contracts/test/TestERC20Metadata.sol | 14 - .../contracts/test/TestERC20PermitAllowed.sol | 24 - .../contracts/test/TestMulticall.sol | 30 - .../contracts/test/TestPositionNFTOwner.sol | 28 - .../contracts/test/TestUniswapV3Callee.sol | 62 - .../contracts/test/TickLensTest.sol | 15 - lib/v3-periphery/deploys.md | 25 - lib/v3-periphery/hardhat.config.ts | 104 - lib/v3-periphery/package.json | 68 - lib/v3-periphery/test/Base64.spec.ts | 81 - .../test/CallbackValidation.spec.ts | 56 - .../test/LiquidityAmounts.spec.ts | 241 - lib/v3-periphery/test/Multicall.spec.ts | 65 - lib/v3-periphery/test/NFTDescriptor.spec.ts | 907 -- .../test/NonfungiblePositionManager.spec.ts | 1304 -- ...NonfungibleTokenPositionDescriptor.spec.ts | 217 - lib/v3-periphery/test/OracleLibrary.spec.ts | 675 - lib/v3-periphery/test/PairFlash.spec.ts | 168 - lib/v3-periphery/test/Path.spec.ts | 90 - .../test/PeripheryImmutableState.spec.ts | 56 - lib/v3-periphery/test/PoolAddress.spec.ts | 72 - .../test/PoolTicksCounter.spec.ts | 280 - lib/v3-periphery/test/PositionValue.spec.ts | 490 - lib/v3-periphery/test/Quoter.spec.ts | 201 - lib/v3-periphery/test/QuoterV2.spec.ts | 578 - lib/v3-periphery/test/SelfPermit.spec.ts | 198 - lib/v3-periphery/test/SwapRouter.gas.spec.ts | 453 - lib/v3-periphery/test/SwapRouter.spec.ts | 916 -- lib/v3-periphery/test/TickLens.spec.ts | 223 - lib/v3-periphery/test/V3Migrator.spec.ts | 446 - .../test/__snapshots__/Base64.spec.ts.snap | 32 - .../LiquidityAmounts.spec.ts.snap | 21 - .../test/__snapshots__/Multicall.spec.ts.snap | 5 - .../__snapshots__/NFTDescriptor.spec.ts.snap | 7 - .../test/__snapshots__/NFTDescriptor.svg | 1 - .../NonfungiblePositionManager.spec.ts.snap | 41 - .../__snapshots__/OracleLibrary.spec.ts.snap | 3 - .../test/__snapshots__/PairFlash.spec.ts.snap | 3 - .../test/__snapshots__/Path.spec.ts.snap | 3 - .../PeripheryImmutableState.spec.ts.snap | 3 - .../__snapshots__/PoolAddress.spec.ts.snap | 5 - .../__snapshots__/PositionValue.spec.ts.snap | 11 - .../test/__snapshots__/QuoterV2.spec.ts.snap | 51 - .../__snapshots__/SwapRouter.gas.spec.ts.snap | 37 - .../__snapshots__/SwapRouter.spec.ts.snap | 3 - .../test/__snapshots__/TickLens.spec.ts.snap | 5 - .../__snapshots__/V3Migrator.spec.ts.snap | 3 - lib/v3-periphery/test/contracts/WETH9.json | 156 - lib/v3-periphery/test/shared/base64.ts | 7 - .../test/shared/completeFixture.ts | 63 - .../test/shared/computePoolAddress.ts | 22 - lib/v3-periphery/test/shared/constants.ts | 15 - .../test/shared/encodePriceSqrt.ts | 16 - .../test/shared/expandTo18Decimals.ts | 5 - lib/v3-periphery/test/shared/expect.ts | 8 - .../test/shared/externalFixtures.ts | 57 - .../test/shared/extractJSONFromURI.ts | 5 - .../test/shared/formatSqrtRatioX96.spec.ts | 30 - .../test/shared/formatSqrtRatioX96.ts | 30 - .../test/shared/getPermitNFTSignature.ts | 57 - lib/v3-periphery/test/shared/path.ts | 61 - lib/v3-periphery/test/shared/permit.ts | 61 - lib/v3-periphery/test/shared/poolAtAddress.ts | 7 - lib/v3-periphery/test/shared/quoter.ts | 153 - .../test/shared/snapshotGasCost.ts | 27 - lib/v3-periphery/test/shared/ticks.ts | 9 - lib/v3-periphery/test/shared/tokenSort.ts | 10 - lib/v3-periphery/testnet-deploys.md | 3 - lib/v3-periphery/tsconfig.json | 14 - lib/v3-periphery/yarn.lock | 8111 ---------- 1047 files changed, 205168 deletions(-) delete mode 100644 lib/forge-std/.gitattributes delete mode 100644 lib/forge-std/.github/workflows/ci.yml delete mode 100644 lib/forge-std/.github/workflows/sync.yml delete mode 100644 lib/forge-std/.gitignore delete mode 100644 lib/forge-std/LICENSE-APACHE delete mode 100644 lib/forge-std/LICENSE-MIT delete mode 100644 lib/forge-std/README.md delete mode 100644 lib/forge-std/foundry.toml delete mode 100644 lib/forge-std/package.json delete mode 100755 lib/forge-std/scripts/vm.py delete mode 100644 lib/forge-std/src/Base.sol delete mode 100644 lib/forge-std/src/Script.sol delete mode 100644 lib/forge-std/src/StdAssertions.sol delete mode 100644 lib/forge-std/src/StdChains.sol delete mode 100644 lib/forge-std/src/StdCheats.sol delete mode 100644 lib/forge-std/src/StdError.sol delete mode 100644 lib/forge-std/src/StdInvariant.sol delete mode 100644 lib/forge-std/src/StdJson.sol delete mode 100644 lib/forge-std/src/StdMath.sol delete mode 100644 lib/forge-std/src/StdStorage.sol delete mode 100644 lib/forge-std/src/StdStyle.sol delete mode 100644 lib/forge-std/src/StdToml.sol delete mode 100644 lib/forge-std/src/StdUtils.sol delete mode 100644 lib/forge-std/src/Test.sol delete mode 100644 lib/forge-std/src/Vm.sol delete mode 100644 lib/forge-std/src/console.sol delete mode 100644 lib/forge-std/src/console2.sol delete mode 100644 lib/forge-std/src/interfaces/IERC1155.sol delete mode 100644 lib/forge-std/src/interfaces/IERC165.sol delete mode 100644 lib/forge-std/src/interfaces/IERC20.sol delete mode 100644 lib/forge-std/src/interfaces/IERC4626.sol delete mode 100644 lib/forge-std/src/interfaces/IERC721.sol delete mode 100644 lib/forge-std/src/interfaces/IMulticall3.sol delete mode 100644 lib/forge-std/src/mocks/MockERC20.sol delete mode 100644 lib/forge-std/src/mocks/MockERC721.sol delete mode 100644 lib/forge-std/src/safeconsole.sol delete mode 100644 lib/forge-std/test/StdAssertions.t.sol delete mode 100644 lib/forge-std/test/StdChains.t.sol delete mode 100644 lib/forge-std/test/StdCheats.t.sol delete mode 100644 lib/forge-std/test/StdError.t.sol delete mode 100644 lib/forge-std/test/StdJson.t.sol delete mode 100644 lib/forge-std/test/StdMath.t.sol delete mode 100644 lib/forge-std/test/StdStorage.t.sol delete mode 100644 lib/forge-std/test/StdStyle.t.sol delete mode 100644 lib/forge-std/test/StdToml.t.sol delete mode 100644 lib/forge-std/test/StdUtils.t.sol delete mode 100644 lib/forge-std/test/Vm.t.sol delete mode 100644 lib/forge-std/test/compilation/CompilationScript.sol delete mode 100644 lib/forge-std/test/compilation/CompilationScriptBase.sol delete mode 100644 lib/forge-std/test/compilation/CompilationTest.sol delete mode 100644 lib/forge-std/test/compilation/CompilationTestBase.sol delete mode 100644 lib/forge-std/test/fixtures/broadcast.log.json delete mode 100644 lib/forge-std/test/fixtures/test.json delete mode 100644 lib/forge-std/test/fixtures/test.toml delete mode 100644 lib/forge-std/test/mocks/MockERC20.t.sol delete mode 100644 lib/forge-std/test/mocks/MockERC721.t.sol delete mode 100644 lib/openzeppelin-contracts/.changeset/chilled-walls-develop.md delete mode 100644 lib/openzeppelin-contracts/.changeset/chilly-humans-warn.md delete mode 100644 lib/openzeppelin-contracts/.changeset/cold-cheetahs-check.md delete mode 100644 lib/openzeppelin-contracts/.changeset/config.json delete mode 100644 lib/openzeppelin-contracts/.changeset/cool-mangos-compare.md delete mode 100644 lib/openzeppelin-contracts/.changeset/curvy-crabs-repeat.md delete mode 100644 lib/openzeppelin-contracts/.changeset/dirty-cobras-smile.md delete mode 100644 lib/openzeppelin-contracts/.changeset/eight-eyes-burn.md delete mode 100644 lib/openzeppelin-contracts/.changeset/eleven-planets-relax.md delete mode 100644 lib/openzeppelin-contracts/.changeset/flat-turtles-repeat.md delete mode 100644 lib/openzeppelin-contracts/.changeset/fluffy-steaks-exist.md delete mode 100644 lib/openzeppelin-contracts/.changeset/forty-dodos-visit.md delete mode 100644 lib/openzeppelin-contracts/.changeset/friendly-nails-push.md delete mode 100644 lib/openzeppelin-contracts/.changeset/gentle-bulldogs-turn.md delete mode 100644 lib/openzeppelin-contracts/.changeset/gorgeous-badgers-vanish.md delete mode 100644 lib/openzeppelin-contracts/.changeset/heavy-baboons-give.md delete mode 100644 lib/openzeppelin-contracts/.changeset/kind-planets-cough.md delete mode 100644 lib/openzeppelin-contracts/.changeset/light-news-listen.md delete mode 100644 lib/openzeppelin-contracts/.changeset/lucky-crews-eat.md delete mode 100644 lib/openzeppelin-contracts/.changeset/nervous-eyes-teach.md delete mode 100644 lib/openzeppelin-contracts/.changeset/nervous-pans-grow.md delete mode 100644 lib/openzeppelin-contracts/.changeset/nice-paws-pull.md delete mode 100644 lib/openzeppelin-contracts/.changeset/odd-files-protect.md delete mode 100644 lib/openzeppelin-contracts/.changeset/odd-lobsters-wash.md delete mode 100644 lib/openzeppelin-contracts/.changeset/poor-chefs-cheat.md delete mode 100644 lib/openzeppelin-contracts/.changeset/shiny-poets-whisper.md delete mode 100644 lib/openzeppelin-contracts/.changeset/silver-swans-promise.md delete mode 100644 lib/openzeppelin-contracts/.changeset/smart-bugs-switch.md delete mode 100644 lib/openzeppelin-contracts/.changeset/spotty-falcons-explain.md delete mode 100644 lib/openzeppelin-contracts/.changeset/spotty-queens-own.md delete mode 100644 lib/openzeppelin-contracts/.changeset/strong-singers-talk.md delete mode 100644 lib/openzeppelin-contracts/.changeset/thick-pumpkins-report.md delete mode 100644 lib/openzeppelin-contracts/.changeset/thin-walls-drop.md delete mode 100644 lib/openzeppelin-contracts/.changeset/twenty-feet-grin.md delete mode 100644 lib/openzeppelin-contracts/.changeset/violet-moons-tell.md delete mode 100644 lib/openzeppelin-contracts/.changeset/warm-sheep-cover.md delete mode 100644 lib/openzeppelin-contracts/.changeset/wise-bobcats-speak.md delete mode 100644 lib/openzeppelin-contracts/.changeset/witty-chicken-smile.md delete mode 100644 lib/openzeppelin-contracts/.changeset/yellow-deers-walk.md delete mode 100644 lib/openzeppelin-contracts/.changeset/yellow-moles-hammer.md delete mode 100644 lib/openzeppelin-contracts/.codecov.yml delete mode 100644 lib/openzeppelin-contracts/.editorconfig delete mode 100644 lib/openzeppelin-contracts/.eslintrc delete mode 100755 lib/openzeppelin-contracts/.githooks/pre-push delete mode 100644 lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/bug_report.md delete mode 100644 lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/config.yml delete mode 100644 lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/feature_request.md delete mode 100644 lib/openzeppelin-contracts/.github/PULL_REQUEST_TEMPLATE.md delete mode 100644 lib/openzeppelin-contracts/.github/actions/gas-compare/action.yml delete mode 100644 lib/openzeppelin-contracts/.github/actions/setup/action.yml delete mode 100644 lib/openzeppelin-contracts/.github/actions/storage-layout/action.yml delete mode 100644 lib/openzeppelin-contracts/.github/workflows/actionlint.yml delete mode 100644 lib/openzeppelin-contracts/.github/workflows/changeset.yml delete mode 100644 lib/openzeppelin-contracts/.github/workflows/checks.yml delete mode 100644 lib/openzeppelin-contracts/.github/workflows/docs.yml delete mode 100644 lib/openzeppelin-contracts/.github/workflows/formal-verification.yml delete mode 100644 lib/openzeppelin-contracts/.github/workflows/release-cycle.yml delete mode 100644 lib/openzeppelin-contracts/.github/workflows/upgradeable.yml delete mode 100644 lib/openzeppelin-contracts/.gitignore delete mode 100644 lib/openzeppelin-contracts/.gitmodules delete mode 100644 lib/openzeppelin-contracts/.mocharc.js delete mode 100644 lib/openzeppelin-contracts/.prettierrc delete mode 100644 lib/openzeppelin-contracts/.solcover.js delete mode 100644 lib/openzeppelin-contracts/CHANGELOG.md delete mode 100644 lib/openzeppelin-contracts/CODE_OF_CONDUCT.md delete mode 100644 lib/openzeppelin-contracts/CONTRIBUTING.md delete mode 100644 lib/openzeppelin-contracts/FUNDING.json delete mode 100644 lib/openzeppelin-contracts/GUIDELINES.md delete mode 100644 lib/openzeppelin-contracts/LICENSE delete mode 100644 lib/openzeppelin-contracts/README.md delete mode 100644 lib/openzeppelin-contracts/RELEASING.md delete mode 100644 lib/openzeppelin-contracts/SECURITY.md delete mode 100644 lib/openzeppelin-contracts/audits/2017-03.md delete mode 100644 lib/openzeppelin-contracts/audits/2018-10.pdf delete mode 100644 lib/openzeppelin-contracts/audits/2022-10-Checkpoints.pdf delete mode 100644 lib/openzeppelin-contracts/audits/2022-10-ERC4626.pdf delete mode 100644 lib/openzeppelin-contracts/audits/2023-05-v4.9.pdf delete mode 100644 lib/openzeppelin-contracts/audits/2023-10-v5.0.pdf delete mode 100644 lib/openzeppelin-contracts/audits/README.md delete mode 100644 lib/openzeppelin-contracts/certora/.gitignore delete mode 100644 lib/openzeppelin-contracts/certora/Makefile delete mode 100644 lib/openzeppelin-contracts/certora/README.md delete mode 100644 lib/openzeppelin-contracts/certora/diff/access_manager_AccessManager.sol.patch delete mode 100644 lib/openzeppelin-contracts/certora/harnesses/AccessControlDefaultAdminRulesHarness.sol delete mode 100644 lib/openzeppelin-contracts/certora/harnesses/AccessControlHarness.sol delete mode 100644 lib/openzeppelin-contracts/certora/harnesses/AccessManagedHarness.sol delete mode 100644 lib/openzeppelin-contracts/certora/harnesses/AccessManagerHarness.sol delete mode 100644 lib/openzeppelin-contracts/certora/harnesses/DoubleEndedQueueHarness.sol delete mode 100644 lib/openzeppelin-contracts/certora/harnesses/ERC20FlashMintHarness.sol delete mode 100644 lib/openzeppelin-contracts/certora/harnesses/ERC20PermitHarness.sol delete mode 100644 lib/openzeppelin-contracts/certora/harnesses/ERC20WrapperHarness.sol delete mode 100644 lib/openzeppelin-contracts/certora/harnesses/ERC3156FlashBorrowerHarness.sol delete mode 100644 lib/openzeppelin-contracts/certora/harnesses/ERC721Harness.sol delete mode 100644 lib/openzeppelin-contracts/certora/harnesses/ERC721ReceiverHarness.sol delete mode 100644 lib/openzeppelin-contracts/certora/harnesses/EnumerableMapHarness.sol delete mode 100644 lib/openzeppelin-contracts/certora/harnesses/EnumerableSetHarness.sol delete mode 100644 lib/openzeppelin-contracts/certora/harnesses/InitializableHarness.sol delete mode 100644 lib/openzeppelin-contracts/certora/harnesses/NoncesHarness.sol delete mode 100644 lib/openzeppelin-contracts/certora/harnesses/Ownable2StepHarness.sol delete mode 100644 lib/openzeppelin-contracts/certora/harnesses/OwnableHarness.sol delete mode 100644 lib/openzeppelin-contracts/certora/harnesses/PausableHarness.sol delete mode 100644 lib/openzeppelin-contracts/certora/harnesses/TimelockControllerHarness.sol delete mode 100644 lib/openzeppelin-contracts/certora/reports/2021-10.pdf delete mode 100644 lib/openzeppelin-contracts/certora/reports/2022-03.pdf delete mode 100644 lib/openzeppelin-contracts/certora/reports/2022-05.pdf delete mode 100755 lib/openzeppelin-contracts/certora/run.js delete mode 100644 lib/openzeppelin-contracts/certora/specs.json delete mode 100644 lib/openzeppelin-contracts/certora/specs/AccessControl.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/AccessControlDefaultAdminRules.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/AccessManaged.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/AccessManager.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/DoubleEndedQueue.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/ERC20.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/ERC20FlashMint.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/ERC20Wrapper.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/ERC721.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/EnumerableMap.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/EnumerableSet.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/Initializable.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/Nonces.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/Ownable.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/Ownable2Step.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/Pausable.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/TimelockController.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/helpers/helpers.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/methods/IAccessControl.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/methods/IAccessControlDefaultAdminRules.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/methods/IAccessManaged.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/methods/IAccessManager.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/methods/IERC20.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/methods/IERC2612.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/methods/IERC3156FlashBorrower.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/methods/IERC3156FlashLender.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/methods/IERC5313.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/methods/IERC721.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/methods/IERC721Receiver.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/methods/IOwnable.spec delete mode 100644 lib/openzeppelin-contracts/certora/specs/methods/IOwnable2Step.spec delete mode 100644 lib/openzeppelin-contracts/contracts/access/AccessControl.sol delete mode 100644 lib/openzeppelin-contracts/contracts/access/IAccessControl.sol delete mode 100644 lib/openzeppelin-contracts/contracts/access/Ownable.sol delete mode 100644 lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol delete mode 100644 lib/openzeppelin-contracts/contracts/access/README.adoc delete mode 100644 lib/openzeppelin-contracts/contracts/access/extensions/AccessControlDefaultAdminRules.sol delete mode 100644 lib/openzeppelin-contracts/contracts/access/extensions/AccessControlEnumerable.sol delete mode 100644 lib/openzeppelin-contracts/contracts/access/extensions/IAccessControlDefaultAdminRules.sol delete mode 100644 lib/openzeppelin-contracts/contracts/access/extensions/IAccessControlEnumerable.sol delete mode 100644 lib/openzeppelin-contracts/contracts/access/manager/AccessManaged.sol delete mode 100644 lib/openzeppelin-contracts/contracts/access/manager/AccessManager.sol delete mode 100644 lib/openzeppelin-contracts/contracts/access/manager/AuthorityUtils.sol delete mode 100644 lib/openzeppelin-contracts/contracts/access/manager/IAccessManaged.sol delete mode 100644 lib/openzeppelin-contracts/contracts/access/manager/IAccessManager.sol delete mode 100644 lib/openzeppelin-contracts/contracts/access/manager/IAuthority.sol delete mode 100644 lib/openzeppelin-contracts/contracts/finance/README.adoc delete mode 100644 lib/openzeppelin-contracts/contracts/finance/VestingWallet.sol delete mode 100644 lib/openzeppelin-contracts/contracts/finance/VestingWalletCliff.sol delete mode 100644 lib/openzeppelin-contracts/contracts/governance/Governor.sol delete mode 100644 lib/openzeppelin-contracts/contracts/governance/IGovernor.sol delete mode 100644 lib/openzeppelin-contracts/contracts/governance/README.adoc delete mode 100644 lib/openzeppelin-contracts/contracts/governance/TimelockController.sol delete mode 100644 lib/openzeppelin-contracts/contracts/governance/extensions/GovernorCountingFractional.sol delete mode 100644 lib/openzeppelin-contracts/contracts/governance/extensions/GovernorCountingSimple.sol delete mode 100644 lib/openzeppelin-contracts/contracts/governance/extensions/GovernorPreventLateQuorum.sol delete mode 100644 lib/openzeppelin-contracts/contracts/governance/extensions/GovernorSettings.sol delete mode 100644 lib/openzeppelin-contracts/contracts/governance/extensions/GovernorStorage.sol delete mode 100644 lib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockAccess.sol delete mode 100644 lib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockCompound.sol delete mode 100644 lib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockControl.sol delete mode 100644 lib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotes.sol delete mode 100644 lib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotesQuorumFraction.sol delete mode 100644 lib/openzeppelin-contracts/contracts/governance/utils/IVotes.sol delete mode 100644 lib/openzeppelin-contracts/contracts/governance/utils/Votes.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC1155.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC1155MetadataURI.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC1155Receiver.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC1363Receiver.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC1363Spender.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC1820Implementer.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC1820Registry.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC1967.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC20Metadata.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC2309.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC2612.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC2981.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC3156.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashBorrower.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashLender.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC4906.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC5267.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC5313.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC5805.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC6372.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC721.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC721Enumerable.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC721Metadata.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC721Receiver.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC777.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC777Recipient.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/IERC777Sender.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/README.adoc delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/draft-IERC1822.sol delete mode 100644 lib/openzeppelin-contracts/contracts/interfaces/draft-IERC6093.sol delete mode 100644 lib/openzeppelin-contracts/contracts/metatx/ERC2771Context.sol delete mode 100644 lib/openzeppelin-contracts/contracts/metatx/ERC2771Forwarder.sol delete mode 100644 lib/openzeppelin-contracts/contracts/metatx/README.adoc delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/AccessManagedTarget.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/AccessManagerMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/ArraysMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/AuthorityMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/Base64Dirty.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/CallReceiverMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/ConstructorMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/ContextMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/DummyImplementation.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/EIP712Verifier.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/ERC1271WalletMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165InterfacesSupported.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165MaliciousData.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165MissingData.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165NotSupported.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165ReturnBomb.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/ERC2771ContextMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/ERC3156FlashBorrowerMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/EtherReceiverMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/InitializableMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/MerkleProofCustomHashMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/MerkleTreeMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/MulticallHelper.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/MultipleInheritanceInitializableMocks.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/PausableMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/ReentrancyAttack.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/ReentrancyMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/ReentrancyTransientMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/RegressionImplementation.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/SingleInheritanceInitializableMocks.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/Stateless.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/StorageSlotMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/TimelockReentrant.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/UpgradeableBeaconMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/VotesMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/compound/CompTimelock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/governance/GovernorFractionalMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/governance/GovernorMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/governance/GovernorPreventLateQuorumMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/governance/GovernorStorageMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/governance/GovernorTimelockAccessMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/governance/GovernorTimelockCompoundMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/governance/GovernorTimelockControlMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/governance/GovernorVoteMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/governance/GovernorWithParamsMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/proxy/BadBeacon.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/proxy/ClashingImplementation.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/proxy/UUPSUpgradeableMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/token/ERC1155ReceiverMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/token/ERC1363ForceApproveMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/token/ERC1363NoReturnMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/token/ERC1363ReceiverMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/token/ERC1363ReturnFalseMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/token/ERC1363SpenderMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/token/ERC20ApprovalMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/token/ERC20DecimalsMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/token/ERC20ExcessDecimalsMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/token/ERC20FlashMintMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/token/ERC20ForceApproveMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/token/ERC20Mock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/token/ERC20MulticallMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/token/ERC20NoReturnMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/token/ERC20Reentrant.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/token/ERC20ReturnFalseMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/token/ERC20VotesLegacyMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/token/ERC20VotesTimestampMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/token/ERC4626LimitsMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/token/ERC4626Mock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/token/ERC4626OffsetMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/token/ERC4646FeesMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/token/ERC721ConsecutiveEnumerableMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/token/ERC721ConsecutiveMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/token/ERC721ReceiverMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/mocks/token/ERC721URIStorageMock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/package.json delete mode 100644 lib/openzeppelin-contracts/contracts/proxy/Clones.sol delete mode 100644 lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sol delete mode 100644 lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Utils.sol delete mode 100644 lib/openzeppelin-contracts/contracts/proxy/Proxy.sol delete mode 100644 lib/openzeppelin-contracts/contracts/proxy/README.adoc delete mode 100644 lib/openzeppelin-contracts/contracts/proxy/beacon/BeaconProxy.sol delete mode 100644 lib/openzeppelin-contracts/contracts/proxy/beacon/IBeacon.sol delete mode 100644 lib/openzeppelin-contracts/contracts/proxy/beacon/UpgradeableBeacon.sol delete mode 100644 lib/openzeppelin-contracts/contracts/proxy/transparent/ProxyAdmin.sol delete mode 100644 lib/openzeppelin-contracts/contracts/proxy/transparent/TransparentUpgradeableProxy.sol delete mode 100644 lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol delete mode 100644 lib/openzeppelin-contracts/contracts/proxy/utils/UUPSUpgradeable.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC1155/ERC1155.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC1155/README.adoc delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Burnable.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Pausable.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Supply.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155URIStorage.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC1155/utils/ERC1155Holder.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC1155/utils/ERC1155Utils.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC20/README.adoc delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC1363.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Burnable.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Capped.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20FlashMint.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Pausable.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Permit.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Votes.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Wrapper.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC4626.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC721/README.adoc delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Burnable.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Consecutive.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Enumerable.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Pausable.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Royalty.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721URIStorage.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Votes.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Wrapper.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Enumerable.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC721/utils/ERC721Holder.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/ERC721/utils/ERC721Utils.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/common/ERC2981.sol delete mode 100644 lib/openzeppelin-contracts/contracts/token/common/README.adoc delete mode 100644 lib/openzeppelin-contracts/contracts/utils/Address.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/Arrays.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/Base64.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/Context.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/Create2.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/Errors.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/Multicall.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/Nonces.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/Packing.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/Panic.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/Pausable.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/README.adoc delete mode 100644 lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/ReentrancyGuardTransient.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/ShortStrings.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/SlotDerivation.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/Strings.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/cryptography/EIP712.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/cryptography/Hashes.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/cryptography/MessageHashUtils.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/cryptography/P256.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/cryptography/RSA.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Checker.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/math/Math.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/structs/BitMaps.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/structs/Checkpoints.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/structs/CircularBuffer.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/structs/DoubleEndedQueue.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/structs/EnumerableMap.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/structs/MerkleTree.sol delete mode 100644 lib/openzeppelin-contracts/contracts/utils/types/Time.sol delete mode 100644 lib/openzeppelin-contracts/contracts/vendor/compound/ICompoundTimelock.sol delete mode 100644 lib/openzeppelin-contracts/contracts/vendor/compound/LICENSE delete mode 100644 lib/openzeppelin-contracts/foundry.toml delete mode 100644 lib/openzeppelin-contracts/fv-requirements.txt delete mode 100644 lib/openzeppelin-contracts/hardhat.config.js delete mode 100644 lib/openzeppelin-contracts/hardhat/async-test-sanity.js delete mode 100644 lib/openzeppelin-contracts/hardhat/env-artifacts.js delete mode 100644 lib/openzeppelin-contracts/hardhat/ignore-unreachable-warnings.js delete mode 100644 lib/openzeppelin-contracts/hardhat/remappings.js delete mode 100644 lib/openzeppelin-contracts/hardhat/skip-foundry-tests.js delete mode 100644 lib/openzeppelin-contracts/hardhat/task-test-get-files.js delete mode 100644 lib/openzeppelin-contracts/lib/erc4626-tests/ERC4626.prop.sol delete mode 100644 lib/openzeppelin-contracts/lib/erc4626-tests/ERC4626.test.sol delete mode 100644 lib/openzeppelin-contracts/lib/erc4626-tests/LICENSE delete mode 100644 lib/openzeppelin-contracts/lib/erc4626-tests/README.md delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/.gitattributes delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/.github/workflows/ci.yml delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/.github/workflows/sync.yml delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/.gitignore delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/.gitmodules delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/LICENSE-APACHE delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/LICENSE-MIT delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/README.md delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/foundry.toml delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/.github/workflows/build.yml delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/.gitignore delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/LICENSE delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/Makefile delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/default.nix delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/demo/demo.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/package.json delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/test.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/test.t.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/package.json delete mode 100755 lib/openzeppelin-contracts/lib/forge-std/scripts/vm.py delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/src/Base.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/src/Script.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/src/StdAssertions.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/src/StdChains.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/src/StdCheats.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/src/StdError.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/src/StdInvariant.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/src/StdJson.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/src/StdMath.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/src/StdStorage.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/src/StdStyle.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/src/StdUtils.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/src/Test.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/src/Vm.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/src/console.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/src/console2.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/src/interfaces/IERC1155.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/src/interfaces/IERC165.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/src/interfaces/IERC20.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/src/interfaces/IERC4626.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/src/interfaces/IERC721.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/src/interfaces/IMulticall3.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/src/mocks/MockERC20.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/src/mocks/MockERC721.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/src/safeconsole.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/test/StdAssertions.t.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/test/StdChains.t.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/test/StdCheats.t.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/test/StdError.t.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/test/StdMath.t.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/test/StdStorage.t.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/test/StdStyle.t.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/test/StdUtils.t.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/test/Vm.t.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/test/compilation/CompilationScript.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/test/compilation/CompilationScriptBase.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/test/compilation/CompilationTest.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/test/compilation/CompilationTestBase.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/test/fixtures/broadcast.log.json delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/test/mocks/MockERC20.t.sol delete mode 100644 lib/openzeppelin-contracts/lib/forge-std/test/mocks/MockERC721.t.sol delete mode 100644 lib/openzeppelin-contracts/lib/halmos-cheatcodes/LICENSE delete mode 100644 lib/openzeppelin-contracts/lib/halmos-cheatcodes/README.md delete mode 100644 lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/SVM.sol delete mode 100644 lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/SymTest.sol delete mode 100644 lib/openzeppelin-contracts/logo.svg delete mode 100644 lib/openzeppelin-contracts/netlify.toml delete mode 100644 lib/openzeppelin-contracts/package-lock.json delete mode 100644 lib/openzeppelin-contracts/package.json delete mode 100644 lib/openzeppelin-contracts/remappings.txt delete mode 100644 lib/openzeppelin-contracts/renovate.json delete mode 100644 lib/openzeppelin-contracts/scripts/checks/compare-layout.js delete mode 100755 lib/openzeppelin-contracts/scripts/checks/compareGasReports.js delete mode 100755 lib/openzeppelin-contracts/scripts/checks/coverage.sh delete mode 100644 lib/openzeppelin-contracts/scripts/checks/extract-layout.js delete mode 100755 lib/openzeppelin-contracts/scripts/checks/generation.sh delete mode 100755 lib/openzeppelin-contracts/scripts/checks/inheritance-ordering.js delete mode 100644 lib/openzeppelin-contracts/scripts/gen-nav.js delete mode 100644 lib/openzeppelin-contracts/scripts/generate/format-lines.js delete mode 100755 lib/openzeppelin-contracts/scripts/generate/run.js delete mode 100644 lib/openzeppelin-contracts/scripts/generate/templates/Arrays.js delete mode 100644 lib/openzeppelin-contracts/scripts/generate/templates/Arrays.opts.js delete mode 100644 lib/openzeppelin-contracts/scripts/generate/templates/Checkpoints.js delete mode 100644 lib/openzeppelin-contracts/scripts/generate/templates/Checkpoints.opts.js delete mode 100644 lib/openzeppelin-contracts/scripts/generate/templates/Checkpoints.t.js delete mode 100644 lib/openzeppelin-contracts/scripts/generate/templates/EnumerableMap.js delete mode 100644 lib/openzeppelin-contracts/scripts/generate/templates/EnumerableMap.opts.js delete mode 100644 lib/openzeppelin-contracts/scripts/generate/templates/EnumerableSet.js delete mode 100644 lib/openzeppelin-contracts/scripts/generate/templates/EnumerableSet.opts.js delete mode 100644 lib/openzeppelin-contracts/scripts/generate/templates/MerkleProof.js delete mode 100644 lib/openzeppelin-contracts/scripts/generate/templates/MerkleProof.opts.js delete mode 100644 lib/openzeppelin-contracts/scripts/generate/templates/Packing.js delete mode 100644 lib/openzeppelin-contracts/scripts/generate/templates/Packing.opts.js delete mode 100644 lib/openzeppelin-contracts/scripts/generate/templates/Packing.t.js delete mode 100644 lib/openzeppelin-contracts/scripts/generate/templates/SafeCast.js delete mode 100644 lib/openzeppelin-contracts/scripts/generate/templates/Slot.opts.js delete mode 100644 lib/openzeppelin-contracts/scripts/generate/templates/SlotDerivation.js delete mode 100644 lib/openzeppelin-contracts/scripts/generate/templates/SlotDerivation.t.js delete mode 100644 lib/openzeppelin-contracts/scripts/generate/templates/StorageSlot.js delete mode 100644 lib/openzeppelin-contracts/scripts/generate/templates/StorageSlotMock.js delete mode 100644 lib/openzeppelin-contracts/scripts/generate/templates/conversion.js delete mode 100644 lib/openzeppelin-contracts/scripts/git-user-config.sh delete mode 100644 lib/openzeppelin-contracts/scripts/helpers.js delete mode 100755 lib/openzeppelin-contracts/scripts/prepack.sh delete mode 100755 lib/openzeppelin-contracts/scripts/prepare-docs.sh delete mode 100755 lib/openzeppelin-contracts/scripts/release/format-changelog.js delete mode 100755 lib/openzeppelin-contracts/scripts/release/synchronize-versions.js delete mode 100755 lib/openzeppelin-contracts/scripts/release/update-comment.js delete mode 100755 lib/openzeppelin-contracts/scripts/release/version.sh delete mode 100644 lib/openzeppelin-contracts/scripts/release/workflow/exit-prerelease.sh delete mode 100644 lib/openzeppelin-contracts/scripts/release/workflow/github-release.js delete mode 100644 lib/openzeppelin-contracts/scripts/release/workflow/integrity-check.sh delete mode 100644 lib/openzeppelin-contracts/scripts/release/workflow/pack.sh delete mode 100644 lib/openzeppelin-contracts/scripts/release/workflow/publish.sh delete mode 100644 lib/openzeppelin-contracts/scripts/release/workflow/rerun.js delete mode 100644 lib/openzeppelin-contracts/scripts/release/workflow/set-changesets-pr-title.js delete mode 100644 lib/openzeppelin-contracts/scripts/release/workflow/start.sh delete mode 100644 lib/openzeppelin-contracts/scripts/release/workflow/state.js delete mode 100644 lib/openzeppelin-contracts/scripts/remove-ignored-artifacts.js delete mode 100644 lib/openzeppelin-contracts/scripts/solhint-custom/index.js delete mode 100644 lib/openzeppelin-contracts/scripts/solhint-custom/package.json delete mode 100644 lib/openzeppelin-contracts/scripts/update-docs-branch.js delete mode 100644 lib/openzeppelin-contracts/scripts/upgradeable/README.md delete mode 100755 lib/openzeppelin-contracts/scripts/upgradeable/patch-apply.sh delete mode 100755 lib/openzeppelin-contracts/scripts/upgradeable/patch-save.sh delete mode 100644 lib/openzeppelin-contracts/scripts/upgradeable/transpile-onto.sh delete mode 100644 lib/openzeppelin-contracts/scripts/upgradeable/transpile.sh delete mode 100644 lib/openzeppelin-contracts/scripts/upgradeable/upgradeable.patch delete mode 100644 lib/openzeppelin-contracts/slither.config.json delete mode 100644 lib/openzeppelin-contracts/solhint.config.js delete mode 100644 lib/openzeppelin-contracts/test/TESTING.md delete mode 100644 lib/openzeppelin-contracts/test/access/AccessControl.behavior.js delete mode 100644 lib/openzeppelin-contracts/test/access/AccessControl.test.js delete mode 100644 lib/openzeppelin-contracts/test/access/Ownable.test.js delete mode 100644 lib/openzeppelin-contracts/test/access/Ownable2Step.test.js delete mode 100644 lib/openzeppelin-contracts/test/access/extensions/AccessControlDefaultAdminRules.test.js delete mode 100644 lib/openzeppelin-contracts/test/access/extensions/AccessControlEnumerable.test.js delete mode 100644 lib/openzeppelin-contracts/test/access/manager/AccessManaged.test.js delete mode 100644 lib/openzeppelin-contracts/test/access/manager/AccessManager.behavior.js delete mode 100644 lib/openzeppelin-contracts/test/access/manager/AccessManager.predicate.js delete mode 100644 lib/openzeppelin-contracts/test/access/manager/AccessManager.test.js delete mode 100644 lib/openzeppelin-contracts/test/access/manager/AuthorityUtils.test.js delete mode 100644 lib/openzeppelin-contracts/test/finance/VestingWallet.behavior.js delete mode 100644 lib/openzeppelin-contracts/test/finance/VestingWallet.test.js delete mode 100644 lib/openzeppelin-contracts/test/finance/VestingWalletCliff.test.js delete mode 100644 lib/openzeppelin-contracts/test/governance/Governor.t.sol delete mode 100644 lib/openzeppelin-contracts/test/governance/Governor.test.js delete mode 100644 lib/openzeppelin-contracts/test/governance/TimelockController.test.js delete mode 100644 lib/openzeppelin-contracts/test/governance/extensions/GovernorCountingFractional.test.js delete mode 100644 lib/openzeppelin-contracts/test/governance/extensions/GovernorERC721.test.js delete mode 100644 lib/openzeppelin-contracts/test/governance/extensions/GovernorPreventLateQuorum.test.js delete mode 100644 lib/openzeppelin-contracts/test/governance/extensions/GovernorStorage.test.js delete mode 100644 lib/openzeppelin-contracts/test/governance/extensions/GovernorTimelockAccess.test.js delete mode 100644 lib/openzeppelin-contracts/test/governance/extensions/GovernorTimelockCompound.test.js delete mode 100644 lib/openzeppelin-contracts/test/governance/extensions/GovernorTimelockControl.test.js delete mode 100644 lib/openzeppelin-contracts/test/governance/extensions/GovernorVotesQuorumFraction.test.js delete mode 100644 lib/openzeppelin-contracts/test/governance/extensions/GovernorWithParams.test.js delete mode 100644 lib/openzeppelin-contracts/test/governance/utils/ERC6372.behavior.js delete mode 100644 lib/openzeppelin-contracts/test/governance/utils/Votes.behavior.js delete mode 100644 lib/openzeppelin-contracts/test/governance/utils/Votes.test.js delete mode 100644 lib/openzeppelin-contracts/test/helpers/access-manager.js delete mode 100644 lib/openzeppelin-contracts/test/helpers/account.js delete mode 100644 lib/openzeppelin-contracts/test/helpers/constants.js delete mode 100644 lib/openzeppelin-contracts/test/helpers/deploy.js delete mode 100644 lib/openzeppelin-contracts/test/helpers/eip712-types.js delete mode 100644 lib/openzeppelin-contracts/test/helpers/eip712.js delete mode 100644 lib/openzeppelin-contracts/test/helpers/enums.js delete mode 100644 lib/openzeppelin-contracts/test/helpers/governance.js delete mode 100644 lib/openzeppelin-contracts/test/helpers/iterate.js delete mode 100644 lib/openzeppelin-contracts/test/helpers/math.js delete mode 100644 lib/openzeppelin-contracts/test/helpers/methods.js delete mode 100644 lib/openzeppelin-contracts/test/helpers/random.js delete mode 100644 lib/openzeppelin-contracts/test/helpers/storage.js delete mode 100644 lib/openzeppelin-contracts/test/helpers/strings.js delete mode 100644 lib/openzeppelin-contracts/test/helpers/time.js delete mode 100644 lib/openzeppelin-contracts/test/helpers/txpool.js delete mode 100644 lib/openzeppelin-contracts/test/metatx/ERC2771Context.test.js delete mode 100644 lib/openzeppelin-contracts/test/metatx/ERC2771Forwarder.t.sol delete mode 100644 lib/openzeppelin-contracts/test/metatx/ERC2771Forwarder.test.js delete mode 100644 lib/openzeppelin-contracts/test/proxy/Clones.behaviour.js delete mode 100644 lib/openzeppelin-contracts/test/proxy/Clones.t.sol delete mode 100644 lib/openzeppelin-contracts/test/proxy/Clones.test.js delete mode 100644 lib/openzeppelin-contracts/test/proxy/ERC1967/ERC1967Proxy.test.js delete mode 100644 lib/openzeppelin-contracts/test/proxy/ERC1967/ERC1967Utils.test.js delete mode 100644 lib/openzeppelin-contracts/test/proxy/Proxy.behaviour.js delete mode 100644 lib/openzeppelin-contracts/test/proxy/beacon/BeaconProxy.test.js delete mode 100644 lib/openzeppelin-contracts/test/proxy/beacon/UpgradeableBeacon.test.js delete mode 100644 lib/openzeppelin-contracts/test/proxy/transparent/ProxyAdmin.test.js delete mode 100644 lib/openzeppelin-contracts/test/proxy/transparent/TransparentUpgradeableProxy.behaviour.js delete mode 100644 lib/openzeppelin-contracts/test/proxy/transparent/TransparentUpgradeableProxy.test.js delete mode 100644 lib/openzeppelin-contracts/test/proxy/utils/Initializable.test.js delete mode 100644 lib/openzeppelin-contracts/test/proxy/utils/UUPSUpgradeable.test.js delete mode 100644 lib/openzeppelin-contracts/test/sanity.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC1155/ERC1155.behavior.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC1155/ERC1155.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Burnable.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Pausable.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Supply.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155URIStorage.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC1155/utils/ERC1155Holder.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC1155/utils/ERC1155Utils.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC20/ERC20.behavior.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC20/ERC20.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC1363.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Burnable.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Capped.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20FlashMint.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Pausable.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Permit.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Votes.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Wrapper.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC4626.t.sol delete mode 100644 lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC4626.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC20/utils/SafeERC20.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC721/ERC721.behavior.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC721/ERC721.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC721/ERC721Enumerable.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Burnable.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Consecutive.t.sol delete mode 100644 lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Consecutive.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Pausable.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Royalty.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721URIStorage.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Votes.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Wrapper.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC721/utils/ERC721Holder.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/ERC721/utils/ERC721Utils.test.js delete mode 100644 lib/openzeppelin-contracts/test/token/common/ERC2981.behavior.js delete mode 100644 lib/openzeppelin-contracts/test/utils/Address.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/Arrays.t.sol delete mode 100644 lib/openzeppelin-contracts/test/utils/Arrays.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/Base64.t.sol delete mode 100644 lib/openzeppelin-contracts/test/utils/Base64.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/Context.behavior.js delete mode 100644 lib/openzeppelin-contracts/test/utils/Context.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/Create2.t.sol delete mode 100644 lib/openzeppelin-contracts/test/utils/Create2.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/Multicall.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/Nonces.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/Packing.t.sol delete mode 100644 lib/openzeppelin-contracts/test/utils/Packing.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/Panic.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/Pausable.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/ReentrancyGuard.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/ShortStrings.t.sol delete mode 100644 lib/openzeppelin-contracts/test/utils/ShortStrings.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/SlotDerivation.t.sol delete mode 100644 lib/openzeppelin-contracts/test/utils/SlotDerivation.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/StorageSlot.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/Strings.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/cryptography/ECDSA.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/cryptography/EIP712.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/cryptography/MerkleProof.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/cryptography/MessageHashUtils.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/cryptography/P256.t.sol delete mode 100644 lib/openzeppelin-contracts/test/utils/cryptography/P256.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/cryptography/RSA.helper.js delete mode 100644 lib/openzeppelin-contracts/test/utils/cryptography/RSA.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/cryptography/SigVer15_186-3.rsp delete mode 100644 lib/openzeppelin-contracts/test/utils/cryptography/SignatureChecker.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/cryptography/ecdsa_secp256r1_sha256_p1363_test.json delete mode 100644 lib/openzeppelin-contracts/test/utils/introspection/ERC165.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/introspection/ERC165Checker.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/introspection/SupportsInterface.behavior.js delete mode 100644 lib/openzeppelin-contracts/test/utils/math/Math.t.sol delete mode 100644 lib/openzeppelin-contracts/test/utils/math/Math.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/math/SafeCast.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/math/SignedMath.t.sol delete mode 100644 lib/openzeppelin-contracts/test/utils/math/SignedMath.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/structs/BitMap.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/structs/Checkpoints.t.sol delete mode 100644 lib/openzeppelin-contracts/test/utils/structs/Checkpoints.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/structs/CircularBuffer.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/structs/DoubleEndedQueue.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/structs/EnumerableMap.behavior.js delete mode 100644 lib/openzeppelin-contracts/test/utils/structs/EnumerableMap.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/structs/EnumerableSet.behavior.js delete mode 100644 lib/openzeppelin-contracts/test/utils/structs/EnumerableSet.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/structs/MerkleTree.test.js delete mode 100644 lib/openzeppelin-contracts/test/utils/types/Time.test.js delete mode 100644 lib/v2-core/.gitattributes delete mode 100644 lib/v2-core/.github/stale.yml delete mode 100644 lib/v2-core/.github/workflows/CI.yml delete mode 100644 lib/v2-core/.gitignore delete mode 100644 lib/v2-core/.mocharc.json delete mode 100644 lib/v2-core/.prettierrc delete mode 100644 lib/v2-core/.waffle.json delete mode 100644 lib/v2-core/CITATION.cff delete mode 100644 lib/v2-core/LICENSE delete mode 100644 lib/v2-core/README.md delete mode 100644 lib/v2-core/contracts/UniswapV2ERC20.sol delete mode 100644 lib/v2-core/contracts/UniswapV2Factory.sol delete mode 100644 lib/v2-core/contracts/UniswapV2Pair.sol delete mode 100644 lib/v2-core/contracts/interfaces/IERC20.sol delete mode 100644 lib/v2-core/contracts/interfaces/IUniswapV2Callee.sol delete mode 100644 lib/v2-core/contracts/interfaces/IUniswapV2ERC20.sol delete mode 100644 lib/v2-core/contracts/interfaces/IUniswapV2Factory.sol delete mode 100644 lib/v2-core/contracts/interfaces/IUniswapV2Pair.sol delete mode 100644 lib/v2-core/contracts/libraries/Math.sol delete mode 100644 lib/v2-core/contracts/libraries/SafeMath.sol delete mode 100644 lib/v2-core/contracts/libraries/UQ112x112.sol delete mode 100644 lib/v2-core/contracts/test/ERC20.sol delete mode 100644 lib/v2-core/package.json delete mode 100644 lib/v2-core/test/UniswapV2ERC20.spec.ts delete mode 100644 lib/v2-core/test/UniswapV2Factory.spec.ts delete mode 100644 lib/v2-core/test/UniswapV2Pair.spec.ts delete mode 100644 lib/v2-core/test/shared/fixtures.ts delete mode 100644 lib/v2-core/test/shared/utilities.ts delete mode 100644 lib/v2-core/tsconfig.json delete mode 100644 lib/v2-core/yarn.lock delete mode 100644 lib/v3-core/.gitattributes delete mode 100644 lib/v3-core/.github/stale.yml delete mode 100644 lib/v3-core/.github/workflows/fuzz-testing.yml delete mode 100644 lib/v3-core/.github/workflows/lint.yml delete mode 100644 lib/v3-core/.github/workflows/mythx.yml delete mode 100644 lib/v3-core/.github/workflows/tests.yml delete mode 100644 lib/v3-core/.gitignore delete mode 100644 lib/v3-core/.prettierrc delete mode 100644 lib/v3-core/.solhint.json delete mode 100644 lib/v3-core/.yarnrc delete mode 100644 lib/v3-core/LICENSE delete mode 100644 lib/v3-core/README.md delete mode 100644 lib/v3-core/audits/abdk/audit.pdf delete mode 100644 lib/v3-core/audits/tob/README.md delete mode 100644 lib/v3-core/audits/tob/audit.pdf delete mode 100644 lib/v3-core/audits/tob/contracts/crytic/echidna/E2E_mint_burn.config.yaml delete mode 100644 lib/v3-core/audits/tob/contracts/crytic/echidna/E2E_mint_burn.sol delete mode 100644 lib/v3-core/audits/tob/contracts/crytic/echidna/E2E_swap.config.yaml delete mode 100644 lib/v3-core/audits/tob/contracts/crytic/echidna/E2E_swap.sol delete mode 100644 lib/v3-core/audits/tob/contracts/crytic/echidna/Other.config.yaml delete mode 100644 lib/v3-core/audits/tob/contracts/crytic/echidna/Other.sol delete mode 100644 lib/v3-core/audits/tob/contracts/crytic/echidna/Setup.sol delete mode 100644 lib/v3-core/audits/tob/contracts/crytic/manticore/001.sol delete mode 100644 lib/v3-core/audits/tob/contracts/crytic/manticore/002.sol delete mode 100644 lib/v3-core/audits/tob/contracts/crytic/manticore/003.sol delete mode 100644 lib/v3-core/bug-bounty.md delete mode 100644 lib/v3-core/contracts/NoDelegateCall.sol delete mode 100644 lib/v3-core/contracts/UniswapV3Factory.sol delete mode 100644 lib/v3-core/contracts/UniswapV3Pool.sol delete mode 100644 lib/v3-core/contracts/UniswapV3PoolDeployer.sol delete mode 100644 lib/v3-core/contracts/interfaces/IERC20Minimal.sol delete mode 100644 lib/v3-core/contracts/interfaces/IUniswapV3Factory.sol delete mode 100644 lib/v3-core/contracts/interfaces/IUniswapV3Pool.sol delete mode 100644 lib/v3-core/contracts/interfaces/IUniswapV3PoolDeployer.sol delete mode 100644 lib/v3-core/contracts/interfaces/LICENSE delete mode 100644 lib/v3-core/contracts/interfaces/callback/IUniswapV3FlashCallback.sol delete mode 100644 lib/v3-core/contracts/interfaces/callback/IUniswapV3MintCallback.sol delete mode 100644 lib/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol delete mode 100644 lib/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol delete mode 100644 lib/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol delete mode 100644 lib/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol delete mode 100644 lib/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol delete mode 100644 lib/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol delete mode 100644 lib/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol delete mode 100644 lib/v3-core/contracts/libraries/BitMath.sol delete mode 100644 lib/v3-core/contracts/libraries/FixedPoint128.sol delete mode 100644 lib/v3-core/contracts/libraries/FixedPoint96.sol delete mode 100644 lib/v3-core/contracts/libraries/FullMath.sol delete mode 100644 lib/v3-core/contracts/libraries/LICENSE delete mode 100644 lib/v3-core/contracts/libraries/LICENSE_MIT delete mode 100644 lib/v3-core/contracts/libraries/LiquidityMath.sol delete mode 100644 lib/v3-core/contracts/libraries/LowGasSafeMath.sol delete mode 100644 lib/v3-core/contracts/libraries/Oracle.sol delete mode 100644 lib/v3-core/contracts/libraries/Position.sol delete mode 100644 lib/v3-core/contracts/libraries/SafeCast.sol delete mode 100644 lib/v3-core/contracts/libraries/SqrtPriceMath.sol delete mode 100644 lib/v3-core/contracts/libraries/SwapMath.sol delete mode 100644 lib/v3-core/contracts/libraries/Tick.sol delete mode 100644 lib/v3-core/contracts/libraries/TickBitmap.sol delete mode 100644 lib/v3-core/contracts/libraries/TickMath.sol delete mode 100644 lib/v3-core/contracts/libraries/TransferHelper.sol delete mode 100644 lib/v3-core/contracts/libraries/UnsafeMath.sol delete mode 100644 lib/v3-core/contracts/test/BitMathEchidnaTest.sol delete mode 100644 lib/v3-core/contracts/test/BitMathTest.sol delete mode 100644 lib/v3-core/contracts/test/FullMathEchidnaTest.sol delete mode 100644 lib/v3-core/contracts/test/FullMathTest.sol delete mode 100644 lib/v3-core/contracts/test/LiquidityMathTest.sol delete mode 100644 lib/v3-core/contracts/test/LowGasSafeMathEchidnaTest.sol delete mode 100644 lib/v3-core/contracts/test/MockTimeUniswapV3Pool.sol delete mode 100644 lib/v3-core/contracts/test/MockTimeUniswapV3PoolDeployer.sol delete mode 100644 lib/v3-core/contracts/test/NoDelegateCallTest.sol delete mode 100644 lib/v3-core/contracts/test/OracleEchidnaTest.sol delete mode 100644 lib/v3-core/contracts/test/OracleTest.sol delete mode 100644 lib/v3-core/contracts/test/SqrtPriceMathEchidnaTest.sol delete mode 100644 lib/v3-core/contracts/test/SqrtPriceMathTest.sol delete mode 100644 lib/v3-core/contracts/test/SwapMathEchidnaTest.sol delete mode 100644 lib/v3-core/contracts/test/SwapMathTest.sol delete mode 100644 lib/v3-core/contracts/test/TestERC20.sol delete mode 100644 lib/v3-core/contracts/test/TestUniswapV3Callee.sol delete mode 100644 lib/v3-core/contracts/test/TestUniswapV3ReentrantCallee.sol delete mode 100644 lib/v3-core/contracts/test/TestUniswapV3Router.sol delete mode 100644 lib/v3-core/contracts/test/TestUniswapV3SwapPay.sol delete mode 100644 lib/v3-core/contracts/test/TickBitmapEchidnaTest.sol delete mode 100644 lib/v3-core/contracts/test/TickBitmapTest.sol delete mode 100644 lib/v3-core/contracts/test/TickEchidnaTest.sol delete mode 100644 lib/v3-core/contracts/test/TickMathEchidnaTest.sol delete mode 100644 lib/v3-core/contracts/test/TickMathTest.sol delete mode 100644 lib/v3-core/contracts/test/TickOverflowSafetyEchidnaTest.sol delete mode 100644 lib/v3-core/contracts/test/TickTest.sol delete mode 100644 lib/v3-core/contracts/test/UniswapV3PoolSwapTest.sol delete mode 100644 lib/v3-core/contracts/test/UnsafeMathEchidnaTest.sol delete mode 100644 lib/v3-core/echidna.config.yml delete mode 100644 lib/v3-core/hardhat.config.ts delete mode 100644 lib/v3-core/package.json delete mode 100644 lib/v3-core/test/BitMath.spec.ts delete mode 100644 lib/v3-core/test/FullMath.spec.ts delete mode 100644 lib/v3-core/test/LiquidityMath.spec.ts delete mode 100644 lib/v3-core/test/NoDelegateCall.spec.ts delete mode 100644 lib/v3-core/test/Oracle.spec.ts delete mode 100644 lib/v3-core/test/SqrtPriceMath.spec.ts delete mode 100644 lib/v3-core/test/SwapMath.spec.ts delete mode 100644 lib/v3-core/test/Tick.spec.ts delete mode 100644 lib/v3-core/test/TickBitmap.spec.ts delete mode 100644 lib/v3-core/test/TickMath.spec.ts delete mode 100644 lib/v3-core/test/UniswapV3Factory.spec.ts delete mode 100644 lib/v3-core/test/UniswapV3Pool.arbitrage.spec.ts delete mode 100644 lib/v3-core/test/UniswapV3Pool.gas.spec.ts delete mode 100644 lib/v3-core/test/UniswapV3Pool.spec.ts delete mode 100644 lib/v3-core/test/UniswapV3Pool.swaps.spec.ts delete mode 100644 lib/v3-core/test/UniswapV3Router.spec.ts delete mode 100644 lib/v3-core/test/__snapshots__/BitMath.spec.ts.snap delete mode 100644 lib/v3-core/test/__snapshots__/LiquidityMath.spec.ts.snap delete mode 100644 lib/v3-core/test/__snapshots__/NoDelegateCall.spec.ts.snap delete mode 100644 lib/v3-core/test/__snapshots__/Oracle.spec.ts.snap delete mode 100644 lib/v3-core/test/__snapshots__/SqrtPriceMath.spec.ts.snap delete mode 100644 lib/v3-core/test/__snapshots__/SwapMath.spec.ts.snap delete mode 100644 lib/v3-core/test/__snapshots__/TickBitmap.spec.ts.snap delete mode 100644 lib/v3-core/test/__snapshots__/TickMath.spec.ts.snap delete mode 100644 lib/v3-core/test/__snapshots__/UniswapV3Factory.spec.ts.snap delete mode 100644 lib/v3-core/test/__snapshots__/UniswapV3Pool.arbitrage.spec.ts.snap delete mode 100644 lib/v3-core/test/__snapshots__/UniswapV3Pool.gas.spec.ts.snap delete mode 100644 lib/v3-core/test/__snapshots__/UniswapV3Pool.swaps.spec.ts.snap delete mode 100644 lib/v3-core/test/shared/checkObservationEquals.ts delete mode 100644 lib/v3-core/test/shared/expect.ts delete mode 100644 lib/v3-core/test/shared/fixtures.ts delete mode 100644 lib/v3-core/test/shared/format.ts delete mode 100644 lib/v3-core/test/shared/snapshotGasCost.ts delete mode 100644 lib/v3-core/test/shared/utilities.ts delete mode 100644 lib/v3-core/tsconfig.json delete mode 100644 lib/v3-core/yarn.lock delete mode 100644 lib/v3-periphery/.gitattributes delete mode 100644 lib/v3-periphery/.github/stale.yml delete mode 100644 lib/v3-periphery/.github/workflows/lint.yml delete mode 100644 lib/v3-periphery/.github/workflows/tests.yml delete mode 100644 lib/v3-periphery/.gitignore delete mode 100644 lib/v3-periphery/.prettierignore delete mode 100644 lib/v3-periphery/.prettierrc delete mode 100644 lib/v3-periphery/.solhint.json delete mode 100644 lib/v3-periphery/.yarnrc delete mode 100644 lib/v3-periphery/LICENSE delete mode 100644 lib/v3-periphery/README.md delete mode 100644 lib/v3-periphery/audits/abdk/audit.pdf delete mode 100644 lib/v3-periphery/bug-bounty.md delete mode 100644 lib/v3-periphery/contracts/NonfungiblePositionManager.sol delete mode 100644 lib/v3-periphery/contracts/NonfungibleTokenPositionDescriptor.sol delete mode 100644 lib/v3-periphery/contracts/SwapRouter.sol delete mode 100644 lib/v3-periphery/contracts/V3Migrator.sol delete mode 100644 lib/v3-periphery/contracts/base/BlockTimestamp.sol delete mode 100644 lib/v3-periphery/contracts/base/ERC721Permit.sol delete mode 100644 lib/v3-periphery/contracts/base/LiquidityManagement.sol delete mode 100644 lib/v3-periphery/contracts/base/Multicall.sol delete mode 100644 lib/v3-periphery/contracts/base/PeripheryImmutableState.sol delete mode 100644 lib/v3-periphery/contracts/base/PeripheryPayments.sol delete mode 100644 lib/v3-periphery/contracts/base/PeripheryPaymentsWithFee.sol delete mode 100644 lib/v3-periphery/contracts/base/PeripheryValidation.sol delete mode 100644 lib/v3-periphery/contracts/base/PoolInitializer.sol delete mode 100644 lib/v3-periphery/contracts/base/SelfPermit.sol delete mode 100644 lib/v3-periphery/contracts/examples/PairFlash.sol delete mode 100644 lib/v3-periphery/contracts/interfaces/IERC20Metadata.sol delete mode 100644 lib/v3-periphery/contracts/interfaces/IERC721Permit.sol delete mode 100644 lib/v3-periphery/contracts/interfaces/IMulticall.sol delete mode 100644 lib/v3-periphery/contracts/interfaces/INonfungiblePositionManager.sol delete mode 100644 lib/v3-periphery/contracts/interfaces/INonfungibleTokenPositionDescriptor.sol delete mode 100644 lib/v3-periphery/contracts/interfaces/IPeripheryImmutableState.sol delete mode 100644 lib/v3-periphery/contracts/interfaces/IPeripheryPayments.sol delete mode 100644 lib/v3-periphery/contracts/interfaces/IPeripheryPaymentsWithFee.sol delete mode 100644 lib/v3-periphery/contracts/interfaces/IPoolInitializer.sol delete mode 100644 lib/v3-periphery/contracts/interfaces/IQuoter.sol delete mode 100644 lib/v3-periphery/contracts/interfaces/IQuoterV2.sol delete mode 100644 lib/v3-periphery/contracts/interfaces/ISelfPermit.sol delete mode 100644 lib/v3-periphery/contracts/interfaces/ISwapRouter.sol delete mode 100644 lib/v3-periphery/contracts/interfaces/ITickLens.sol delete mode 100644 lib/v3-periphery/contracts/interfaces/IV3Migrator.sol delete mode 100644 lib/v3-periphery/contracts/interfaces/external/IERC1271.sol delete mode 100644 lib/v3-periphery/contracts/interfaces/external/IERC20PermitAllowed.sol delete mode 100644 lib/v3-periphery/contracts/interfaces/external/IWETH9.sol delete mode 100644 lib/v3-periphery/contracts/lens/Quoter.sol delete mode 100644 lib/v3-periphery/contracts/lens/QuoterV2.sol delete mode 100644 lib/v3-periphery/contracts/lens/README.md delete mode 100644 lib/v3-periphery/contracts/lens/TickLens.sol delete mode 100644 lib/v3-periphery/contracts/lens/UniswapInterfaceMulticall.sol delete mode 100644 lib/v3-periphery/contracts/libraries/BytesLib.sol delete mode 100644 lib/v3-periphery/contracts/libraries/CallbackValidation.sol delete mode 100644 lib/v3-periphery/contracts/libraries/ChainId.sol delete mode 100644 lib/v3-periphery/contracts/libraries/HexStrings.sol delete mode 100644 lib/v3-periphery/contracts/libraries/LiquidityAmounts.sol delete mode 100644 lib/v3-periphery/contracts/libraries/NFTDescriptor.sol delete mode 100644 lib/v3-periphery/contracts/libraries/NFTSVG.sol delete mode 100644 lib/v3-periphery/contracts/libraries/OracleLibrary.sol delete mode 100644 lib/v3-periphery/contracts/libraries/Path.sol delete mode 100644 lib/v3-periphery/contracts/libraries/PoolAddress.sol delete mode 100644 lib/v3-periphery/contracts/libraries/PoolTicksCounter.sol delete mode 100644 lib/v3-periphery/contracts/libraries/PositionKey.sol delete mode 100644 lib/v3-periphery/contracts/libraries/PositionValue.sol delete mode 100644 lib/v3-periphery/contracts/libraries/SqrtPriceMathPartial.sol delete mode 100644 lib/v3-periphery/contracts/libraries/TokenRatioSortOrder.sol delete mode 100644 lib/v3-periphery/contracts/libraries/TransferHelper.sol delete mode 100644 lib/v3-periphery/contracts/test/Base64Test.sol delete mode 100644 lib/v3-periphery/contracts/test/LiquidityAmountsTest.sol delete mode 100644 lib/v3-periphery/contracts/test/MockObservable.sol delete mode 100644 lib/v3-periphery/contracts/test/MockObservations.sol delete mode 100644 lib/v3-periphery/contracts/test/MockTimeNonfungiblePositionManager.sol delete mode 100644 lib/v3-periphery/contracts/test/MockTimeSwapRouter.sol delete mode 100644 lib/v3-periphery/contracts/test/NFTDescriptorTest.sol delete mode 100644 lib/v3-periphery/contracts/test/NonfungiblePositionManagerPositionsGasTest.sol delete mode 100644 lib/v3-periphery/contracts/test/OracleTest.sol delete mode 100644 lib/v3-periphery/contracts/test/PathTest.sol delete mode 100644 lib/v3-periphery/contracts/test/PeripheryImmutableStateTest.sol delete mode 100644 lib/v3-periphery/contracts/test/PoolAddressTest.sol delete mode 100644 lib/v3-periphery/contracts/test/PoolTicksCounterTest.sol delete mode 100644 lib/v3-periphery/contracts/test/PositionValueTest.sol delete mode 100644 lib/v3-periphery/contracts/test/SelfPermitTest.sol delete mode 100644 lib/v3-periphery/contracts/test/TestCallbackValidation.sol delete mode 100644 lib/v3-periphery/contracts/test/TestERC20.sol delete mode 100644 lib/v3-periphery/contracts/test/TestERC20Metadata.sol delete mode 100644 lib/v3-periphery/contracts/test/TestERC20PermitAllowed.sol delete mode 100644 lib/v3-periphery/contracts/test/TestMulticall.sol delete mode 100644 lib/v3-periphery/contracts/test/TestPositionNFTOwner.sol delete mode 100644 lib/v3-periphery/contracts/test/TestUniswapV3Callee.sol delete mode 100644 lib/v3-periphery/contracts/test/TickLensTest.sol delete mode 100644 lib/v3-periphery/deploys.md delete mode 100644 lib/v3-periphery/hardhat.config.ts delete mode 100644 lib/v3-periphery/package.json delete mode 100644 lib/v3-periphery/test/Base64.spec.ts delete mode 100644 lib/v3-periphery/test/CallbackValidation.spec.ts delete mode 100644 lib/v3-periphery/test/LiquidityAmounts.spec.ts delete mode 100644 lib/v3-periphery/test/Multicall.spec.ts delete mode 100644 lib/v3-periphery/test/NFTDescriptor.spec.ts delete mode 100644 lib/v3-periphery/test/NonfungiblePositionManager.spec.ts delete mode 100644 lib/v3-periphery/test/NonfungibleTokenPositionDescriptor.spec.ts delete mode 100644 lib/v3-periphery/test/OracleLibrary.spec.ts delete mode 100644 lib/v3-periphery/test/PairFlash.spec.ts delete mode 100644 lib/v3-periphery/test/Path.spec.ts delete mode 100644 lib/v3-periphery/test/PeripheryImmutableState.spec.ts delete mode 100644 lib/v3-periphery/test/PoolAddress.spec.ts delete mode 100644 lib/v3-periphery/test/PoolTicksCounter.spec.ts delete mode 100644 lib/v3-periphery/test/PositionValue.spec.ts delete mode 100644 lib/v3-periphery/test/Quoter.spec.ts delete mode 100644 lib/v3-periphery/test/QuoterV2.spec.ts delete mode 100644 lib/v3-periphery/test/SelfPermit.spec.ts delete mode 100644 lib/v3-periphery/test/SwapRouter.gas.spec.ts delete mode 100644 lib/v3-periphery/test/SwapRouter.spec.ts delete mode 100644 lib/v3-periphery/test/TickLens.spec.ts delete mode 100644 lib/v3-periphery/test/V3Migrator.spec.ts delete mode 100644 lib/v3-periphery/test/__snapshots__/Base64.spec.ts.snap delete mode 100644 lib/v3-periphery/test/__snapshots__/LiquidityAmounts.spec.ts.snap delete mode 100644 lib/v3-periphery/test/__snapshots__/Multicall.spec.ts.snap delete mode 100644 lib/v3-periphery/test/__snapshots__/NFTDescriptor.spec.ts.snap delete mode 100644 lib/v3-periphery/test/__snapshots__/NFTDescriptor.svg delete mode 100644 lib/v3-periphery/test/__snapshots__/NonfungiblePositionManager.spec.ts.snap delete mode 100644 lib/v3-periphery/test/__snapshots__/OracleLibrary.spec.ts.snap delete mode 100644 lib/v3-periphery/test/__snapshots__/PairFlash.spec.ts.snap delete mode 100644 lib/v3-periphery/test/__snapshots__/Path.spec.ts.snap delete mode 100644 lib/v3-periphery/test/__snapshots__/PeripheryImmutableState.spec.ts.snap delete mode 100644 lib/v3-periphery/test/__snapshots__/PoolAddress.spec.ts.snap delete mode 100644 lib/v3-periphery/test/__snapshots__/PositionValue.spec.ts.snap delete mode 100644 lib/v3-periphery/test/__snapshots__/QuoterV2.spec.ts.snap delete mode 100644 lib/v3-periphery/test/__snapshots__/SwapRouter.gas.spec.ts.snap delete mode 100644 lib/v3-periphery/test/__snapshots__/SwapRouter.spec.ts.snap delete mode 100644 lib/v3-periphery/test/__snapshots__/TickLens.spec.ts.snap delete mode 100644 lib/v3-periphery/test/__snapshots__/V3Migrator.spec.ts.snap delete mode 100644 lib/v3-periphery/test/contracts/WETH9.json delete mode 100644 lib/v3-periphery/test/shared/base64.ts delete mode 100644 lib/v3-periphery/test/shared/completeFixture.ts delete mode 100644 lib/v3-periphery/test/shared/computePoolAddress.ts delete mode 100644 lib/v3-periphery/test/shared/constants.ts delete mode 100644 lib/v3-periphery/test/shared/encodePriceSqrt.ts delete mode 100644 lib/v3-periphery/test/shared/expandTo18Decimals.ts delete mode 100644 lib/v3-periphery/test/shared/expect.ts delete mode 100644 lib/v3-periphery/test/shared/externalFixtures.ts delete mode 100644 lib/v3-periphery/test/shared/extractJSONFromURI.ts delete mode 100644 lib/v3-periphery/test/shared/formatSqrtRatioX96.spec.ts delete mode 100644 lib/v3-periphery/test/shared/formatSqrtRatioX96.ts delete mode 100644 lib/v3-periphery/test/shared/getPermitNFTSignature.ts delete mode 100644 lib/v3-periphery/test/shared/path.ts delete mode 100644 lib/v3-periphery/test/shared/permit.ts delete mode 100644 lib/v3-periphery/test/shared/poolAtAddress.ts delete mode 100644 lib/v3-periphery/test/shared/quoter.ts delete mode 100644 lib/v3-periphery/test/shared/snapshotGasCost.ts delete mode 100644 lib/v3-periphery/test/shared/ticks.ts delete mode 100644 lib/v3-periphery/test/shared/tokenSort.ts delete mode 100644 lib/v3-periphery/testnet-deploys.md delete mode 100644 lib/v3-periphery/tsconfig.json delete mode 100644 lib/v3-periphery/yarn.lock diff --git a/.gitmodules b/.gitmodules index e29ed65..e69de29 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,15 +0,0 @@ -[submodule "lib/v3-core"] - path = lib/v3-core - url = https://github.com/Uniswap/v3-core -[submodule "lib/v2-core"] - path = lib/v2-core - url = https://github.com/Uniswap/v2-core -[submodule "lib/openzeppelin-contracts"] - path = lib/openzeppelin-contracts - url = https://github.com/openzeppelin/openzeppelin-contracts -[submodule "lib/v3-periphery"] - path = lib/v3-periphery - url = https://github.com/Uniswap/v3-periphery -[submodule "lib/forge-std"] - path = lib/forge-std - url = https://github.com/foundry-rs/forge-std diff --git a/lib/forge-std/.gitattributes b/lib/forge-std/.gitattributes deleted file mode 100644 index 27042d4..0000000 --- a/lib/forge-std/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -src/Vm.sol linguist-generated diff --git a/lib/forge-std/.github/workflows/ci.yml b/lib/forge-std/.github/workflows/ci.yml deleted file mode 100644 index 2d68e91..0000000 --- a/lib/forge-std/.github/workflows/ci.yml +++ /dev/null @@ -1,128 +0,0 @@ -name: CI - -on: - workflow_dispatch: - pull_request: - push: - branches: - - master - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly - - - name: Print forge version - run: forge --version - - # Backwards compatibility checks: - # - the oldest and newest version of each supported minor version - # - versions with specific issues - - name: Check compatibility with latest - if: always() - run: | - output=$(forge build --skip test) - if echo "$output" | grep -q "Warning"; then - echo "$output" - exit 1 - fi - - - name: Check compatibility with 0.8.0 - if: always() - run: | - output=$(forge build --skip test --use solc:0.8.0) - if echo "$output" | grep -q "Warning"; then - echo "$output" - exit 1 - fi - - - name: Check compatibility with 0.7.6 - if: always() - run: | - output=$(forge build --skip test --use solc:0.7.6) - if echo "$output" | grep -q "Warning"; then - echo "$output" - exit 1 - fi - - - name: Check compatibility with 0.7.0 - if: always() - run: | - output=$(forge build --skip test --use solc:0.7.0) - if echo "$output" | grep -q "Warning"; then - echo "$output" - exit 1 - fi - - - name: Check compatibility with 0.6.12 - if: always() - run: | - output=$(forge build --skip test --use solc:0.6.12) - if echo "$output" | grep -q "Warning"; then - echo "$output" - exit 1 - fi - - - name: Check compatibility with 0.6.2 - if: always() - run: | - output=$(forge build --skip test --use solc:0.6.2) - if echo "$output" | grep -q "Warning"; then - echo "$output" - exit 1 - fi - - # 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@v4 - - - name: Install Foundry - uses: foundry-rs/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@v4 - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly - - - name: Print forge version - run: forge --version - - - name: Check formatting - run: forge fmt --check diff --git a/lib/forge-std/.github/workflows/sync.yml b/lib/forge-std/.github/workflows/sync.yml deleted file mode 100644 index 9b170f0..0000000 --- a/lib/forge-std/.github/workflows/sync.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: Sync Release Branch - -on: - release: - types: - - created - -jobs: - sync-release-branch: - runs-on: ubuntu-latest - if: startsWith(github.event.release.tag_name, 'v1') - steps: - - name: Check out the repo - uses: actions/checkout@v4 - with: - fetch-depth: 0 - ref: v1 - - # The email is derived from the bots user id, - # found here: https://api.github.com/users/github-actions%5Bbot%5D - - name: Configure Git - run: | - git config user.name github-actions[bot] - git config user.email 41898282+github-actions[bot]@users.noreply.github.com - - - name: Sync Release Branch - run: | - git fetch --tags - git checkout v1 - git reset --hard ${GITHUB_REF} - git push --force diff --git a/lib/forge-std/.gitignore b/lib/forge-std/.gitignore deleted file mode 100644 index 756106d..0000000 --- a/lib/forge-std/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -cache/ -out/ -.vscode -.idea diff --git a/lib/forge-std/LICENSE-APACHE b/lib/forge-std/LICENSE-APACHE deleted file mode 100644 index cf01a49..0000000 --- a/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/forge-std/LICENSE-MIT b/lib/forge-std/LICENSE-MIT deleted file mode 100644 index 28f9830..0000000 --- a/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/forge-std/README.md b/lib/forge-std/README.md deleted file mode 100644 index 0cb8660..0000000 --- a/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 - -Contains various assertions. - -### `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/forge-std/foundry.toml b/lib/forge-std/foundry.toml deleted file mode 100644 index 2bc66fa..0000000 --- a/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://eth-mainnet.alchemyapi.io/v2/WV407BEiBmjNJfKo9Uo_55u0z0ITyCOX" # Different API key. -optimism_sepolia = "https://sepolia.optimism.io/" # Adds a trailing slash. -arbitrum_one_sepolia = "https://sepolia-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/forge-std/package.json b/lib/forge-std/package.json deleted file mode 100644 index 7e66185..0000000 --- a/lib/forge-std/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "forge-std", - "version": "1.9.1", - "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/forge-std/scripts/vm.py b/lib/forge-std/scripts/vm.py deleted file mode 100755 index f0537db..0000000 --- a/lib/forge-std/scripts/vm.py +++ /dev/null @@ -1,635 +0,0 @@ -#!/usr/bin/env python3 - -import copy -import json -import re -import subprocess -from enum import Enum as PyEnum -from typing import Callable -from urllib import request - -VoidFn = Callable[[], None] - -CHEATCODES_JSON_URL = "https://raw.githubusercontent.com/foundry-rs/foundry/master/crates/cheatcodes/assets/cheatcodes.json" -OUT_PATH = "src/Vm.sol" - -VM_SAFE_DOC = """\ -/// The `VmSafe` interface does not allow manipulation of the EVM state or other actions that may -/// result in Script simulations differing from on-chain execution. It is recommended to only use -/// these cheats in scripts. -""" - -VM_DOC = """\ -/// The `Vm` interface does allow manipulation of the EVM state. These are all intended to be used -/// in tests, but it is not recommended to use these cheats in scripts. -""" - - -def main(): - json_str = request.urlopen(CHEATCODES_JSON_URL).read().decode("utf-8") - contract = Cheatcodes.from_json(json_str) - - ccs = contract.cheatcodes - ccs = list(filter(lambda cc: cc.status not in ["experimental", "internal"], ccs)) - ccs.sort(key=lambda cc: cc.func.id) - - safe = list(filter(lambda cc: cc.safety == "safe", ccs)) - safe.sort(key=CmpCheatcode) - unsafe = list(filter(lambda cc: cc.safety == "unsafe", ccs)) - unsafe.sort(key=CmpCheatcode) - assert len(safe) + len(unsafe) == len(ccs) - - prefix_with_group_headers(safe) - prefix_with_group_headers(unsafe) - - out = "" - - out += "// Automatically @generated by scripts/vm.py. Do not modify manually.\n\n" - - pp = CheatcodesPrinter( - spdx_identifier="MIT OR Apache-2.0", - solidity_requirement=">=0.6.2 <0.9.0", - abicoder_pragma=True, - ) - pp.p_prelude() - pp.prelude = False - out += pp.finish() - - out += "\n\n" - out += VM_SAFE_DOC - vm_safe = Cheatcodes( - # TODO: Custom errors were introduced in 0.8.4 - errors=[], # contract.errors - events=contract.events, - enums=contract.enums, - structs=contract.structs, - cheatcodes=safe, - ) - pp.p_contract(vm_safe, "VmSafe") - out += pp.finish() - - out += "\n\n" - out += VM_DOC - vm_unsafe = Cheatcodes( - errors=[], - events=[], - enums=[], - structs=[], - cheatcodes=unsafe, - ) - pp.p_contract(vm_unsafe, "Vm", "VmSafe") - out += pp.finish() - - # Compatibility with <0.8.0 - def memory_to_calldata(m: re.Match) -> str: - return " calldata " + m.group(1) - - out = re.sub(r" memory (.*returns)", memory_to_calldata, out) - - with open(OUT_PATH, "w") as f: - f.write(out) - - forge_fmt = ["forge", "fmt", OUT_PATH] - res = subprocess.run(forge_fmt) - assert res.returncode == 0, f"command failed: {forge_fmt}" - - print(f"Wrote to {OUT_PATH}") - - -class CmpCheatcode: - cheatcode: "Cheatcode" - - def __init__(self, cheatcode: "Cheatcode"): - self.cheatcode = cheatcode - - def __lt__(self, other: "CmpCheatcode") -> bool: - return cmp_cheatcode(self.cheatcode, other.cheatcode) < 0 - - def __eq__(self, other: "CmpCheatcode") -> bool: - return cmp_cheatcode(self.cheatcode, other.cheatcode) == 0 - - def __gt__(self, other: "CmpCheatcode") -> bool: - return cmp_cheatcode(self.cheatcode, other.cheatcode) > 0 - - -def cmp_cheatcode(a: "Cheatcode", b: "Cheatcode") -> int: - if a.group != b.group: - return -1 if a.group < b.group else 1 - if a.status != b.status: - return -1 if a.status < b.status else 1 - if a.safety != b.safety: - return -1 if a.safety < b.safety else 1 - if a.func.id != b.func.id: - return -1 if a.func.id < b.func.id else 1 - return 0 - - -# HACK: A way to add group header comments without having to modify printer code -def prefix_with_group_headers(cheats: list["Cheatcode"]): - s = set() - for i, cheat in enumerate(cheats): - if cheat.group in s: - continue - - s.add(cheat.group) - - c = copy.deepcopy(cheat) - c.func.description = "" - c.func.declaration = f"// ======== {group(c.group)} ========" - cheats.insert(i, c) - return cheats - - -def group(s: str) -> str: - if s == "evm": - return "EVM" - if s == "json": - return "JSON" - return s[0].upper() + s[1:] - - -class Visibility(PyEnum): - EXTERNAL: str = "external" - PUBLIC: str = "public" - INTERNAL: str = "internal" - PRIVATE: str = "private" - - def __str__(self): - return self.value - - -class Mutability(PyEnum): - PURE: str = "pure" - VIEW: str = "view" - NONE: str = "" - - def __str__(self): - return self.value - - -class Function: - id: str - description: str - declaration: str - visibility: Visibility - mutability: Mutability - signature: str - selector: str - selector_bytes: bytes - - def __init__( - self, - id: str, - description: str, - declaration: str, - visibility: Visibility, - mutability: Mutability, - signature: str, - selector: str, - selector_bytes: bytes, - ): - self.id = id - self.description = description - self.declaration = declaration - self.visibility = visibility - self.mutability = mutability - self.signature = signature - self.selector = selector - self.selector_bytes = selector_bytes - - @staticmethod - def from_dict(d: dict) -> "Function": - return Function( - d["id"], - d["description"], - d["declaration"], - Visibility(d["visibility"]), - Mutability(d["mutability"]), - d["signature"], - d["selector"], - bytes(d["selectorBytes"]), - ) - - -class Cheatcode: - func: Function - group: str - status: str - safety: str - - def __init__(self, func: Function, group: str, status: str, safety: str): - self.func = func - self.group = group - self.status = status - self.safety = safety - - @staticmethod - def from_dict(d: dict) -> "Cheatcode": - return Cheatcode( - Function.from_dict(d["func"]), - str(d["group"]), - str(d["status"]), - str(d["safety"]), - ) - - -class Error: - name: str - description: str - declaration: str - - def __init__(self, name: str, description: str, declaration: str): - self.name = name - self.description = description - self.declaration = declaration - - @staticmethod - def from_dict(d: dict) -> "Error": - return Error(**d) - - -class Event: - name: str - description: str - declaration: str - - def __init__(self, name: str, description: str, declaration: str): - self.name = name - self.description = description - self.declaration = declaration - - @staticmethod - def from_dict(d: dict) -> "Event": - return Event(**d) - - -class EnumVariant: - name: str - description: str - - def __init__(self, name: str, description: str): - self.name = name - self.description = description - - -class Enum: - name: str - description: str - variants: list[EnumVariant] - - def __init__(self, name: str, description: str, variants: list[EnumVariant]): - self.name = name - self.description = description - self.variants = variants - - @staticmethod - def from_dict(d: dict) -> "Enum": - return Enum( - d["name"], - d["description"], - list(map(lambda v: EnumVariant(**v), d["variants"])), - ) - - -class StructField: - name: str - ty: str - description: str - - def __init__(self, name: str, ty: str, description: str): - self.name = name - self.ty = ty - self.description = description - - -class Struct: - name: str - description: str - fields: list[StructField] - - def __init__(self, name: str, description: str, fields: list[StructField]): - self.name = name - self.description = description - self.fields = fields - - @staticmethod - def from_dict(d: dict) -> "Struct": - return Struct( - d["name"], - d["description"], - list(map(lambda f: StructField(**f), d["fields"])), - ) - - -class Cheatcodes: - errors: list[Error] - events: list[Event] - enums: list[Enum] - structs: list[Struct] - cheatcodes: list[Cheatcode] - - def __init__( - self, - errors: list[Error], - events: list[Event], - enums: list[Enum], - structs: list[Struct], - cheatcodes: list[Cheatcode], - ): - self.errors = errors - self.events = events - self.enums = enums - self.structs = structs - self.cheatcodes = cheatcodes - - @staticmethod - def from_dict(d: dict) -> "Cheatcodes": - return Cheatcodes( - errors=[Error.from_dict(e) for e in d["errors"]], - events=[Event.from_dict(e) for e in d["events"]], - enums=[Enum.from_dict(e) for e in d["enums"]], - structs=[Struct.from_dict(e) for e in d["structs"]], - cheatcodes=[Cheatcode.from_dict(e) for e in d["cheatcodes"]], - ) - - @staticmethod - def from_json(s) -> "Cheatcodes": - return Cheatcodes.from_dict(json.loads(s)) - - @staticmethod - def from_json_file(file_path: str) -> "Cheatcodes": - with open(file_path, "r") as f: - return Cheatcodes.from_dict(json.load(f)) - - -class Item(PyEnum): - ERROR: str = "error" - EVENT: str = "event" - ENUM: str = "enum" - STRUCT: str = "struct" - FUNCTION: str = "function" - - -class ItemOrder: - _list: list[Item] - - def __init__(self, list: list[Item]) -> None: - assert len(list) <= len(Item), "list must not contain more items than Item" - assert len(list) == len(set(list)), "list must not contain duplicates" - self._list = list - pass - - def get_list(self) -> list[Item]: - return self._list - - @staticmethod - def default() -> "ItemOrder": - return ItemOrder( - [ - Item.ERROR, - Item.EVENT, - Item.ENUM, - Item.STRUCT, - Item.FUNCTION, - ] - ) - - -class CheatcodesPrinter: - buffer: str - - prelude: bool - spdx_identifier: str - solidity_requirement: str - abicoder_v2: bool - - block_doc_style: bool - - indent_level: int - _indent_str: str - - nl_str: str - - items_order: ItemOrder - - def __init__( - self, - buffer: str = "", - prelude: bool = True, - spdx_identifier: str = "UNLICENSED", - solidity_requirement: str = "", - abicoder_pragma: bool = False, - block_doc_style: bool = False, - indent_level: int = 0, - indent_with: int | str = 4, - nl_str: str = "\n", - items_order: ItemOrder = ItemOrder.default(), - ): - self.prelude = prelude - self.spdx_identifier = spdx_identifier - self.solidity_requirement = solidity_requirement - self.abicoder_v2 = abicoder_pragma - self.block_doc_style = block_doc_style - self.buffer = buffer - self.indent_level = indent_level - self.nl_str = nl_str - - if isinstance(indent_with, int): - assert indent_with >= 0 - self._indent_str = " " * indent_with - elif isinstance(indent_with, str): - self._indent_str = indent_with - else: - assert False, "indent_with must be int or str" - - self.items_order = items_order - - def finish(self) -> str: - ret = self.buffer.rstrip() - self.buffer = "" - return ret - - def p_contract(self, contract: Cheatcodes, name: str, inherits: str = ""): - if self.prelude: - self.p_prelude(contract) - - self._p_str("interface ") - name = name.strip() - if name != "": - self._p_str(name) - self._p_str(" ") - if inherits != "": - self._p_str("is ") - self._p_str(inherits) - self._p_str(" ") - self._p_str("{") - self._p_nl() - self._with_indent(lambda: self._p_items(contract)) - self._p_str("}") - self._p_nl() - - def _p_items(self, contract: Cheatcodes): - for item in self.items_order.get_list(): - if item == Item.ERROR: - self.p_errors(contract.errors) - elif item == Item.EVENT: - self.p_events(contract.events) - elif item == Item.ENUM: - self.p_enums(contract.enums) - elif item == Item.STRUCT: - self.p_structs(contract.structs) - elif item == Item.FUNCTION: - self.p_functions(contract.cheatcodes) - else: - assert False, f"unknown item {item}" - - def p_prelude(self, contract: Cheatcodes | None = None): - self._p_str(f"// SPDX-License-Identifier: {self.spdx_identifier}") - self._p_nl() - - if self.solidity_requirement != "": - req = self.solidity_requirement - elif contract and len(contract.errors) > 0: - req = ">=0.8.4 <0.9.0" - else: - req = ">=0.6.0 <0.9.0" - self._p_str(f"pragma solidity {req};") - self._p_nl() - - if self.abicoder_v2: - self._p_str("pragma experimental ABIEncoderV2;") - self._p_nl() - - self._p_nl() - - def p_errors(self, errors: list[Error]): - for error in errors: - self._p_line(lambda: self.p_error(error)) - - def p_error(self, error: Error): - self._p_comment(error.description, doc=True) - self._p_line(lambda: self._p_str(error.declaration)) - - def p_events(self, events: list[Event]): - for event in events: - self._p_line(lambda: self.p_event(event)) - - def p_event(self, event: Event): - self._p_comment(event.description, doc=True) - self._p_line(lambda: self._p_str(event.declaration)) - - def p_enums(self, enums: list[Enum]): - for enum in enums: - self._p_line(lambda: self.p_enum(enum)) - - def p_enum(self, enum: Enum): - self._p_comment(enum.description, doc=True) - self._p_line(lambda: self._p_str(f"enum {enum.name} {{")) - self._with_indent(lambda: self.p_enum_variants(enum.variants)) - self._p_line(lambda: self._p_str("}")) - - def p_enum_variants(self, variants: list[EnumVariant]): - for i, variant in enumerate(variants): - self._p_indent() - self._p_comment(variant.description) - - self._p_indent() - self._p_str(variant.name) - if i < len(variants) - 1: - self._p_str(",") - self._p_nl() - - def p_structs(self, structs: list[Struct]): - for struct in structs: - self._p_line(lambda: self.p_struct(struct)) - - def p_struct(self, struct: Struct): - self._p_comment(struct.description, doc=True) - self._p_line(lambda: self._p_str(f"struct {struct.name} {{")) - self._with_indent(lambda: self.p_struct_fields(struct.fields)) - self._p_line(lambda: self._p_str("}")) - - def p_struct_fields(self, fields: list[StructField]): - for field in fields: - self._p_line(lambda: self.p_struct_field(field)) - - def p_struct_field(self, field: StructField): - self._p_comment(field.description) - self._p_indented(lambda: self._p_str(f"{field.ty} {field.name};")) - - def p_functions(self, cheatcodes: list[Cheatcode]): - for cheatcode in cheatcodes: - self._p_line(lambda: self.p_function(cheatcode.func)) - - def p_function(self, func: Function): - self._p_comment(func.description, doc=True) - self._p_line(lambda: self._p_str(func.declaration)) - - def _p_comment(self, s: str, doc: bool = False): - s = s.strip() - if s == "": - return - - s = map(lambda line: line.lstrip(), s.split("\n")) - if self.block_doc_style: - self._p_str("/*") - if doc: - self._p_str("*") - self._p_nl() - for line in s: - self._p_indent() - self._p_str(" ") - if doc: - self._p_str("* ") - self._p_str(line) - self._p_nl() - self._p_indent() - self._p_str(" */") - self._p_nl() - else: - first_line = True - for line in s: - if not first_line: - self._p_indent() - first_line = False - - if doc: - self._p_str("/// ") - else: - self._p_str("// ") - self._p_str(line) - self._p_nl() - - def _with_indent(self, f: VoidFn): - self._inc_indent() - f() - self._dec_indent() - - def _p_line(self, f: VoidFn): - self._p_indent() - f() - self._p_nl() - - def _p_indented(self, f: VoidFn): - self._p_indent() - f() - - def _p_indent(self): - for _ in range(self.indent_level): - self._p_str(self._indent_str) - - def _p_nl(self): - self._p_str(self.nl_str) - - def _p_str(self, txt: str): - self.buffer += txt - - def _inc_indent(self): - self.indent_level += 1 - - def _dec_indent(self): - self.indent_level -= 1 - - -if __name__ == "__main__": - main() diff --git a/lib/forge-std/src/Base.sol b/lib/forge-std/src/Base.sol deleted file mode 100644 index 851ac0c..0000000 --- a/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/forge-std/src/Script.sol b/lib/forge-std/src/Script.sol deleted file mode 100644 index 94e75f6..0000000 --- a/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 ScriptBase, StdChains, StdCheatsSafe, StdUtils { - // Note: IS_SCRIPT() must return true. - bool public IS_SCRIPT = true; -} diff --git a/lib/forge-std/src/StdAssertions.sol b/lib/forge-std/src/StdAssertions.sol deleted file mode 100644 index 857ecd5..0000000 --- a/lib/forge-std/src/StdAssertions.sol +++ /dev/null @@ -1,669 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; -pragma experimental ABIEncoderV2; - -import {Vm} from "./Vm.sol"; - -abstract contract StdAssertions { - Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - - event log(string); - event logs(bytes); - - event log_address(address); - event log_bytes32(bytes32); - event log_int(int256); - event log_uint(uint256); - 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, int256 val, uint256 decimals); - event log_named_decimal_uint(string key, uint256 val, uint256 decimals); - event log_named_int(string key, int256 val); - event log_named_uint(string key, uint256 val); - event log_named_bytes(string key, bytes val); - event log_named_string(string key, string val); - - 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); - - bool private _failed; - - function failed() public view returns (bool) { - if (_failed) { - return _failed; - } else { - return vm.load(address(vm), bytes32("failed")) != bytes32(0); - } - } - - function fail() internal virtual { - vm.store(address(vm), bytes32("failed"), bytes32(uint256(1))); - _failed = true; - } - - function assertTrue(bool data) internal pure virtual { - vm.assertTrue(data); - } - - function assertTrue(bool data, string memory err) internal pure virtual { - vm.assertTrue(data, err); - } - - function assertFalse(bool data) internal pure virtual { - vm.assertFalse(data); - } - - function assertFalse(bool data, string memory err) internal pure virtual { - vm.assertFalse(data, err); - } - - function assertEq(bool left, bool right) internal pure virtual { - vm.assertEq(left, right); - } - - function assertEq(bool left, bool right, string memory err) internal pure virtual { - vm.assertEq(left, right, err); - } - - function assertEq(uint256 left, uint256 right) internal pure virtual { - vm.assertEq(left, right); - } - - function assertEq(uint256 left, uint256 right, string memory err) internal pure virtual { - vm.assertEq(left, right, err); - } - - function assertEqDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual { - vm.assertEqDecimal(left, right, decimals); - } - - function assertEqDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual { - vm.assertEqDecimal(left, right, decimals, err); - } - - function assertEq(int256 left, int256 right) internal pure virtual { - vm.assertEq(left, right); - } - - function assertEq(int256 left, int256 right, string memory err) internal pure virtual { - vm.assertEq(left, right, err); - } - - function assertEqDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual { - vm.assertEqDecimal(left, right, decimals); - } - - function assertEqDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual { - vm.assertEqDecimal(left, right, decimals, err); - } - - function assertEq(address left, address right) internal pure virtual { - vm.assertEq(left, right); - } - - function assertEq(address left, address right, string memory err) internal pure virtual { - vm.assertEq(left, right, err); - } - - function assertEq(bytes32 left, bytes32 right) internal pure virtual { - vm.assertEq(left, right); - } - - function assertEq(bytes32 left, bytes32 right, string memory err) internal pure virtual { - vm.assertEq(left, right, err); - } - - function assertEq32(bytes32 left, bytes32 right) internal pure virtual { - assertEq(left, right); - } - - function assertEq32(bytes32 left, bytes32 right, string memory err) internal pure virtual { - assertEq(left, right, err); - } - - function assertEq(string memory left, string memory right) internal pure virtual { - vm.assertEq(left, right); - } - - function assertEq(string memory left, string memory right, string memory err) internal pure virtual { - vm.assertEq(left, right, err); - } - - function assertEq(bytes memory left, bytes memory right) internal pure virtual { - vm.assertEq(left, right); - } - - function assertEq(bytes memory left, bytes memory right, string memory err) internal pure virtual { - vm.assertEq(left, right, err); - } - - function assertEq(bool[] memory left, bool[] memory right) internal pure virtual { - vm.assertEq(left, right); - } - - function assertEq(bool[] memory left, bool[] memory right, string memory err) internal pure virtual { - vm.assertEq(left, right, err); - } - - function assertEq(uint256[] memory left, uint256[] memory right) internal pure virtual { - vm.assertEq(left, right); - } - - function assertEq(uint256[] memory left, uint256[] memory right, string memory err) internal pure virtual { - vm.assertEq(left, right, err); - } - - function assertEq(int256[] memory left, int256[] memory right) internal pure virtual { - vm.assertEq(left, right); - } - - function assertEq(int256[] memory left, int256[] memory right, string memory err) internal pure virtual { - vm.assertEq(left, right, err); - } - - function assertEq(address[] memory left, address[] memory right) internal pure virtual { - vm.assertEq(left, right); - } - - function assertEq(address[] memory left, address[] memory right, string memory err) internal pure virtual { - vm.assertEq(left, right, err); - } - - function assertEq(bytes32[] memory left, bytes32[] memory right) internal pure virtual { - vm.assertEq(left, right); - } - - function assertEq(bytes32[] memory left, bytes32[] memory right, string memory err) internal pure virtual { - vm.assertEq(left, right, err); - } - - function assertEq(string[] memory left, string[] memory right) internal pure virtual { - vm.assertEq(left, right); - } - - function assertEq(string[] memory left, string[] memory right, string memory err) internal pure virtual { - vm.assertEq(left, right, err); - } - - function assertEq(bytes[] memory left, bytes[] memory right) internal pure virtual { - vm.assertEq(left, right); - } - - function assertEq(bytes[] memory left, bytes[] memory right, string memory err) internal pure virtual { - vm.assertEq(left, right, err); - } - - // Legacy helper - function assertEqUint(uint256 left, uint256 right) internal pure virtual { - assertEq(left, right); - } - - function assertNotEq(bool left, bool right) internal pure virtual { - vm.assertNotEq(left, right); - } - - function assertNotEq(bool left, bool right, string memory err) internal pure virtual { - vm.assertNotEq(left, right, err); - } - - function assertNotEq(uint256 left, uint256 right) internal pure virtual { - vm.assertNotEq(left, right); - } - - function assertNotEq(uint256 left, uint256 right, string memory err) internal pure virtual { - vm.assertNotEq(left, right, err); - } - - function assertNotEqDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual { - vm.assertNotEqDecimal(left, right, decimals); - } - - function assertNotEqDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) - internal - pure - virtual - { - vm.assertNotEqDecimal(left, right, decimals, err); - } - - function assertNotEq(int256 left, int256 right) internal pure virtual { - vm.assertNotEq(left, right); - } - - function assertNotEq(int256 left, int256 right, string memory err) internal pure virtual { - vm.assertNotEq(left, right, err); - } - - function assertNotEqDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual { - vm.assertNotEqDecimal(left, right, decimals); - } - - function assertNotEqDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual { - vm.assertNotEqDecimal(left, right, decimals, err); - } - - function assertNotEq(address left, address right) internal pure virtual { - vm.assertNotEq(left, right); - } - - function assertNotEq(address left, address right, string memory err) internal pure virtual { - vm.assertNotEq(left, right, err); - } - - function assertNotEq(bytes32 left, bytes32 right) internal pure virtual { - vm.assertNotEq(left, right); - } - - function assertNotEq(bytes32 left, bytes32 right, string memory err) internal pure virtual { - vm.assertNotEq(left, right, err); - } - - function assertNotEq32(bytes32 left, bytes32 right) internal pure virtual { - assertNotEq(left, right); - } - - function assertNotEq32(bytes32 left, bytes32 right, string memory err) internal pure virtual { - assertNotEq(left, right, err); - } - - function assertNotEq(string memory left, string memory right) internal pure virtual { - vm.assertNotEq(left, right); - } - - function assertNotEq(string memory left, string memory right, string memory err) internal pure virtual { - vm.assertNotEq(left, right, err); - } - - function assertNotEq(bytes memory left, bytes memory right) internal pure virtual { - vm.assertNotEq(left, right); - } - - function assertNotEq(bytes memory left, bytes memory right, string memory err) internal pure virtual { - vm.assertNotEq(left, right, err); - } - - function assertNotEq(bool[] memory left, bool[] memory right) internal pure virtual { - vm.assertNotEq(left, right); - } - - function assertNotEq(bool[] memory left, bool[] memory right, string memory err) internal pure virtual { - vm.assertNotEq(left, right, err); - } - - function assertNotEq(uint256[] memory left, uint256[] memory right) internal pure virtual { - vm.assertNotEq(left, right); - } - - function assertNotEq(uint256[] memory left, uint256[] memory right, string memory err) internal pure virtual { - vm.assertNotEq(left, right, err); - } - - function assertNotEq(int256[] memory left, int256[] memory right) internal pure virtual { - vm.assertNotEq(left, right); - } - - function assertNotEq(int256[] memory left, int256[] memory right, string memory err) internal pure virtual { - vm.assertNotEq(left, right, err); - } - - function assertNotEq(address[] memory left, address[] memory right) internal pure virtual { - vm.assertNotEq(left, right); - } - - function assertNotEq(address[] memory left, address[] memory right, string memory err) internal pure virtual { - vm.assertNotEq(left, right, err); - } - - function assertNotEq(bytes32[] memory left, bytes32[] memory right) internal pure virtual { - vm.assertNotEq(left, right); - } - - function assertNotEq(bytes32[] memory left, bytes32[] memory right, string memory err) internal pure virtual { - vm.assertNotEq(left, right, err); - } - - function assertNotEq(string[] memory left, string[] memory right) internal pure virtual { - vm.assertNotEq(left, right); - } - - function assertNotEq(string[] memory left, string[] memory right, string memory err) internal pure virtual { - vm.assertNotEq(left, right, err); - } - - function assertNotEq(bytes[] memory left, bytes[] memory right) internal pure virtual { - vm.assertNotEq(left, right); - } - - function assertNotEq(bytes[] memory left, bytes[] memory right, string memory err) internal pure virtual { - vm.assertNotEq(left, right, err); - } - - function assertLt(uint256 left, uint256 right) internal pure virtual { - vm.assertLt(left, right); - } - - function assertLt(uint256 left, uint256 right, string memory err) internal pure virtual { - vm.assertLt(left, right, err); - } - - function assertLtDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual { - vm.assertLtDecimal(left, right, decimals); - } - - function assertLtDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual { - vm.assertLtDecimal(left, right, decimals, err); - } - - function assertLt(int256 left, int256 right) internal pure virtual { - vm.assertLt(left, right); - } - - function assertLt(int256 left, int256 right, string memory err) internal pure virtual { - vm.assertLt(left, right, err); - } - - function assertLtDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual { - vm.assertLtDecimal(left, right, decimals); - } - - function assertLtDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual { - vm.assertLtDecimal(left, right, decimals, err); - } - - function assertGt(uint256 left, uint256 right) internal pure virtual { - vm.assertGt(left, right); - } - - function assertGt(uint256 left, uint256 right, string memory err) internal pure virtual { - vm.assertGt(left, right, err); - } - - function assertGtDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual { - vm.assertGtDecimal(left, right, decimals); - } - - function assertGtDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual { - vm.assertGtDecimal(left, right, decimals, err); - } - - function assertGt(int256 left, int256 right) internal pure virtual { - vm.assertGt(left, right); - } - - function assertGt(int256 left, int256 right, string memory err) internal pure virtual { - vm.assertGt(left, right, err); - } - - function assertGtDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual { - vm.assertGtDecimal(left, right, decimals); - } - - function assertGtDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual { - vm.assertGtDecimal(left, right, decimals, err); - } - - function assertLe(uint256 left, uint256 right) internal pure virtual { - vm.assertLe(left, right); - } - - function assertLe(uint256 left, uint256 right, string memory err) internal pure virtual { - vm.assertLe(left, right, err); - } - - function assertLeDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual { - vm.assertLeDecimal(left, right, decimals); - } - - function assertLeDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual { - vm.assertLeDecimal(left, right, decimals, err); - } - - function assertLe(int256 left, int256 right) internal pure virtual { - vm.assertLe(left, right); - } - - function assertLe(int256 left, int256 right, string memory err) internal pure virtual { - vm.assertLe(left, right, err); - } - - function assertLeDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual { - vm.assertLeDecimal(left, right, decimals); - } - - function assertLeDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual { - vm.assertLeDecimal(left, right, decimals, err); - } - - function assertGe(uint256 left, uint256 right) internal pure virtual { - vm.assertGe(left, right); - } - - function assertGe(uint256 left, uint256 right, string memory err) internal pure virtual { - vm.assertGe(left, right, err); - } - - function assertGeDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual { - vm.assertGeDecimal(left, right, decimals); - } - - function assertGeDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual { - vm.assertGeDecimal(left, right, decimals, err); - } - - function assertGe(int256 left, int256 right) internal pure virtual { - vm.assertGe(left, right); - } - - function assertGe(int256 left, int256 right, string memory err) internal pure virtual { - vm.assertGe(left, right, err); - } - - function assertGeDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual { - vm.assertGeDecimal(left, right, decimals); - } - - function assertGeDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual { - vm.assertGeDecimal(left, right, decimals, err); - } - - function assertApproxEqAbs(uint256 left, uint256 right, uint256 maxDelta) internal pure virtual { - vm.assertApproxEqAbs(left, right, maxDelta); - } - - function assertApproxEqAbs(uint256 left, uint256 right, uint256 maxDelta, string memory err) - internal - pure - virtual - { - vm.assertApproxEqAbs(left, right, maxDelta, err); - } - - function assertApproxEqAbsDecimal(uint256 left, uint256 right, uint256 maxDelta, uint256 decimals) - internal - pure - virtual - { - vm.assertApproxEqAbsDecimal(left, right, maxDelta, decimals); - } - - function assertApproxEqAbsDecimal( - uint256 left, - uint256 right, - uint256 maxDelta, - uint256 decimals, - string memory err - ) internal pure virtual { - vm.assertApproxEqAbsDecimal(left, right, maxDelta, decimals, err); - } - - function assertApproxEqAbs(int256 left, int256 right, uint256 maxDelta) internal pure virtual { - vm.assertApproxEqAbs(left, right, maxDelta); - } - - function assertApproxEqAbs(int256 left, int256 right, uint256 maxDelta, string memory err) internal pure virtual { - vm.assertApproxEqAbs(left, right, maxDelta, err); - } - - function assertApproxEqAbsDecimal(int256 left, int256 right, uint256 maxDelta, uint256 decimals) - internal - pure - virtual - { - vm.assertApproxEqAbsDecimal(left, right, maxDelta, decimals); - } - - function assertApproxEqAbsDecimal(int256 left, int256 right, uint256 maxDelta, uint256 decimals, string memory err) - internal - pure - virtual - { - vm.assertApproxEqAbsDecimal(left, right, maxDelta, decimals, err); - } - - function assertApproxEqRel( - uint256 left, - uint256 right, - uint256 maxPercentDelta // An 18 decimal fixed point number, where 1e18 == 100% - ) internal pure virtual { - vm.assertApproxEqRel(left, right, maxPercentDelta); - } - - function assertApproxEqRel( - uint256 left, - uint256 right, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - string memory err - ) internal pure virtual { - vm.assertApproxEqRel(left, right, maxPercentDelta, err); - } - - function assertApproxEqRelDecimal( - uint256 left, - uint256 right, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - uint256 decimals - ) internal pure virtual { - vm.assertApproxEqRelDecimal(left, right, maxPercentDelta, decimals); - } - - function assertApproxEqRelDecimal( - uint256 left, - uint256 right, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - uint256 decimals, - string memory err - ) internal pure virtual { - vm.assertApproxEqRelDecimal(left, right, maxPercentDelta, decimals, err); - } - - function assertApproxEqRel(int256 left, int256 right, uint256 maxPercentDelta) internal pure virtual { - vm.assertApproxEqRel(left, right, maxPercentDelta); - } - - function assertApproxEqRel( - int256 left, - int256 right, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - string memory err - ) internal pure virtual { - vm.assertApproxEqRel(left, right, maxPercentDelta, err); - } - - function assertApproxEqRelDecimal( - int256 left, - int256 right, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - uint256 decimals - ) internal pure virtual { - vm.assertApproxEqRelDecimal(left, right, maxPercentDelta, decimals); - } - - function assertApproxEqRelDecimal( - int256 left, - int256 right, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - uint256 decimals, - string memory err - ) internal pure virtual { - vm.assertApproxEqRelDecimal(left, right, maxPercentDelta, decimals, err); - } - - // Inherited from DSTest, not used but kept for backwards-compatibility - function checkEq0(bytes memory left, bytes memory right) internal pure returns (bool) { - return keccak256(left) == keccak256(right); - } - - function assertEq0(bytes memory left, bytes memory right) internal pure virtual { - assertEq(left, right); - } - - function assertEq0(bytes memory left, bytes memory right, string memory err) internal pure virtual { - assertEq(left, right, err); - } - - function assertNotEq0(bytes memory left, bytes memory right) internal pure virtual { - assertNotEq(left, right); - } - - function assertNotEq0(bytes memory left, bytes memory right, string memory err) internal pure virtual { - assertNotEq(left, right, err); - } - - 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); - revert("assertion failed"); - } - - 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); - revert("assertion failed"); - } - } -} diff --git a/lib/forge-std/src/StdChains.sol b/lib/forge-std/src/StdChains.sol deleted file mode 100644 index 0fe827e..0000000 --- a/lib/forge-std/src/StdChains.sol +++ /dev/null @@ -1,259 +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 - view - 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' - // The upstream error thrown by forge for failing cheats changed so we check both the old and new versions - bytes memory oldNotFoundError = - abi.encodeWithSignature("CheatCodeError", string(abi.encodePacked("invalid rpc url ", chainAlias))); - bytes memory newNotFoundError = abi.encodeWithSignature( - "CheatcodeError(string)", string(abi.encodePacked("invalid rpc url: ", chainAlias)) - ); - bytes32 errHash = keccak256(err); - if ( - (errHash != keccak256(oldNotFoundError) && errHash != keccak256(newNotFoundError)) - || 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 `test_Rpcs` in `StdChains.t.sol` - setChainWithDefaultRpcUrl("anvil", ChainData("Anvil", 31337, "http://127.0.0.1:8545")); - setChainWithDefaultRpcUrl( - "mainnet", ChainData("Mainnet", 1, "https://eth-mainnet.alchemyapi.io/v2/pwc5rmJhrdoaSEfimoKEmsvOjKSmPDrP") - ); - setChainWithDefaultRpcUrl( - "sepolia", ChainData("Sepolia", 11155111, "https://sepolia.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001") - ); - setChainWithDefaultRpcUrl("holesky", ChainData("Holesky", 17000, "https://rpc.holesky.ethpandaops.io")); - setChainWithDefaultRpcUrl("optimism", ChainData("Optimism", 10, "https://mainnet.optimism.io")); - setChainWithDefaultRpcUrl( - "optimism_sepolia", ChainData("Optimism Sepolia", 11155420, "https://sepolia.optimism.io") - ); - setChainWithDefaultRpcUrl("arbitrum_one", ChainData("Arbitrum One", 42161, "https://arb1.arbitrum.io/rpc")); - setChainWithDefaultRpcUrl( - "arbitrum_one_sepolia", ChainData("Arbitrum One Sepolia", 421614, "https://sepolia-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_amoy", ChainData("Polygon Amoy", 80002, "https://rpc-amoy.polygon.technology") - ); - 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")); - setChainWithDefaultRpcUrl("moonbeam", ChainData("Moonbeam", 1284, "https://rpc.api.moonbeam.network")); - setChainWithDefaultRpcUrl( - "moonriver", ChainData("Moonriver", 1285, "https://rpc.api.moonriver.moonbeam.network") - ); - setChainWithDefaultRpcUrl("moonbase", ChainData("Moonbase", 1287, "https://rpc.testnet.moonbeam.network")); - setChainWithDefaultRpcUrl("base_sepolia", ChainData("Base Sepolia", 84532, "https://sepolia.base.org")); - setChainWithDefaultRpcUrl("base", ChainData("Base", 8453, "https://mainnet.base.org")); - setChainWithDefaultRpcUrl("blast_sepolia", ChainData("Blast Sepolia", 168587773, "https://sepolia.blast.io")); - setChainWithDefaultRpcUrl("blast", ChainData("Blast", 81457, "https://rpc.blast.io")); - setChainWithDefaultRpcUrl("fantom_opera", ChainData("Fantom Opera", 250, "https://rpc.ankr.com/fantom/")); - setChainWithDefaultRpcUrl( - "fantom_opera_testnet", ChainData("Fantom Opera Testnet", 4002, "https://rpc.ankr.com/fantom_testnet/") - ); - setChainWithDefaultRpcUrl("fraxtal", ChainData("Fraxtal", 252, "https://rpc.frax.com")); - setChainWithDefaultRpcUrl("fraxtal_testnet", ChainData("Fraxtal Testnet", 2522, "https://rpc.testnet.frax.com")); - setChainWithDefaultRpcUrl( - "berachain_bartio_testnet", ChainData("Berachain bArtio Testnet", 80084, "https://bartio.rpc.berachain.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/forge-std/src/StdCheats.sol b/lib/forge-std/src/StdCheats.sol deleted file mode 100644 index f293313..0000000 --- a/lib/forge-std/src/StdCheats.sol +++ /dev/null @@ -1,817 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import {StdStorage, stdStorage} from "./StdStorage.sol"; -import {console2} from "./console2.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, console, and Create2Deployer addresses - vm.assume( - addr != address(vm) && addr != 0x000000000000000000636F6e736F6c652e6c6f67 - && addr != 0x4e59b44847b379578588920cA78FbF26c0B4956C - ); - } - - 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"))))); - address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67; - - // 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 { - console2_log_StdCheats("changePrank is deprecated. Please use vm.startPrank instead."); - 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); - } - - // Used to prevent the compilation of console, which shortens the compilation time when console is not used elsewhere. - function console2_log_StdCheats(string memory p0) private view { - (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature("log(string)", p0)); - status; - } -} diff --git a/lib/forge-std/src/StdError.sol b/lib/forge-std/src/StdError.sol deleted file mode 100644 index a302191..0000000 --- a/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/forge-std/src/StdInvariant.sol b/lib/forge-std/src/StdInvariant.sol deleted file mode 100644 index 056db98..0000000 --- a/lib/forge-std/src/StdInvariant.sol +++ /dev/null @@ -1,122 +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; - } - - struct FuzzArtifactSelector { - string artifact; - bytes4[] selectors; - } - - struct FuzzInterface { - address addr; - string[] artifacts; - } - - address[] private _excludedContracts; - address[] private _excludedSenders; - address[] private _targetedContracts; - address[] private _targetedSenders; - - string[] private _excludedArtifacts; - string[] private _targetedArtifacts; - - FuzzArtifactSelector[] private _targetedArtifactSelectors; - - FuzzSelector[] private _excludedSelectors; - FuzzSelector[] private _targetedSelectors; - - FuzzInterface[] private _targetedInterfaces; - - // Functions for users: - // These are intended to be called in tests. - - function excludeContract(address newExcludedContract_) internal { - _excludedContracts.push(newExcludedContract_); - } - - function excludeSelector(FuzzSelector memory newExcludedSelector_) internal { - _excludedSelectors.push(newExcludedSelector_); - } - - 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(FuzzArtifactSelector 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_); - } - - function targetInterface(FuzzInterface memory newTargetedInterface_) internal { - _targetedInterfaces.push(newTargetedInterface_); - } - - // 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 excludeSelectors() public view returns (FuzzSelector[] memory excludedSelectors_) { - excludedSelectors_ = _excludedSelectors; - } - - 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 (FuzzArtifactSelector[] 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; - } - - function targetInterfaces() public view returns (FuzzInterface[] memory targetedInterfaces_) { - targetedInterfaces_ = _targetedInterfaces; - } -} diff --git a/lib/forge-std/src/StdJson.sol b/lib/forge-std/src/StdJson.sol deleted file mode 100644 index 6dbde83..0000000 --- a/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(""); -// json.readUint(""); -// ``` -// To write: -// ``` -// using stdJson for string; -// string memory json = "json"; -// json.serialize("a", uint256(123)); -// string memory semiFinal = json.serialize("b", string("test")); -// string memory finalJson = json.serialize("c", semiFinal); -// finalJson.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 pure returns (uint256) { - return vm.parseJsonUint(json, key); - } - - function readUintArray(string memory json, string memory key) internal pure returns (uint256[] memory) { - return vm.parseJsonUintArray(json, key); - } - - function readInt(string memory json, string memory key) internal pure returns (int256) { - return vm.parseJsonInt(json, key); - } - - function readIntArray(string memory json, string memory key) internal pure returns (int256[] memory) { - return vm.parseJsonIntArray(json, key); - } - - function readBytes32(string memory json, string memory key) internal pure returns (bytes32) { - return vm.parseJsonBytes32(json, key); - } - - function readBytes32Array(string memory json, string memory key) internal pure returns (bytes32[] memory) { - return vm.parseJsonBytes32Array(json, key); - } - - function readString(string memory json, string memory key) internal pure returns (string memory) { - return vm.parseJsonString(json, key); - } - - function readStringArray(string memory json, string memory key) internal pure returns (string[] memory) { - return vm.parseJsonStringArray(json, key); - } - - function readAddress(string memory json, string memory key) internal pure returns (address) { - return vm.parseJsonAddress(json, key); - } - - function readAddressArray(string memory json, string memory key) internal pure returns (address[] memory) { - return vm.parseJsonAddressArray(json, key); - } - - function readBool(string memory json, string memory key) internal pure returns (bool) { - return vm.parseJsonBool(json, key); - } - - function readBoolArray(string memory json, string memory key) internal pure returns (bool[] memory) { - return vm.parseJsonBoolArray(json, key); - } - - function readBytes(string memory json, string memory key) internal pure returns (bytes memory) { - return vm.parseJsonBytes(json, key); - } - - function readBytesArray(string memory json, string memory key) internal pure returns (bytes[] memory) { - return vm.parseJsonBytesArray(json, key); - } - - function serialize(string memory jsonKey, string memory rootObject) internal returns (string memory) { - return vm.serializeJson(jsonKey, rootObject); - } - - 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/forge-std/src/StdMath.sol b/lib/forge-std/src/StdMath.sol deleted file mode 100644 index 459523b..0000000 --- a/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/forge-std/src/StdStorage.sol b/lib/forge-std/src/StdStorage.sol deleted file mode 100644 index ffd668c..0000000 --- a/lib/forge-std/src/StdStorage.sol +++ /dev/null @@ -1,473 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -import {Vm} from "./Vm.sol"; - -struct FindData { - uint256 slot; - uint256 offsetLeft; - uint256 offsetRight; - bool found; -} - -struct StdStorage { - mapping(address => mapping(bytes4 => mapping(bytes32 => FindData))) finds; - bytes32[] _keys; - bytes4 _sig; - uint256 _depth; - address _target; - bytes32 _set; - bool _enable_packed_slots; - bytes _calldata; -} - -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"))))); - uint256 constant UINT256_MAX = 115792089237316195423570985008687907853269984665640564039457584007913129639935; - - function sigs(string memory sigStr) internal pure returns (bytes4) { - return bytes4(keccak256(bytes(sigStr))); - } - - function getCallParams(StdStorage storage self) internal view returns (bytes memory) { - if (self._calldata.length == 0) { - return flatten(self._keys); - } else { - return self._calldata; - } - } - - // Calls target contract with configured parameters - function callTarget(StdStorage storage self) internal view returns (bool, bytes32) { - bytes memory cald = abi.encodePacked(self._sig, getCallParams(self)); - (bool success, bytes memory rdat) = self._target.staticcall(cald); - bytes32 result = bytesToBytes32(rdat, 32 * self._depth); - - return (success, result); - } - - // Tries mutating slot value to determine if the targeted value is stored in it. - // If current value is 0, then we are setting slot value to type(uint256).max - // Otherwise, we set it to 0. That way, return value should always be affected. - function checkSlotMutatesCall(StdStorage storage self, bytes32 slot) internal returns (bool) { - bytes32 prevSlotValue = vm.load(self._target, slot); - (bool success, bytes32 prevReturnValue) = callTarget(self); - - bytes32 testVal = prevReturnValue == bytes32(0) ? bytes32(UINT256_MAX) : bytes32(0); - vm.store(self._target, slot, testVal); - - (, bytes32 newReturnValue) = callTarget(self); - - vm.store(self._target, slot, prevSlotValue); - - return (success && (prevReturnValue != newReturnValue)); - } - - // Tries setting one of the bits in slot to 1 until return value changes. - // Index of resulted bit is an offset packed slot has from left/right side - function findOffset(StdStorage storage self, bytes32 slot, bool left) internal returns (bool, uint256) { - for (uint256 offset = 0; offset < 256; offset++) { - uint256 valueToPut = left ? (1 << (255 - offset)) : (1 << offset); - vm.store(self._target, slot, bytes32(valueToPut)); - - (bool success, bytes32 data) = callTarget(self); - - if (success && (uint256(data) > 0)) { - return (true, offset); - } - } - return (false, 0); - } - - function findOffsets(StdStorage storage self, bytes32 slot) internal returns (bool, uint256, uint256) { - bytes32 prevSlotValue = vm.load(self._target, slot); - - (bool foundLeft, uint256 offsetLeft) = findOffset(self, slot, true); - (bool foundRight, uint256 offsetRight) = findOffset(self, slot, false); - - // `findOffset` may mutate slot value, so we are setting it to initial value - vm.store(self._target, slot, prevSlotValue); - return (foundLeft && foundRight, offsetLeft, offsetRight); - } - - function find(StdStorage storage self) internal returns (FindData storage) { - return find(self, true); - } - - /// @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, bool _clear) internal returns (FindData storage) { - address who = self._target; - bytes4 fsig = self._sig; - uint256 field_depth = self._depth; - bytes memory params = getCallParams(self); - - // calldata to test against - if (self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))].found) { - if (_clear) { - clear(self); - } - return self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))]; - } - vm.record(); - (, bytes32 callResult) = callTarget(self); - (bytes32[] memory reads,) = vm.accesses(address(who)); - - if (reads.length == 0) { - revert("stdStorage find(StdStorage): No storage use detected for target."); - } else { - 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])); - } - - if (!checkSlotMutatesCall(self, reads[i])) { - continue; - } - - (uint256 offsetLeft, uint256 offsetRight) = (0, 0); - - if (self._enable_packed_slots) { - bool found; - (found, offsetLeft, offsetRight) = findOffsets(self, reads[i]); - if (!found) { - continue; - } - } - - // Check that value between found offsets is equal to the current call result - uint256 curVal = (uint256(prev) & getMaskByOffsets(offsetLeft, offsetRight)) >> offsetRight; - - if (uint256(callResult) != curVal) { - continue; - } - - emit SlotFound(who, fsig, keccak256(abi.encodePacked(params, field_depth)), uint256(reads[i])); - self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))] = - FindData(uint256(reads[i]), offsetLeft, offsetRight, true); - break; - } - } - - require( - self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))].found, - "stdStorage find(StdStorage): Slot(s) not found." - ); - - if (_clear) { - clear(self); - } - return self.finds[who][fsig][keccak256(abi.encodePacked(params, 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_calldata(StdStorage storage self, bytes memory _calldata) internal returns (StdStorage storage) { - self._calldata = _calldata; - 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 enable_packed_slots(StdStorage storage self) internal returns (StdStorage storage) { - self._enable_packed_slots = true; - 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) { - FindData storage data = find(self, false); - uint256 mask = getMaskByOffsets(data.offsetLeft, data.offsetRight); - uint256 value = (uint256(vm.load(self._target, bytes32(data.slot))) & mask) >> data.offsetRight; - clear(self); - return abi.encode(value); - } - - 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 parent(StdStorage storage self) internal returns (uint256, bytes32) { - address who = self._target; - uint256 field_depth = self._depth; - vm.startMappingRecording(); - uint256 child = find(self, true).slot - field_depth; - (bool found, bytes32 key, bytes32 parent_slot) = vm.getMappingKeyAndParentOf(who, bytes32(child)); - if (!found) { - revert( - "stdStorage read_bool(StdStorage): Cannot find parent. Make sure you give a slot and startMappingRecording() has been called." - ); - } - return (uint256(parent_slot), key); - } - - function root(StdStorage storage self) internal returns (uint256) { - address who = self._target; - uint256 field_depth = self._depth; - vm.startMappingRecording(); - uint256 child = find(self, true).slot - field_depth; - bool found; - bytes32 root_slot; - bytes32 parent_slot; - (found,, parent_slot) = vm.getMappingKeyAndParentOf(who, bytes32(child)); - if (!found) { - revert( - "stdStorage read_bool(StdStorage): Cannot find parent. Make sure you give a slot and startMappingRecording() has been called." - ); - } - while (found) { - root_slot = parent_slot; - (found,, parent_slot) = vm.getMappingKeyAndParentOf(who, bytes32(root_slot)); - } - return uint256(root_slot); - } - - 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; - } - - function clear(StdStorage storage self) internal { - delete self._target; - delete self._sig; - delete self._keys; - delete self._depth; - delete self._enable_packed_slots; - delete self._calldata; - } - - // Returns mask which contains non-zero bits for values between `offsetLeft` and `offsetRight` - // (slotValue & mask) >> offsetRight will be the value of the given packed variable - function getMaskByOffsets(uint256 offsetLeft, uint256 offsetRight) internal pure returns (uint256 mask) { - // mask = ((1 << (256 - (offsetRight + offsetLeft))) - 1) << offsetRight; - // using assembly because (1 << 256) causes overflow - assembly { - mask := shl(offsetRight, sub(shl(sub(256, add(offsetRight, offsetLeft)), 1), 1)) - } - } - - // Returns slot value with updated packed variable. - function getUpdatedSlotValue(bytes32 curValue, uint256 varValue, uint256 offsetLeft, uint256 offsetRight) - internal - pure - returns (bytes32 newValue) - { - return bytes32((uint256(curValue) & ~getMaskByOffsets(offsetLeft, offsetRight)) | (varValue << offsetRight)); - } -} - -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 find(self, true); - } - - function find(StdStorage storage self, bool _clear) internal returns (uint256) { - return stdStorageSafe.find(self, _clear).slot; - } - - 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 with_calldata(StdStorage storage self, bytes memory _calldata) internal returns (StdStorage storage) { - return stdStorageSafe.with_calldata(self, _calldata); - } - - function enable_packed_slots(StdStorage storage self) internal returns (StdStorage storage) { - return stdStorageSafe.enable_packed_slots(self); - } - - function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) { - return stdStorageSafe.depth(self, _depth); - } - - function clear(StdStorage storage self) internal { - stdStorageSafe.clear(self); - } - - 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; - bytes memory params = stdStorageSafe.getCallParams(self); - - if (!self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))].found) { - find(self, false); - } - FindData storage data = self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))]; - if ((data.offsetLeft + data.offsetRight) > 0) { - uint256 maxVal = 2 ** (256 - (data.offsetLeft + data.offsetRight)); - require( - uint256(set) < maxVal, - string( - abi.encodePacked( - "stdStorage find(StdStorage): Packed slot. We can't fit value greater than ", - vm.toString(maxVal) - ) - ) - ); - } - bytes32 curVal = vm.load(who, bytes32(data.slot)); - bytes32 valToSet = stdStorageSafe.getUpdatedSlotValue(curVal, uint256(set), data.offsetLeft, data.offsetRight); - - vm.store(who, bytes32(data.slot), valToSet); - - (bool success, bytes32 callResult) = stdStorageSafe.callTarget(self); - - if (!success || callResult != set) { - vm.store(who, bytes32(data.slot), curVal); - revert("stdStorage find(StdStorage): Failed to write value."); - } - clear(self); - } - - 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); - } - - function parent(StdStorage storage self) internal returns (uint256, bytes32) { - return stdStorageSafe.parent(self); - } - - function root(StdStorage storage self) internal returns (uint256) { - return stdStorageSafe.root(self); - } -} diff --git a/lib/forge-std/src/StdStyle.sol b/lib/forge-std/src/StdStyle.sol deleted file mode 100644 index d371e0c..0000000 --- a/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/forge-std/src/StdToml.sol b/lib/forge-std/src/StdToml.sol deleted file mode 100644 index ef88db6..0000000 --- a/lib/forge-std/src/StdToml.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 TOML files -// To parse: -// ``` -// using stdToml for string; -// string memory toml = vm.readFile(""); -// toml.readUint(""); -// ``` -// To write: -// ``` -// using stdToml for string; -// string memory json = "json"; -// json.serialize("a", uint256(123)); -// string memory semiFinal = json.serialize("b", string("test")); -// string memory finalJson = json.serialize("c", semiFinal); -// finalJson.write(""); -// ``` - -library stdToml { - VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); - - function parseRaw(string memory toml, string memory key) internal pure returns (bytes memory) { - return vm.parseToml(toml, key); - } - - function readUint(string memory toml, string memory key) internal pure returns (uint256) { - return vm.parseTomlUint(toml, key); - } - - function readUintArray(string memory toml, string memory key) internal pure returns (uint256[] memory) { - return vm.parseTomlUintArray(toml, key); - } - - function readInt(string memory toml, string memory key) internal pure returns (int256) { - return vm.parseTomlInt(toml, key); - } - - function readIntArray(string memory toml, string memory key) internal pure returns (int256[] memory) { - return vm.parseTomlIntArray(toml, key); - } - - function readBytes32(string memory toml, string memory key) internal pure returns (bytes32) { - return vm.parseTomlBytes32(toml, key); - } - - function readBytes32Array(string memory toml, string memory key) internal pure returns (bytes32[] memory) { - return vm.parseTomlBytes32Array(toml, key); - } - - function readString(string memory toml, string memory key) internal pure returns (string memory) { - return vm.parseTomlString(toml, key); - } - - function readStringArray(string memory toml, string memory key) internal pure returns (string[] memory) { - return vm.parseTomlStringArray(toml, key); - } - - function readAddress(string memory toml, string memory key) internal pure returns (address) { - return vm.parseTomlAddress(toml, key); - } - - function readAddressArray(string memory toml, string memory key) internal pure returns (address[] memory) { - return vm.parseTomlAddressArray(toml, key); - } - - function readBool(string memory toml, string memory key) internal pure returns (bool) { - return vm.parseTomlBool(toml, key); - } - - function readBoolArray(string memory toml, string memory key) internal pure returns (bool[] memory) { - return vm.parseTomlBoolArray(toml, key); - } - - function readBytes(string memory toml, string memory key) internal pure returns (bytes memory) { - return vm.parseTomlBytes(toml, key); - } - - function readBytesArray(string memory toml, string memory key) internal pure returns (bytes[] memory) { - return vm.parseTomlBytesArray(toml, key); - } - - function serialize(string memory jsonKey, string memory rootObject) internal returns (string memory) { - return vm.serializeJson(jsonKey, rootObject); - } - - 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.writeToml(jsonKey, path); - } - - function write(string memory jsonKey, string memory path, string memory valueKey) internal { - vm.writeToml(jsonKey, path, valueKey); - } -} diff --git a/lib/forge-std/src/StdUtils.sol b/lib/forge-std/src/StdUtils.sol deleted file mode 100644 index 5d12043..0000000 --- a/lib/forge-std/src/StdUtils.sol +++ /dev/null @@ -1,226 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import {IMulticall3} from "./interfaces/IMulticall3.sol"; -import {MockERC20} from "./mocks/MockERC20.sol"; -import {MockERC721} from "./mocks/MockERC721.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 pure virtual returns (uint256 result) { - result = _bound(x, min, max); - console2_log_StdUtils("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 pure virtual returns (int256 result) { - result = _bound(x, min, max); - console2_log_StdUtils("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) { - console2_log_StdUtils("computeCreateAddress is deprecated. Please use vm.computeCreateAddress instead."); - return vm.computeCreateAddress(deployer, nonce); - } - - function computeCreate2Address(bytes32 salt, bytes32 initcodeHash, address deployer) - internal - pure - virtual - returns (address) - { - console2_log_StdUtils("computeCreate2Address is deprecated. Please use vm.computeCreate2Address instead."); - return vm.computeCreate2Address(salt, initcodeHash, deployer); - } - - /// @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) { - console2_log_StdUtils("computeCreate2Address is deprecated. Please use vm.computeCreate2Address instead."); - return vm.computeCreate2Address(salt, initCodeHash); - } - - /// @dev returns an initialized mock ERC20 contract - function deployMockERC20(string memory name, string memory symbol, uint8 decimals) - internal - returns (MockERC20 mock) - { - mock = new MockERC20(); - mock.initialize(name, symbol, decimals); - } - - /// @dev returns an initialized mock ERC721 contract - function deployMockERC721(string memory name, string memory symbol) internal returns (MockERC721 mock) { - mock = new MockERC721(); - mock.initialize(name, symbol); - } - - /// @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))); - } - - // This section is used to prevent the compilation of console, which shortens the compilation time when console is - // not used elsewhere. We also trick the compiler into letting us make the console log methods as `pure` to avoid - // any breaking changes to function signatures. - 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 = CONSOLE2_ADDRESS; - /// @solidity memory-safe-assembly - assembly { - let payloadStart := add(payload, 32) - let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) - } - } - - function console2_log_StdUtils(string memory p0) private pure { - _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); - } - - function console2_log_StdUtils(string memory p0, uint256 p1) private pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1)); - } - - function console2_log_StdUtils(string memory p0, string memory p1) private pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); - } -} diff --git a/lib/forge-std/src/Test.sol b/lib/forge-std/src/Test.sol deleted file mode 100644 index 5ff60ea..0000000 --- a/lib/forge-std/src/Test.sol +++ /dev/null @@ -1,33 +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 {stdToml} from "./StdToml.sol"; -import {StdUtils} from "./StdUtils.sol"; -import {Vm} from "./Vm.sol"; - -// 📦 BOILERPLATE -import {TestBase} from "./Base.sol"; - -// ⭐️ TEST -abstract contract Test is TestBase, StdAssertions, StdChains, StdCheats, StdInvariant, StdUtils { - // Note: IS_TEST() must return true. - bool public IS_TEST = true; -} diff --git a/lib/forge-std/src/Vm.sol b/lib/forge-std/src/Vm.sol deleted file mode 100644 index e13a386..0000000 --- a/lib/forge-std/src/Vm.sol +++ /dev/null @@ -1,1763 +0,0 @@ -// Automatically @generated by scripts/vm.py. Do not modify manually. - -// SPDX-License-Identifier: MIT OR Apache-2.0 -pragma solidity >=0.6.2 <0.9.0; -pragma experimental ABIEncoderV2; - -/// The `VmSafe` interface does not allow manipulation of the EVM state or other actions that may -/// result in Script simulations differing from on-chain execution. It is recommended to only use -/// these cheats in scripts. -interface VmSafe { - /// A modification applied to either `msg.sender` or `tx.origin`. Returned by `readCallers`. - enum CallerMode { - // No caller modification is currently active. - None, - // A one time broadcast triggered by a `vm.broadcast()` call is currently active. - Broadcast, - // A recurrent broadcast triggered by a `vm.startBroadcast()` call is currently active. - RecurrentBroadcast, - // A one time prank triggered by a `vm.prank()` call is currently active. - Prank, - // A recurrent prank triggered by a `vm.startPrank()` call is currently active. - RecurrentPrank - } - - /// The kind of account access that occurred. - enum AccountAccessKind { - // The account was called. - Call, - // The account was called via delegatecall. - DelegateCall, - // The account was called via callcode. - CallCode, - // The account was called via staticcall. - StaticCall, - // The account was created. - Create, - // The account was selfdestructed. - SelfDestruct, - // Synthetic access indicating the current context has resumed after a previous sub-context (AccountAccess). - Resume, - // The account's balance was read. - Balance, - // The account's codesize was read. - Extcodesize, - // The account's codehash was read. - Extcodehash, - // The account's code was copied. - Extcodecopy - } - - /// Forge execution contexts. - enum ForgeContext { - // Test group execution context (test, coverage or snapshot). - TestGroup, - // `forge test` execution context. - Test, - // `forge coverage` execution context. - Coverage, - // `forge snapshot` execution context. - Snapshot, - // Script group execution context (dry run, broadcast or resume). - ScriptGroup, - // `forge script` execution context. - ScriptDryRun, - // `forge script --broadcast` execution context. - ScriptBroadcast, - // `forge script --resume` execution context. - ScriptResume, - // Unknown `forge` execution context. - Unknown - } - - /// An Ethereum log. Returned by `getRecordedLogs`. - struct Log { - // The topics of the log, including the signature, if any. - bytes32[] topics; - // The raw data of the log. - bytes data; - // The address of the log's emitter. - address emitter; - } - - /// An RPC URL and its alias. Returned by `rpcUrlStructs`. - struct Rpc { - // The alias of the RPC URL. - string key; - // The RPC URL. - string url; - } - - /// An RPC log object. Returned by `eth_getLogs`. - struct EthGetLogs { - // The address of the log's emitter. - address emitter; - // The topics of the log, including the signature, if any. - bytes32[] topics; - // The raw data of the log. - bytes data; - // The block hash. - bytes32 blockHash; - // The block number. - uint64 blockNumber; - // The transaction hash. - bytes32 transactionHash; - // The transaction index in the block. - uint64 transactionIndex; - // The log index. - uint256 logIndex; - // Whether the log was removed. - bool removed; - } - - /// A single entry in a directory listing. Returned by `readDir`. - struct DirEntry { - // The error message, if any. - string errorMessage; - // The path of the entry. - string path; - // The depth of the entry. - uint64 depth; - // Whether the entry is a directory. - bool isDir; - // Whether the entry is a symlink. - bool isSymlink; - } - - /// Metadata information about a file. - /// This structure is returned from the `fsMetadata` function and represents known - /// metadata about a file such as its permissions, size, modification - /// times, etc. - struct FsMetadata { - // True if this metadata is for a directory. - bool isDir; - // True if this metadata is for a symlink. - bool isSymlink; - // The size of the file, in bytes, this metadata is for. - uint256 length; - // True if this metadata is for a readonly (unwritable) file. - bool readOnly; - // The last modification time listed in this metadata. - uint256 modified; - // The last access time of this metadata. - uint256 accessed; - // The creation time listed in this metadata. - uint256 created; - } - - /// A wallet with a public and private key. - struct Wallet { - // The wallet's address. - address addr; - // The wallet's public key `X`. - uint256 publicKeyX; - // The wallet's public key `Y`. - uint256 publicKeyY; - // The wallet's private key. - uint256 privateKey; - } - - /// The result of a `tryFfi` call. - struct FfiResult { - // The exit code of the call. - int32 exitCode; - // The optionally hex-decoded `stdout` data. - bytes stdout; - // The `stderr` data. - bytes stderr; - } - - /// Information on the chain and fork. - struct ChainInfo { - // The fork identifier. Set to zero if no fork is active. - uint256 forkId; - // The chain ID of the current fork. - uint256 chainId; - } - - /// The result of a `stopAndReturnStateDiff` call. - struct AccountAccess { - // The chain and fork the access occurred. - ChainInfo chainInfo; - // The kind of account access that determines what the account is. - // If kind is Call, DelegateCall, StaticCall or CallCode, then the account is the callee. - // If kind is Create, then the account is the newly created account. - // If kind is SelfDestruct, then the account is the selfdestruct recipient. - // If kind is a Resume, then account represents a account context that has resumed. - AccountAccessKind kind; - // The account that was accessed. - // It's either the account created, callee or a selfdestruct recipient for CREATE, CALL or SELFDESTRUCT. - address account; - // What accessed the account. - address accessor; - // If the account was initialized or empty prior to the access. - // An account is considered initialized if it has code, a - // non-zero nonce, or a non-zero balance. - bool initialized; - // The previous balance of the accessed account. - uint256 oldBalance; - // The potential new balance of the accessed account. - // That is, all balance changes are recorded here, even if reverts occurred. - uint256 newBalance; - // Code of the account deployed by CREATE. - bytes deployedCode; - // Value passed along with the account access - uint256 value; - // Input data provided to the CREATE or CALL - bytes data; - // If this access reverted in either the current or parent context. - bool reverted; - // An ordered list of storage accesses made during an account access operation. - StorageAccess[] storageAccesses; - // Call depth traversed during the recording of state differences - uint64 depth; - } - - /// The storage accessed during an `AccountAccess`. - struct StorageAccess { - // The account whose storage was accessed. - address account; - // The slot that was accessed. - bytes32 slot; - // If the access was a write. - bool isWrite; - // The previous value of the slot. - bytes32 previousValue; - // The new value of the slot. - bytes32 newValue; - // If the access was reverted. - bool reverted; - } - - /// Gas used. Returned by `lastCallGas`. - struct Gas { - // The gas limit of the call. - uint64 gasLimit; - // The total gas used. - uint64 gasTotalUsed; - // DEPRECATED: The amount of gas used for memory expansion. Ref: - uint64 gasMemoryUsed; - // The amount of gas refunded. - int64 gasRefunded; - // The amount of gas remaining. - uint64 gasRemaining; - } - - // ======== Environment ======== - - /// Gets the environment variable `name` and parses it as `address`. - /// Reverts if the variable was not found or could not be parsed. - function envAddress(string calldata name) external view returns (address value); - - /// Gets the environment variable `name` and parses it as an array of `address`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envAddress(string calldata name, string calldata delim) external view returns (address[] memory value); - - /// Gets the environment variable `name` and parses it as `bool`. - /// Reverts if the variable was not found or could not be parsed. - function envBool(string calldata name) external view returns (bool value); - - /// Gets the environment variable `name` and parses it as an array of `bool`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envBool(string calldata name, string calldata delim) external view returns (bool[] memory value); - - /// Gets the environment variable `name` and parses it as `bytes32`. - /// Reverts if the variable was not found or could not be parsed. - function envBytes32(string calldata name) external view returns (bytes32 value); - - /// Gets the environment variable `name` and parses it as an array of `bytes32`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envBytes32(string calldata name, string calldata delim) external view returns (bytes32[] memory value); - - /// Gets the environment variable `name` and parses it as `bytes`. - /// Reverts if the variable was not found or could not be parsed. - function envBytes(string calldata name) external view returns (bytes memory value); - - /// Gets the environment variable `name` and parses it as an array of `bytes`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envBytes(string calldata name, string calldata delim) external view returns (bytes[] memory value); - - /// Gets the environment variable `name` and returns true if it exists, else returns false. - function envExists(string calldata name) external view returns (bool result); - - /// Gets the environment variable `name` and parses it as `int256`. - /// Reverts if the variable was not found or could not be parsed. - function envInt(string calldata name) external view returns (int256 value); - - /// Gets the environment variable `name` and parses it as an array of `int256`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envInt(string calldata name, string calldata delim) external view returns (int256[] memory value); - - /// Gets the environment variable `name` and parses it as `bool`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, bool defaultValue) external view returns (bool value); - - /// Gets the environment variable `name` and parses it as `uint256`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, uint256 defaultValue) external view returns (uint256 value); - - /// Gets the environment variable `name` and parses it as an array of `address`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, address[] calldata defaultValue) - external - view - returns (address[] memory value); - - /// Gets the environment variable `name` and parses it as an array of `bytes32`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, bytes32[] calldata defaultValue) - external - view - returns (bytes32[] memory value); - - /// Gets the environment variable `name` and parses it as an array of `string`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, string[] calldata defaultValue) - external - view - returns (string[] memory value); - - /// Gets the environment variable `name` and parses it as an array of `bytes`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, bytes[] calldata defaultValue) - external - view - returns (bytes[] memory value); - - /// Gets the environment variable `name` and parses it as `int256`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, int256 defaultValue) external view returns (int256 value); - - /// Gets the environment variable `name` and parses it as `address`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, address defaultValue) external view returns (address value); - - /// Gets the environment variable `name` and parses it as `bytes32`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, bytes32 defaultValue) external view returns (bytes32 value); - - /// Gets the environment variable `name` and parses it as `string`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata defaultValue) external view returns (string memory value); - - /// Gets the environment variable `name` and parses it as `bytes`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, bytes calldata defaultValue) external view returns (bytes memory value); - - /// Gets the environment variable `name` and parses it as an array of `bool`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, bool[] calldata defaultValue) - external - view - returns (bool[] memory value); - - /// Gets the environment variable `name` and parses it as an array of `uint256`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, uint256[] calldata defaultValue) - external - view - returns (uint256[] memory value); - - /// Gets the environment variable `name` and parses it as an array of `int256`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, int256[] calldata defaultValue) - external - view - returns (int256[] memory value); - - /// Gets the environment variable `name` and parses it as `string`. - /// Reverts if the variable was not found or could not be parsed. - function envString(string calldata name) external view returns (string memory value); - - /// Gets the environment variable `name` and parses it as an array of `string`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envString(string calldata name, string calldata delim) external view returns (string[] memory value); - - /// Gets the environment variable `name` and parses it as `uint256`. - /// Reverts if the variable was not found or could not be parsed. - function envUint(string calldata name) external view returns (uint256 value); - - /// Gets the environment variable `name` and parses it as an array of `uint256`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envUint(string calldata name, string calldata delim) external view returns (uint256[] memory value); - - /// Returns true if `forge` command was executed in given context. - function isContext(ForgeContext context) external view returns (bool result); - - /// Sets environment variables. - function setEnv(string calldata name, string calldata value) external; - - // ======== EVM ======== - - /// Gets all accessed reads and write slot from a `vm.record` session, for a given address. - function accesses(address target) external returns (bytes32[] memory readSlots, bytes32[] memory writeSlots); - - /// Gets the address for a given private key. - function addr(uint256 privateKey) external pure returns (address keyAddr); - - /// Gets all the logs according to specified filter. - function eth_getLogs(uint256 fromBlock, uint256 toBlock, address target, bytes32[] calldata topics) - external - returns (EthGetLogs[] memory logs); - - /// Gets the current `block.blobbasefee`. - /// You should use this instead of `block.blobbasefee` if you use `vm.blobBaseFee`, as `block.blobbasefee` is assumed to be constant across a transaction, - /// and as a result will get optimized out by the compiler. - /// See https://github.com/foundry-rs/foundry/issues/6180 - function getBlobBaseFee() external view returns (uint256 blobBaseFee); - - /// Gets the current `block.number`. - /// You should use this instead of `block.number` if you use `vm.roll`, as `block.number` is assumed to be constant across a transaction, - /// and as a result will get optimized out by the compiler. - /// See https://github.com/foundry-rs/foundry/issues/6180 - function getBlockNumber() external view returns (uint256 height); - - /// Gets the current `block.timestamp`. - /// You should use this instead of `block.timestamp` if you use `vm.warp`, as `block.timestamp` is assumed to be constant across a transaction, - /// and as a result will get optimized out by the compiler. - /// See https://github.com/foundry-rs/foundry/issues/6180 - function getBlockTimestamp() external view returns (uint256 timestamp); - - /// Gets the map key and parent of a mapping at a given slot, for a given address. - function getMappingKeyAndParentOf(address target, bytes32 elementSlot) - external - returns (bool found, bytes32 key, bytes32 parent); - - /// Gets the number of elements in the mapping at the given slot, for a given address. - function getMappingLength(address target, bytes32 mappingSlot) external returns (uint256 length); - - /// Gets the elements at index idx of the mapping at the given slot, for a given address. The - /// index must be less than the length of the mapping (i.e. the number of keys in the mapping). - function getMappingSlotAt(address target, bytes32 mappingSlot, uint256 idx) external returns (bytes32 value); - - /// Gets the nonce of an account. - function getNonce(address account) external view returns (uint64 nonce); - - /// Gets all the recorded logs. - function getRecordedLogs() external returns (Log[] memory logs); - - /// Gets the gas used in the last call. - function lastCallGas() external view returns (Gas memory gas); - - /// Loads a storage slot from an address. - function load(address target, bytes32 slot) external view returns (bytes32 data); - - /// Pauses gas metering (i.e. gas usage is not counted). Noop if already paused. - function pauseGasMetering() external; - - /// Records all storage reads and writes. - function record() external; - - /// Record all the transaction logs. - function recordLogs() external; - - /// Resumes gas metering (i.e. gas usage is counted again). Noop if already on. - function resumeGasMetering() external; - - /// Performs an Ethereum JSON-RPC request to the current fork URL. - function rpc(string calldata method, string calldata params) external returns (bytes memory data); - - /// Signs `digest` with `privateKey` using the secp256r1 curve. - function signP256(uint256 privateKey, bytes32 digest) external pure returns (bytes32 r, bytes32 s); - - /// Signs `digest` with `privateKey` using the secp256k1 curve. - function sign(uint256 privateKey, bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s); - - /// Signs `digest` with signer provided to script using the secp256k1 curve. - /// If `--sender` is provided, the signer with provided address is used, otherwise, - /// if exactly one signer is provided to the script, that signer is used. - /// Raises error if signer passed through `--sender` does not match any unlocked signers or - /// if `--sender` is not provided and not exactly one signer is passed to the script. - function sign(bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s); - - /// Signs `digest` with signer provided to script using the secp256k1 curve. - /// Raises error if none of the signers passed into the script have provided address. - function sign(address signer, bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s); - - /// Starts recording all map SSTOREs for later retrieval. - function startMappingRecording() external; - - /// Record all account accesses as part of CREATE, CALL or SELFDESTRUCT opcodes in order, - /// along with the context of the calls - function startStateDiffRecording() external; - - /// Returns an ordered array of all account accesses from a `vm.startStateDiffRecording` session. - function stopAndReturnStateDiff() external returns (AccountAccess[] memory accountAccesses); - - /// Stops recording all map SSTOREs for later retrieval and clears the recorded data. - function stopMappingRecording() external; - - // ======== Filesystem ======== - - /// 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; - - /// Copies the contents of one file to another. This function will **overwrite** the contents of `to`. - /// On success, the total number of bytes copied is returned and it is equal to the length of the `to` file as reported by `metadata`. - /// Both `from` and `to` are relative to the project root. - function copyFile(string calldata from, string calldata to) external returns (uint64 copied); - - /// 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; - - /// Returns true if the given path points to an existing entity, else returns false. - function exists(string calldata path) external returns (bool result); - - /// Performs a foreign function call via the terminal. - function ffi(string[] calldata commandInput) external returns (bytes memory result); - - /// 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); - - /// Gets the creation bytecode from an artifact file. Takes in the relative path to the json file or the path to the - /// artifact in the form of :: where and parts are optional. - 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 or the path to the - /// artifact in the form of :: where and parts are optional. - function getDeployedCode(string calldata artifactPath) external view returns (bytes memory runtimeBytecode); - - /// Returns true if the path exists on disk and is pointing at a directory, else returns false. - function isDir(string calldata path) external returns (bool result); - - /// Returns true if the path exists on disk and is pointing at a regular file, else returns false. - function isFile(string calldata path) external returns (bool result); - - /// Get the path of the current project root. - function projectRoot() external view returns (string memory path); - - /// Prompts the user for a string value in the terminal. - function prompt(string calldata promptText) external returns (string memory input); - - /// Prompts the user for an address in the terminal. - function promptAddress(string calldata promptText) external returns (address); - - /// Prompts the user for a hidden string value in the terminal. - function promptSecret(string calldata promptText) external returns (string memory input); - - /// Prompts the user for hidden uint256 in the terminal (usually pk). - function promptSecretUint(string calldata promptText) external returns (uint256); - - /// Prompts the user for uint256 in the terminal. - function promptUint(string calldata promptText) external returns (uint256); - - /// Reads the directory at the given path recursively, up to `maxDepth`. - /// `maxDepth` defaults to 1, meaning only the direct children of the given directory will be returned. - /// Follows symbolic links if `followLinks` is true. - function readDir(string calldata path) external view returns (DirEntry[] memory entries); - - /// See `readDir(string)`. - function readDir(string calldata path, uint64 maxDepth) external view returns (DirEntry[] memory entries); - - /// See `readDir(string)`. - function readDir(string calldata path, uint64 maxDepth, bool followLinks) - external - view - returns (DirEntry[] memory entries); - - /// 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); - - /// 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); - - /// 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; - - /// 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; - - /// Performs a foreign function call via terminal and returns the exit code, stdout, and stderr. - function tryFfi(string[] calldata commandInput) external returns (FfiResult memory result); - - /// Returns the time since unix epoch in milliseconds. - function unixTime() external returns (uint256 milliseconds); - - /// 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; - - // ======== JSON ======== - - /// Checks if `key` exists in a JSON object - /// `keyExists` is being deprecated in favor of `keyExistsJson`. It will be removed in future versions. - function keyExists(string calldata json, string calldata key) external view returns (bool); - - /// Checks if `key` exists in a JSON object. - function keyExistsJson(string calldata json, string calldata key) external view returns (bool); - - /// Parses a string of JSON data at `key` and coerces it to `address`. - function parseJsonAddress(string calldata json, string calldata key) external pure returns (address); - - /// Parses a string of JSON data at `key` and coerces it to `address[]`. - function parseJsonAddressArray(string calldata json, string calldata key) - external - pure - returns (address[] memory); - - /// Parses a string of JSON data at `key` and coerces it to `bool`. - function parseJsonBool(string calldata json, string calldata key) external pure returns (bool); - - /// Parses a string of JSON data at `key` and coerces it to `bool[]`. - function parseJsonBoolArray(string calldata json, string calldata key) external pure returns (bool[] memory); - - /// Parses a string of JSON data at `key` and coerces it to `bytes`. - function parseJsonBytes(string calldata json, string calldata key) external pure returns (bytes memory); - - /// Parses a string of JSON data at `key` and coerces it to `bytes32`. - function parseJsonBytes32(string calldata json, string calldata key) external pure returns (bytes32); - - /// Parses a string of JSON data at `key` and coerces it to `bytes32[]`. - function parseJsonBytes32Array(string calldata json, string calldata key) - external - pure - returns (bytes32[] memory); - - /// Parses a string of JSON data at `key` and coerces it to `bytes[]`. - function parseJsonBytesArray(string calldata json, string calldata key) external pure returns (bytes[] memory); - - /// Parses a string of JSON data at `key` and coerces it to `int256`. - function parseJsonInt(string calldata json, string calldata key) external pure returns (int256); - - /// Parses a string of JSON data at `key` and coerces it to `int256[]`. - function parseJsonIntArray(string calldata json, string calldata key) external pure returns (int256[] memory); - - /// Returns an array of all the keys in a JSON object. - function parseJsonKeys(string calldata json, string calldata key) external pure returns (string[] memory keys); - - /// Parses a string of JSON data at `key` and coerces it to `string`. - function parseJsonString(string calldata json, string calldata key) external pure returns (string memory); - - /// Parses a string of JSON data at `key` and coerces it to `string[]`. - function parseJsonStringArray(string calldata json, string calldata key) external pure returns (string[] memory); - - /// Parses a string of JSON data at `key` and coerces it to `uint256`. - function parseJsonUint(string calldata json, string calldata key) external pure returns (uint256); - - /// Parses a string of JSON data at `key` and coerces it to `uint256[]`. - function parseJsonUintArray(string calldata json, string calldata key) external pure returns (uint256[] memory); - - /// ABI-encodes a JSON object. - function parseJson(string calldata json) external pure returns (bytes memory abiEncodedData); - - /// ABI-encodes a JSON object at `key`. - function parseJson(string calldata json, string calldata key) external pure returns (bytes memory abiEncodedData); - - /// See `serializeJson`. - function serializeAddress(string calldata objectKey, string calldata valueKey, address value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeAddress(string calldata objectKey, string calldata valueKey, address[] calldata values) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeBool(string calldata objectKey, string calldata valueKey, bool value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeBool(string calldata objectKey, string calldata valueKey, bool[] calldata values) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32 value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32[] calldata values) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeBytes(string calldata objectKey, string calldata valueKey, bytes calldata value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeBytes(string calldata objectKey, string calldata valueKey, bytes[] calldata values) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeInt(string calldata objectKey, string calldata valueKey, int256 value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeInt(string calldata objectKey, string calldata valueKey, int256[] calldata values) - external - returns (string memory json); - - /// Serializes a key and value to a JSON object stored in-memory that can be later written to a file. - /// Returns the stringified version of the specific JSON file up to that moment. - function serializeJson(string calldata objectKey, string calldata value) external returns (string memory json); - - /// See `serializeJson`. - function serializeString(string calldata objectKey, string calldata valueKey, string calldata value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeString(string calldata objectKey, string calldata valueKey, string[] calldata values) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeUintToHex(string calldata objectKey, string calldata valueKey, uint256 value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeUint(string calldata objectKey, string calldata valueKey, uint256 value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeUint(string calldata objectKey, string calldata valueKey, uint256[] calldata values) - external - returns (string memory json); - - /// Write a serialized JSON object to a file. If the file exists, it will be overwritten. - 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; - - // ======== Scripting ======== - - /// Has the next call (at this call depth only) create transactions that can later be signed and sent onchain. - /// Broadcasting address is determined by checking the following in order: - /// 1. If `--sender` argument was provided, that address is used. - /// 2. If exactly one signer (e.g. private key, hw wallet, keystore) is set when `forge broadcast` is invoked, that signer is used. - /// 3. Otherwise, default foundry sender (1804c8AB1F12E6bbf3894d4083f33e07309d1f38) is used. - 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; - - /// Has all subsequent calls (at this call depth only) create transactions that can later be signed and sent onchain. - /// Broadcasting address is determined by checking the following in order: - /// 1. If `--sender` argument was provided, that address is used. - /// 2. If exactly one signer (e.g. private key, hw wallet, keystore) is set when `forge broadcast` is invoked, that signer is used. - /// 3. Otherwise, default foundry sender (1804c8AB1F12E6bbf3894d4083f33e07309d1f38) is used. - 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; - - // ======== String ======== - - /// Returns the index of the first occurrence of a `key` in an `input` string. - /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `key` is not found. - /// Returns 0 in case of an empty `key`. - function indexOf(string calldata input, string calldata key) external pure returns (uint256); - - /// Parses the given `string` into an `address`. - function parseAddress(string calldata stringifiedValue) external pure returns (address parsedValue); - - /// Parses the given `string` into a `bool`. - function parseBool(string calldata stringifiedValue) external pure returns (bool parsedValue); - - /// Parses the given `string` into `bytes`. - function parseBytes(string calldata stringifiedValue) external pure returns (bytes memory parsedValue); - - /// Parses the given `string` into a `bytes32`. - function parseBytes32(string calldata stringifiedValue) external pure returns (bytes32 parsedValue); - - /// Parses the given `string` into a `int256`. - function parseInt(string calldata stringifiedValue) external pure returns (int256 parsedValue); - - /// Parses the given `string` into a `uint256`. - function parseUint(string calldata stringifiedValue) external pure returns (uint256 parsedValue); - - /// Replaces occurrences of `from` in the given `string` with `to`. - function replace(string calldata input, string calldata from, string calldata to) - external - pure - returns (string memory output); - - /// Splits the given `string` into an array of strings divided by the `delimiter`. - function split(string calldata input, string calldata delimiter) external pure returns (string[] memory outputs); - - /// Converts the given `string` value to Lowercase. - function toLowercase(string calldata input) external pure returns (string memory output); - - /// Converts the given value to a `string`. - function toString(address value) external pure returns (string memory stringifiedValue); - - /// Converts the given value to a `string`. - function toString(bytes calldata value) external pure returns (string memory stringifiedValue); - - /// Converts the given value to a `string`. - function toString(bytes32 value) external pure returns (string memory stringifiedValue); - - /// Converts the given value to a `string`. - function toString(bool value) external pure returns (string memory stringifiedValue); - - /// Converts the given value to a `string`. - function toString(uint256 value) external pure returns (string memory stringifiedValue); - - /// Converts the given value to a `string`. - function toString(int256 value) external pure returns (string memory stringifiedValue); - - /// Converts the given `string` value to Uppercase. - function toUppercase(string calldata input) external pure returns (string memory output); - - /// Trims leading and trailing whitespace from the given `string` value. - function trim(string calldata input) external pure returns (string memory output); - - // ======== Testing ======== - - /// Compares two `uint256` values. Expects difference to be less than or equal to `maxDelta`. - /// Formats values with decimals in failure message. - function assertApproxEqAbsDecimal(uint256 left, uint256 right, uint256 maxDelta, uint256 decimals) external pure; - - /// Compares two `uint256` values. Expects difference to be less than or equal to `maxDelta`. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertApproxEqAbsDecimal( - uint256 left, - uint256 right, - uint256 maxDelta, - uint256 decimals, - string calldata error - ) external pure; - - /// Compares two `int256` values. Expects difference to be less than or equal to `maxDelta`. - /// Formats values with decimals in failure message. - function assertApproxEqAbsDecimal(int256 left, int256 right, uint256 maxDelta, uint256 decimals) external pure; - - /// Compares two `int256` values. Expects difference to be less than or equal to `maxDelta`. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertApproxEqAbsDecimal( - int256 left, - int256 right, - uint256 maxDelta, - uint256 decimals, - string calldata error - ) external pure; - - /// Compares two `uint256` values. Expects difference to be less than or equal to `maxDelta`. - function assertApproxEqAbs(uint256 left, uint256 right, uint256 maxDelta) external pure; - - /// Compares two `uint256` values. Expects difference to be less than or equal to `maxDelta`. - /// Includes error message into revert string on failure. - function assertApproxEqAbs(uint256 left, uint256 right, uint256 maxDelta, string calldata error) external pure; - - /// Compares two `int256` values. Expects difference to be less than or equal to `maxDelta`. - function assertApproxEqAbs(int256 left, int256 right, uint256 maxDelta) external pure; - - /// Compares two `int256` values. Expects difference to be less than or equal to `maxDelta`. - /// Includes error message into revert string on failure. - function assertApproxEqAbs(int256 left, int256 right, uint256 maxDelta, string calldata error) external pure; - - /// Compares two `uint256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. - /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% - /// Formats values with decimals in failure message. - function assertApproxEqRelDecimal(uint256 left, uint256 right, uint256 maxPercentDelta, uint256 decimals) - external - pure; - - /// Compares two `uint256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. - /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertApproxEqRelDecimal( - uint256 left, - uint256 right, - uint256 maxPercentDelta, - uint256 decimals, - string calldata error - ) external pure; - - /// Compares two `int256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. - /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% - /// Formats values with decimals in failure message. - function assertApproxEqRelDecimal(int256 left, int256 right, uint256 maxPercentDelta, uint256 decimals) - external - pure; - - /// Compares two `int256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. - /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertApproxEqRelDecimal( - int256 left, - int256 right, - uint256 maxPercentDelta, - uint256 decimals, - string calldata error - ) external pure; - - /// Compares two `uint256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. - /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% - function assertApproxEqRel(uint256 left, uint256 right, uint256 maxPercentDelta) external pure; - - /// Compares two `uint256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. - /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% - /// Includes error message into revert string on failure. - function assertApproxEqRel(uint256 left, uint256 right, uint256 maxPercentDelta, string calldata error) - external - pure; - - /// Compares two `int256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. - /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% - function assertApproxEqRel(int256 left, int256 right, uint256 maxPercentDelta) external pure; - - /// Compares two `int256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. - /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% - /// Includes error message into revert string on failure. - function assertApproxEqRel(int256 left, int256 right, uint256 maxPercentDelta, string calldata error) - external - pure; - - /// Asserts that two `uint256` values are equal, formatting them with decimals in failure message. - function assertEqDecimal(uint256 left, uint256 right, uint256 decimals) external pure; - - /// Asserts that two `uint256` values are equal, formatting them with decimals in failure message. - /// Includes error message into revert string on failure. - function assertEqDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure; - - /// Asserts that two `int256` values are equal, formatting them with decimals in failure message. - function assertEqDecimal(int256 left, int256 right, uint256 decimals) external pure; - - /// Asserts that two `int256` values are equal, formatting them with decimals in failure message. - /// Includes error message into revert string on failure. - function assertEqDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure; - - /// Asserts that two `bool` values are equal. - function assertEq(bool left, bool right) external pure; - - /// Asserts that two `bool` values are equal and includes error message into revert string on failure. - function assertEq(bool left, bool right, string calldata error) external pure; - - /// Asserts that two `string` values are equal. - function assertEq(string calldata left, string calldata right) external pure; - - /// Asserts that two `string` values are equal and includes error message into revert string on failure. - function assertEq(string calldata left, string calldata right, string calldata error) external pure; - - /// Asserts that two `bytes` values are equal. - function assertEq(bytes calldata left, bytes calldata right) external pure; - - /// Asserts that two `bytes` values are equal and includes error message into revert string on failure. - function assertEq(bytes calldata left, bytes calldata right, string calldata error) external pure; - - /// Asserts that two arrays of `bool` values are equal. - function assertEq(bool[] calldata left, bool[] calldata right) external pure; - - /// Asserts that two arrays of `bool` values are equal and includes error message into revert string on failure. - function assertEq(bool[] calldata left, bool[] calldata right, string calldata error) external pure; - - /// Asserts that two arrays of `uint256 values are equal. - function assertEq(uint256[] calldata left, uint256[] calldata right) external pure; - - /// Asserts that two arrays of `uint256` values are equal and includes error message into revert string on failure. - function assertEq(uint256[] calldata left, uint256[] calldata right, string calldata error) external pure; - - /// Asserts that two arrays of `int256` values are equal. - function assertEq(int256[] calldata left, int256[] calldata right) external pure; - - /// Asserts that two arrays of `int256` values are equal and includes error message into revert string on failure. - function assertEq(int256[] calldata left, int256[] calldata right, string calldata error) external pure; - - /// Asserts that two `uint256` values are equal. - function assertEq(uint256 left, uint256 right) external pure; - - /// Asserts that two arrays of `address` values are equal. - function assertEq(address[] calldata left, address[] calldata right) external pure; - - /// Asserts that two arrays of `address` values are equal and includes error message into revert string on failure. - function assertEq(address[] calldata left, address[] calldata right, string calldata error) external pure; - - /// Asserts that two arrays of `bytes32` values are equal. - function assertEq(bytes32[] calldata left, bytes32[] calldata right) external pure; - - /// Asserts that two arrays of `bytes32` values are equal and includes error message into revert string on failure. - function assertEq(bytes32[] calldata left, bytes32[] calldata right, string calldata error) external pure; - - /// Asserts that two arrays of `string` values are equal. - function assertEq(string[] calldata left, string[] calldata right) external pure; - - /// Asserts that two arrays of `string` values are equal and includes error message into revert string on failure. - function assertEq(string[] calldata left, string[] calldata right, string calldata error) external pure; - - /// Asserts that two arrays of `bytes` values are equal. - function assertEq(bytes[] calldata left, bytes[] calldata right) external pure; - - /// Asserts that two arrays of `bytes` values are equal and includes error message into revert string on failure. - function assertEq(bytes[] calldata left, bytes[] calldata right, string calldata error) external pure; - - /// Asserts that two `uint256` values are equal and includes error message into revert string on failure. - function assertEq(uint256 left, uint256 right, string calldata error) external pure; - - /// Asserts that two `int256` values are equal. - function assertEq(int256 left, int256 right) external pure; - - /// Asserts that two `int256` values are equal and includes error message into revert string on failure. - function assertEq(int256 left, int256 right, string calldata error) external pure; - - /// Asserts that two `address` values are equal. - function assertEq(address left, address right) external pure; - - /// Asserts that two `address` values are equal and includes error message into revert string on failure. - function assertEq(address left, address right, string calldata error) external pure; - - /// Asserts that two `bytes32` values are equal. - function assertEq(bytes32 left, bytes32 right) external pure; - - /// Asserts that two `bytes32` values are equal and includes error message into revert string on failure. - function assertEq(bytes32 left, bytes32 right, string calldata error) external pure; - - /// Asserts that the given condition is false. - function assertFalse(bool condition) external pure; - - /// Asserts that the given condition is false and includes error message into revert string on failure. - function assertFalse(bool condition, string calldata error) external pure; - - /// Compares two `uint256` values. Expects first value to be greater than or equal to second. - /// Formats values with decimals in failure message. - function assertGeDecimal(uint256 left, uint256 right, uint256 decimals) external pure; - - /// Compares two `uint256` values. Expects first value to be greater than or equal to second. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertGeDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure; - - /// Compares two `int256` values. Expects first value to be greater than or equal to second. - /// Formats values with decimals in failure message. - function assertGeDecimal(int256 left, int256 right, uint256 decimals) external pure; - - /// Compares two `int256` values. Expects first value to be greater than or equal to second. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertGeDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure; - - /// Compares two `uint256` values. Expects first value to be greater than or equal to second. - function assertGe(uint256 left, uint256 right) external pure; - - /// Compares two `uint256` values. Expects first value to be greater than or equal to second. - /// Includes error message into revert string on failure. - function assertGe(uint256 left, uint256 right, string calldata error) external pure; - - /// Compares two `int256` values. Expects first value to be greater than or equal to second. - function assertGe(int256 left, int256 right) external pure; - - /// Compares two `int256` values. Expects first value to be greater than or equal to second. - /// Includes error message into revert string on failure. - function assertGe(int256 left, int256 right, string calldata error) external pure; - - /// Compares two `uint256` values. Expects first value to be greater than second. - /// Formats values with decimals in failure message. - function assertGtDecimal(uint256 left, uint256 right, uint256 decimals) external pure; - - /// Compares two `uint256` values. Expects first value to be greater than second. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertGtDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure; - - /// Compares two `int256` values. Expects first value to be greater than second. - /// Formats values with decimals in failure message. - function assertGtDecimal(int256 left, int256 right, uint256 decimals) external pure; - - /// Compares two `int256` values. Expects first value to be greater than second. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertGtDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure; - - /// Compares two `uint256` values. Expects first value to be greater than second. - function assertGt(uint256 left, uint256 right) external pure; - - /// Compares two `uint256` values. Expects first value to be greater than second. - /// Includes error message into revert string on failure. - function assertGt(uint256 left, uint256 right, string calldata error) external pure; - - /// Compares two `int256` values. Expects first value to be greater than second. - function assertGt(int256 left, int256 right) external pure; - - /// Compares two `int256` values. Expects first value to be greater than second. - /// Includes error message into revert string on failure. - function assertGt(int256 left, int256 right, string calldata error) external pure; - - /// Compares two `uint256` values. Expects first value to be less than or equal to second. - /// Formats values with decimals in failure message. - function assertLeDecimal(uint256 left, uint256 right, uint256 decimals) external pure; - - /// Compares two `uint256` values. Expects first value to be less than or equal to second. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertLeDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure; - - /// Compares two `int256` values. Expects first value to be less than or equal to second. - /// Formats values with decimals in failure message. - function assertLeDecimal(int256 left, int256 right, uint256 decimals) external pure; - - /// Compares two `int256` values. Expects first value to be less than or equal to second. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertLeDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure; - - /// Compares two `uint256` values. Expects first value to be less than or equal to second. - function assertLe(uint256 left, uint256 right) external pure; - - /// Compares two `uint256` values. Expects first value to be less than or equal to second. - /// Includes error message into revert string on failure. - function assertLe(uint256 left, uint256 right, string calldata error) external pure; - - /// Compares two `int256` values. Expects first value to be less than or equal to second. - function assertLe(int256 left, int256 right) external pure; - - /// Compares two `int256` values. Expects first value to be less than or equal to second. - /// Includes error message into revert string on failure. - function assertLe(int256 left, int256 right, string calldata error) external pure; - - /// Compares two `uint256` values. Expects first value to be less than second. - /// Formats values with decimals in failure message. - function assertLtDecimal(uint256 left, uint256 right, uint256 decimals) external pure; - - /// Compares two `uint256` values. Expects first value to be less than second. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertLtDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure; - - /// Compares two `int256` values. Expects first value to be less than second. - /// Formats values with decimals in failure message. - function assertLtDecimal(int256 left, int256 right, uint256 decimals) external pure; - - /// Compares two `int256` values. Expects first value to be less than second. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertLtDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure; - - /// Compares two `uint256` values. Expects first value to be less than second. - function assertLt(uint256 left, uint256 right) external pure; - - /// Compares two `uint256` values. Expects first value to be less than second. - /// Includes error message into revert string on failure. - function assertLt(uint256 left, uint256 right, string calldata error) external pure; - - /// Compares two `int256` values. Expects first value to be less than second. - function assertLt(int256 left, int256 right) external pure; - - /// Compares two `int256` values. Expects first value to be less than second. - /// Includes error message into revert string on failure. - function assertLt(int256 left, int256 right, string calldata error) external pure; - - /// Asserts that two `uint256` values are not equal, formatting them with decimals in failure message. - function assertNotEqDecimal(uint256 left, uint256 right, uint256 decimals) external pure; - - /// Asserts that two `uint256` values are not equal, formatting them with decimals in failure message. - /// Includes error message into revert string on failure. - function assertNotEqDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure; - - /// Asserts that two `int256` values are not equal, formatting them with decimals in failure message. - function assertNotEqDecimal(int256 left, int256 right, uint256 decimals) external pure; - - /// Asserts that two `int256` values are not equal, formatting them with decimals in failure message. - /// Includes error message into revert string on failure. - function assertNotEqDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure; - - /// Asserts that two `bool` values are not equal. - function assertNotEq(bool left, bool right) external pure; - - /// Asserts that two `bool` values are not equal and includes error message into revert string on failure. - function assertNotEq(bool left, bool right, string calldata error) external pure; - - /// Asserts that two `string` values are not equal. - function assertNotEq(string calldata left, string calldata right) external pure; - - /// Asserts that two `string` values are not equal and includes error message into revert string on failure. - function assertNotEq(string calldata left, string calldata right, string calldata error) external pure; - - /// Asserts that two `bytes` values are not equal. - function assertNotEq(bytes calldata left, bytes calldata right) external pure; - - /// Asserts that two `bytes` values are not equal and includes error message into revert string on failure. - function assertNotEq(bytes calldata left, bytes calldata right, string calldata error) external pure; - - /// Asserts that two arrays of `bool` values are not equal. - function assertNotEq(bool[] calldata left, bool[] calldata right) external pure; - - /// Asserts that two arrays of `bool` values are not equal and includes error message into revert string on failure. - function assertNotEq(bool[] calldata left, bool[] calldata right, string calldata error) external pure; - - /// Asserts that two arrays of `uint256` values are not equal. - function assertNotEq(uint256[] calldata left, uint256[] calldata right) external pure; - - /// Asserts that two arrays of `uint256` values are not equal and includes error message into revert string on failure. - function assertNotEq(uint256[] calldata left, uint256[] calldata right, string calldata error) external pure; - - /// Asserts that two arrays of `int256` values are not equal. - function assertNotEq(int256[] calldata left, int256[] calldata right) external pure; - - /// Asserts that two arrays of `int256` values are not equal and includes error message into revert string on failure. - function assertNotEq(int256[] calldata left, int256[] calldata right, string calldata error) external pure; - - /// Asserts that two `uint256` values are not equal. - function assertNotEq(uint256 left, uint256 right) external pure; - - /// Asserts that two arrays of `address` values are not equal. - function assertNotEq(address[] calldata left, address[] calldata right) external pure; - - /// Asserts that two arrays of `address` values are not equal and includes error message into revert string on failure. - function assertNotEq(address[] calldata left, address[] calldata right, string calldata error) external pure; - - /// Asserts that two arrays of `bytes32` values are not equal. - function assertNotEq(bytes32[] calldata left, bytes32[] calldata right) external pure; - - /// Asserts that two arrays of `bytes32` values are not equal and includes error message into revert string on failure. - function assertNotEq(bytes32[] calldata left, bytes32[] calldata right, string calldata error) external pure; - - /// Asserts that two arrays of `string` values are not equal. - function assertNotEq(string[] calldata left, string[] calldata right) external pure; - - /// Asserts that two arrays of `string` values are not equal and includes error message into revert string on failure. - function assertNotEq(string[] calldata left, string[] calldata right, string calldata error) external pure; - - /// Asserts that two arrays of `bytes` values are not equal. - function assertNotEq(bytes[] calldata left, bytes[] calldata right) external pure; - - /// Asserts that two arrays of `bytes` values are not equal and includes error message into revert string on failure. - function assertNotEq(bytes[] calldata left, bytes[] calldata right, string calldata error) external pure; - - /// Asserts that two `uint256` values are not equal and includes error message into revert string on failure. - function assertNotEq(uint256 left, uint256 right, string calldata error) external pure; - - /// Asserts that two `int256` values are not equal. - function assertNotEq(int256 left, int256 right) external pure; - - /// Asserts that two `int256` values are not equal and includes error message into revert string on failure. - function assertNotEq(int256 left, int256 right, string calldata error) external pure; - - /// Asserts that two `address` values are not equal. - function assertNotEq(address left, address right) external pure; - - /// Asserts that two `address` values are not equal and includes error message into revert string on failure. - function assertNotEq(address left, address right, string calldata error) external pure; - - /// Asserts that two `bytes32` values are not equal. - function assertNotEq(bytes32 left, bytes32 right) external pure; - - /// Asserts that two `bytes32` values are not equal and includes error message into revert string on failure. - function assertNotEq(bytes32 left, bytes32 right, string calldata error) external pure; - - /// Asserts that the given condition is true. - function assertTrue(bool condition) external pure; - - /// Asserts that the given condition is true and includes error message into revert string on failure. - function assertTrue(bool condition, string calldata error) external pure; - - /// If the condition is false, discard this run's fuzz inputs and generate new ones. - function assume(bool condition) external pure; - - /// 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; - - /// 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 as structs. - function rpcUrlStructs() external view returns (Rpc[] memory urls); - - /// Returns all rpc urls and their aliases `[alias, url][]`. - function rpcUrls() external view returns (string[2][] memory urls); - - /// Suspends execution of the main thread for `duration` milliseconds. - function sleep(uint256 duration) external; - - // ======== Toml ======== - - /// Checks if `key` exists in a TOML table. - function keyExistsToml(string calldata toml, string calldata key) external view returns (bool); - - /// Parses a string of TOML data at `key` and coerces it to `address`. - function parseTomlAddress(string calldata toml, string calldata key) external pure returns (address); - - /// Parses a string of TOML data at `key` and coerces it to `address[]`. - function parseTomlAddressArray(string calldata toml, string calldata key) - external - pure - returns (address[] memory); - - /// Parses a string of TOML data at `key` and coerces it to `bool`. - function parseTomlBool(string calldata toml, string calldata key) external pure returns (bool); - - /// Parses a string of TOML data at `key` and coerces it to `bool[]`. - function parseTomlBoolArray(string calldata toml, string calldata key) external pure returns (bool[] memory); - - /// Parses a string of TOML data at `key` and coerces it to `bytes`. - function parseTomlBytes(string calldata toml, string calldata key) external pure returns (bytes memory); - - /// Parses a string of TOML data at `key` and coerces it to `bytes32`. - function parseTomlBytes32(string calldata toml, string calldata key) external pure returns (bytes32); - - /// Parses a string of TOML data at `key` and coerces it to `bytes32[]`. - function parseTomlBytes32Array(string calldata toml, string calldata key) - external - pure - returns (bytes32[] memory); - - /// Parses a string of TOML data at `key` and coerces it to `bytes[]`. - function parseTomlBytesArray(string calldata toml, string calldata key) external pure returns (bytes[] memory); - - /// Parses a string of TOML data at `key` and coerces it to `int256`. - function parseTomlInt(string calldata toml, string calldata key) external pure returns (int256); - - /// Parses a string of TOML data at `key` and coerces it to `int256[]`. - function parseTomlIntArray(string calldata toml, string calldata key) external pure returns (int256[] memory); - - /// Returns an array of all the keys in a TOML table. - function parseTomlKeys(string calldata toml, string calldata key) external pure returns (string[] memory keys); - - /// Parses a string of TOML data at `key` and coerces it to `string`. - function parseTomlString(string calldata toml, string calldata key) external pure returns (string memory); - - /// Parses a string of TOML data at `key` and coerces it to `string[]`. - function parseTomlStringArray(string calldata toml, string calldata key) external pure returns (string[] memory); - - /// Parses a string of TOML data at `key` and coerces it to `uint256`. - function parseTomlUint(string calldata toml, string calldata key) external pure returns (uint256); - - /// Parses a string of TOML data at `key` and coerces it to `uint256[]`. - function parseTomlUintArray(string calldata toml, string calldata key) external pure returns (uint256[] memory); - - /// ABI-encodes a TOML table. - function parseToml(string calldata toml) external pure returns (bytes memory abiEncodedData); - - /// ABI-encodes a TOML table at `key`. - function parseToml(string calldata toml, string calldata key) external pure returns (bytes memory abiEncodedData); - - /// Takes serialized JSON, converts to TOML and write a serialized TOML to a file. - function writeToml(string calldata json, string calldata path) external; - - /// Takes serialized JSON, converts to TOML and write a serialized TOML table to an **existing** TOML file, replacing a value with key = - /// This is useful to replace a specific value of a TOML file, without having to parse the entire thing. - function writeToml(string calldata json, string calldata path, string calldata valueKey) external; - - // ======== Utilities ======== - - /// Compute the address of a contract created with CREATE2 using the given CREATE2 deployer. - function computeCreate2Address(bytes32 salt, bytes32 initCodeHash, address deployer) - external - pure - returns (address); - - /// Compute the address of a contract created with CREATE2 using the default CREATE2 deployer. - function computeCreate2Address(bytes32 salt, bytes32 initCodeHash) external pure returns (address); - - /// Compute the address a contract will be deployed at for a given deployer address and nonce. - function computeCreateAddress(address deployer, uint256 nonce) external pure returns (address); - - /// Derives a private key from the name, labels the account with that name, and returns the wallet. - function createWallet(string calldata walletLabel) external returns (Wallet memory wallet); - - /// Generates a wallet from the private key and returns the wallet. - function createWallet(uint256 privateKey) external returns (Wallet memory wallet); - - /// Generates a wallet from the private key, labels the account with that name, and returns the wallet. - function createWallet(uint256 privateKey, string calldata walletLabel) external returns (Wallet memory wallet); - - /// 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); - - /// Derive a private key from a provided mnenomic string (or mnenomic file path) in the specified language - /// at the derivation path `m/44'/60'/0'/0/{index}`. - function deriveKey(string calldata mnemonic, uint32 index, string calldata language) - external - pure - returns (uint256 privateKey); - - /// Derive a private key from a provided mnenomic string (or mnenomic file path) in the specified language - /// at `{derivationPath}{index}`. - function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index, string calldata language) - external - pure - returns (uint256 privateKey); - - /// Returns ENS namehash for provided string. - function ensNamehash(string calldata name) external pure returns (bytes32); - - /// Gets the label for the specified address. - function getLabel(address account) external view returns (string memory currentLabel); - - /// Get a `Wallet`'s nonce. - function getNonce(Wallet calldata wallet) external returns (uint64 nonce); - - /// Labels an address in call traces. - function label(address account, string calldata newLabel) external; - - /// Returns a random `address`. - function randomAddress() external returns (address); - - /// Returns a random uint256 value. - function randomUint() external returns (uint256); - - /// Returns random uin256 value between the provided range (=min..=max). - function randomUint(uint256 min, uint256 max) external returns (uint256); - - /// Adds a private key to the local forge wallet and returns the address. - function rememberKey(uint256 privateKey) external returns (address keyAddr); - - /// Signs data with a `Wallet`. - function sign(Wallet calldata wallet, bytes32 digest) external returns (uint8 v, bytes32 r, bytes32 s); - - /// Encodes a `bytes` value to a base64url string. - function toBase64URL(bytes calldata data) external pure returns (string memory); - - /// Encodes a `string` value to a base64url string. - function toBase64URL(string calldata data) external pure returns (string memory); - - /// Encodes a `bytes` value to a base64 string. - function toBase64(bytes calldata data) external pure returns (string memory); - - /// Encodes a `string` value to a base64 string. - function toBase64(string calldata data) external pure returns (string memory); -} - -/// The `Vm` interface does allow manipulation of the EVM state. These are all intended to be used -/// in tests, but it is not recommended to use these cheats in scripts. -interface Vm is VmSafe { - // ======== EVM ======== - - /// Returns the identifier of the currently active fork. Reverts if no fork is currently active. - function activeFork() external view returns (uint256 forkId); - - /// In forking mode, explicitly grant the given address cheatcode access. - function allowCheatcodes(address account) external; - - /// Sets `block.blobbasefee` - function blobBaseFee(uint256 newBlobBaseFee) external; - - /// Sets the blobhashes in the transaction. - /// Not available on EVM versions before Cancun. - /// If used on unsupported EVM versions it will revert. - function blobhashes(bytes32[] calldata hashes) external; - - /// Sets `block.chainid`. - function chainId(uint256 newChainId) external; - - /// Clears all mocked calls. - function clearMockedCalls() external; - - /// Sets `block.coinbase`. - function coinbase(address newCoinbase) external; - - /// 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 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 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 the latest block and returns the identifier of the fork. - function createSelectFork(string calldata urlOrAlias) 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); - - /// Sets an address' balance. - function deal(address account, uint256 newBalance) external; - - /// Removes the snapshot with the given ID created by `snapshot`. - /// Takes the snapshot ID to delete. - /// Returns `true` if the snapshot was successfully deleted. - /// Returns `false` if the snapshot does not exist. - function deleteSnapshot(uint256 snapshotId) external returns (bool success); - - /// Removes _all_ snapshots previously created by `snapshot`. - function deleteSnapshots() external; - - /// Sets `block.difficulty`. - /// Not available on EVM versions from Paris onwards. Use `prevrandao` instead. - /// Reverts if used on unsupported EVM versions. - function difficulty(uint256 newDifficulty) external; - - /// Dump a genesis JSON file's `allocs` to disk. - function dumpState(string calldata pathToStateJson) external; - - /// Sets an address' code. - function etch(address target, bytes calldata newRuntimeBytecode) external; - - /// Sets `block.basefee`. - function fee(uint256 newBasefee) external; - - /// Gets the blockhashes from the current transaction. - /// Not available on EVM versions before Cancun. - /// If used on unsupported EVM versions it will revert. - function getBlobhashes() external view returns (bytes32[] memory hashes); - - /// Returns true if the account is marked as persistent. - function isPersistent(address account) external view returns (bool persistent); - - /// Load a genesis JSON file's `allocs` into the in-memory revm state. - function loadAllocs(string calldata pathToAllocsJson) 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; - - /// See `makePersistent(address)`. - function makePersistent(address account0, address account1) external; - - /// See `makePersistent(address)`. - function makePersistent(address account0, address account1, address account2) external; - - /// See `makePersistent(address)`. - function makePersistent(address[] calldata accounts) 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; - - /// 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; - - /// Sets the *next* call's `msg.sender` to be the input address. - function prank(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 `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.prevrandao`. - /// Not available on EVM versions before Paris. Use `difficulty` instead. - /// If used on unsupported EVM versions it will revert. - function prevrandao(uint256 newPrevrandao) 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); - - /// Resets the nonce of an account to 0 for EOAs and 1 for contract accounts. - function resetNonce(address account) external; - - /// Revert the state of the EVM to a previous snapshot - /// Takes the snapshot ID to revert to. - /// Returns `true` if the snapshot was successfully reverted. - /// Returns `false` if the snapshot does not exist. - /// **Note:** This does not automatically delete the snapshot. To delete the snapshot use `deleteSnapshot`. - function revertTo(uint256 snapshotId) external returns (bool success); - - /// Revert the state of the EVM to a previous snapshot and automatically deletes the snapshots - /// Takes the snapshot ID to revert to. - /// Returns `true` if the snapshot was successfully reverted and deleted. - /// Returns `false` if the snapshot does not exist. - function revertToAndDelete(uint256 snapshotId) external returns (bool success); - - /// Revokes persistent status from the address, previously added via `makePersistent`. - function revokePersistent(address account) external; - - /// See `revokePersistent(address)`. - function revokePersistent(address[] calldata accounts) external; - - /// Sets `block.height`. - function roll(uint256 newHeight) external; - - /// 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; - - /// Takes a fork identifier created by `createFork` and sets the corresponding forked state as active. - function selectFork(uint256 forkId) 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; - - /// 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); - - /// Sets all subsequent calls' `msg.sender` to be the input address until `stopPrank` is called. - function startPrank(address msgSender) 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; - - /// Stores a value to an address' storage slot. - function store(address target, bytes32 slot, bytes32 value) 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; - - /// Sets `tx.gasprice`. - function txGasPrice(uint256 newGasPrice) external; - - /// Sets `block.timestamp`. - function warp(uint256 newTimestamp) external; - - // ======== Testing ======== - - /// 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; - - /// 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; - - /// 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; - - /// Same as the previous method, but also checks supplied address against emitting contract. - function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData, address emitter) - external; - - /// Prepare an expected log with all topic and data 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. - function expectEmit() external; - - /// Same as the previous method, but also checks supplied address against emitting contract. - function expectEmit(address emitter) external; - - /// Expects an error on next call with any revert data. - function expectRevert() external; - - /// Expects an error on next call that starts with the revert data. - function expectRevert(bytes4 revertData) external; - - /// Expects an error on next call that exactly matches the revert data. - function expectRevert(bytes calldata revertData) 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; - - /// Marks a test as skipped. Must be called at the top of the test. - function skip(bool skipTest) external; - - /// Stops all safe memory expectation in the current subcontext. - function stopExpectSafeMemory() external; -} diff --git a/lib/forge-std/src/console.sol b/lib/forge-std/src/console.sol deleted file mode 100644 index 755eedc..0000000 --- a/lib/forge-std/src/console.sol +++ /dev/null @@ -1,1552 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.4.22 <0.9.0; - -library console { - 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(int p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(int)", p0)); - } - - function logUint(uint p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint)", 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(uint p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint)", p0)); - } - - function log(int p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(int)", 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(uint p0, uint p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint)", p0, p1)); - } - - function log(uint p0, string memory p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,string)", p0, p1)); - } - - function log(uint p0, bool p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool)", p0, p1)); - } - - function log(uint p0, address p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,address)", p0, p1)); - } - - function log(string memory p0, uint p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint)", p0, p1)); - } - - function log(string memory p0, int p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,int)", 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, uint p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint)", 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, uint p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint)", 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(uint p0, uint p1, uint p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint)", p0, p1, p2)); - } - - function log(uint p0, uint p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string)", p0, p1, p2)); - } - - function log(uint p0, uint p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool)", p0, p1, p2)); - } - - function log(uint p0, uint p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address)", p0, p1, p2)); - } - - function log(uint p0, string memory p1, uint p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint)", p0, p1, p2)); - } - - function log(uint p0, string memory p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string)", p0, p1, p2)); - } - - function log(uint p0, string memory p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool)", p0, p1, p2)); - } - - function log(uint p0, string memory p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address)", p0, p1, p2)); - } - - function log(uint p0, bool p1, uint p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint)", p0, p1, p2)); - } - - function log(uint p0, bool p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string)", p0, p1, p2)); - } - - function log(uint p0, bool p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool)", p0, p1, p2)); - } - - function log(uint p0, bool p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address)", p0, p1, p2)); - } - - function log(uint p0, address p1, uint p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint)", p0, p1, p2)); - } - - function log(uint p0, address p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string)", p0, p1, p2)); - } - - function log(uint p0, address p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool)", p0, p1, p2)); - } - - function log(uint p0, address p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address)", p0, p1, p2)); - } - - function log(string memory p0, uint p1, uint p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint)", p0, p1, p2)); - } - - function log(string memory p0, uint p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string)", p0, p1, p2)); - } - - function log(string memory p0, uint p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool)", p0, p1, p2)); - } - - function log(string memory p0, uint p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, uint p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint)", 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, uint p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint)", 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, uint p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint)", 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, uint p1, uint p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint)", p0, p1, p2)); - } - - function log(bool p0, uint p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string)", p0, p1, p2)); - } - - function log(bool p0, uint p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool)", p0, p1, p2)); - } - - function log(bool p0, uint p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, uint p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint)", 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, uint p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint)", 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, uint p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint)", 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, uint p1, uint p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint)", p0, p1, p2)); - } - - function log(address p0, uint p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string)", p0, p1, p2)); - } - - function log(address p0, uint p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool)", p0, p1, p2)); - } - - function log(address p0, uint p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address)", p0, p1, p2)); - } - - function log(address p0, string memory p1, uint p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint)", 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, uint p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint)", 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, uint p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint)", 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(uint p0, uint p1, uint p2, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, uint p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,string)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, uint p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, uint p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,address)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, string memory p2, uint p3) internal pure { - _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 pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,string)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,address)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, bool p2, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,string)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,address)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, address p2, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,string)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,address)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, uint p2, uint p3) internal pure { - _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 pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,string)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, uint p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, uint p2, address p3) internal pure { - _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 pure { - _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 pure { - _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 pure { - _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 pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,address)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, bool p2, uint p3) internal pure { - _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 pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,string)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,address)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, address p2, uint p3) internal pure { - _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 pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,string)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,address)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, uint p2, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, uint p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,string)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, uint p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, uint p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,address)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, string memory p2, uint p3) internal pure { - _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 pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,string)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,address)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, bool p2, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, address p2, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,string)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,address)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, uint p2, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, uint p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,string)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, uint p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, uint p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,address)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, string memory p2, uint p3) internal pure { - _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 pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,string)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,address)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, bool p2, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,string)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,address)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, address p2, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,string)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, uint p2, uint p3) internal pure { - _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 pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, uint p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, uint p2, address p3) internal pure { - _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 pure { - _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 pure { - _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 pure { - _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 pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, bool p2, uint p3) internal pure { - _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 pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, address p2, uint p3) internal pure { - _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 pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, address p2, address p3) internal pure { - _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 pure { - _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 pure { - _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 pure { - _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 pure { - _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 pure { - _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 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, uint p3) internal pure { - _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 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, uint p3) internal pure { - _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 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, uint p2, uint p3) internal pure { - _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 pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint p2, address p3) internal pure { - _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 pure { - _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 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, uint p3) internal pure { - _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 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, uint p3) internal pure { - _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 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, uint p2, uint p3) internal pure { - _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 pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint p2, address p3) internal pure { - _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 pure { - _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 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, uint p3) internal pure { - _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 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, uint p3) internal pure { - _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 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, uint p1, uint p2, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, uint p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, uint p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, uint p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, string memory p2, uint p3) internal pure { - _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 pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, bool p2, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, address p2, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint p2, uint p3) internal pure { - _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 pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint p2, address p3) internal pure { - _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 pure { - _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 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, uint p3) internal pure { - _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 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, uint p3) internal pure { - _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 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, uint p2, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, uint p3) internal pure { - _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 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, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint)", 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, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint)", 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, uint p2, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, uint p3) internal pure { - _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 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, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint)", 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, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint)", 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, uint p1, uint p2, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,uint)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, uint p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, uint p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, uint p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, string memory p2, uint p3) internal pure { - _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 pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, bool p2, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,uint)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, address p2, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,uint)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint p2, uint p3) internal pure { - _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 pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint p2, address p3) internal pure { - _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 pure { - _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 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, uint p3) internal pure { - _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 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, uint p3) internal pure { - _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 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, uint p2, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,uint)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, uint p3) internal pure { - _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 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, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint)", 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, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint)", 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, uint p2, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,uint)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, uint p3) internal pure { - _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 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, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint)", 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, uint p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint)", 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)); - } -} diff --git a/lib/forge-std/src/console2.sol b/lib/forge-std/src/console2.sol deleted file mode 100644 index 03531d9..0000000 --- a/lib/forge-std/src/console2.sol +++ /dev/null @@ -1,4 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.4.22 <0.9.0; - -import {console as console2} from "./console.sol"; diff --git a/lib/forge-std/src/interfaces/IERC1155.sol b/lib/forge-std/src/interfaces/IERC1155.sol deleted file mode 100644 index f7dd2b4..0000000 --- a/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/forge-std/src/interfaces/IERC165.sol b/lib/forge-std/src/interfaces/IERC165.sol deleted file mode 100644 index 9af4bf8..0000000 --- a/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/forge-std/src/interfaces/IERC20.sol b/lib/forge-std/src/interfaces/IERC20.sol deleted file mode 100644 index ba40806..0000000 --- a/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/forge-std/src/interfaces/IERC4626.sol b/lib/forge-std/src/interfaces/IERC4626.sol deleted file mode 100644 index bfe3a11..0000000 --- a/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/forge-std/src/interfaces/IERC721.sol b/lib/forge-std/src/interfaces/IERC721.sol deleted file mode 100644 index 0a16f45..0000000 --- a/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/forge-std/src/interfaces/IMulticall3.sol b/lib/forge-std/src/interfaces/IMulticall3.sol deleted file mode 100644 index 0d031b7..0000000 --- a/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/forge-std/src/mocks/MockERC20.sol b/lib/forge-std/src/mocks/MockERC20.sol deleted file mode 100644 index 2a022fa..0000000 --- a/lib/forge-std/src/mocks/MockERC20.sol +++ /dev/null @@ -1,234 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -import {IERC20} from "../interfaces/IERC20.sol"; - -/// @notice This is a mock contract of the ERC20 standard for testing purposes only, it SHOULD NOT be used in production. -/// @dev Forked from: https://github.com/transmissions11/solmate/blob/0384dbaaa4fcb5715738a9254a7c0a4cb62cf458/src/tokens/ERC20.sol -contract MockERC20 is IERC20 { - /*////////////////////////////////////////////////////////////// - METADATA STORAGE - //////////////////////////////////////////////////////////////*/ - - string internal _name; - - string internal _symbol; - - uint8 internal _decimals; - - function name() external view override returns (string memory) { - return _name; - } - - function symbol() external view override returns (string memory) { - return _symbol; - } - - function decimals() external view override returns (uint8) { - return _decimals; - } - - /*////////////////////////////////////////////////////////////// - ERC20 STORAGE - //////////////////////////////////////////////////////////////*/ - - uint256 internal _totalSupply; - - mapping(address => uint256) internal _balanceOf; - - mapping(address => mapping(address => uint256)) internal _allowance; - - function totalSupply() external view override returns (uint256) { - return _totalSupply; - } - - function balanceOf(address owner) external view override returns (uint256) { - return _balanceOf[owner]; - } - - function allowance(address owner, address spender) external view override returns (uint256) { - return _allowance[owner][spender]; - } - - /*////////////////////////////////////////////////////////////// - EIP-2612 STORAGE - //////////////////////////////////////////////////////////////*/ - - uint256 internal INITIAL_CHAIN_ID; - - bytes32 internal INITIAL_DOMAIN_SEPARATOR; - - mapping(address => uint256) public nonces; - - /*////////////////////////////////////////////////////////////// - INITIALIZE - //////////////////////////////////////////////////////////////*/ - - /// @dev A bool to track whether the contract has been initialized. - bool private initialized; - - /// @dev To hide constructor warnings across solc versions due to different constructor visibility requirements and - /// syntaxes, we add an initialization function that can be called only once. - function initialize(string memory name_, string memory symbol_, uint8 decimals_) public { - require(!initialized, "ALREADY_INITIALIZED"); - - _name = name_; - _symbol = symbol_; - _decimals = decimals_; - - INITIAL_CHAIN_ID = _pureChainId(); - INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator(); - - initialized = true; - } - - /*////////////////////////////////////////////////////////////// - ERC20 LOGIC - //////////////////////////////////////////////////////////////*/ - - function approve(address spender, uint256 amount) public virtual override returns (bool) { - _allowance[msg.sender][spender] = amount; - - emit Approval(msg.sender, spender, amount); - - return true; - } - - function transfer(address to, uint256 amount) public virtual override returns (bool) { - _balanceOf[msg.sender] = _sub(_balanceOf[msg.sender], amount); - _balanceOf[to] = _add(_balanceOf[to], amount); - - emit Transfer(msg.sender, to, amount); - - return true; - } - - function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) { - uint256 allowed = _allowance[from][msg.sender]; // Saves gas for limited approvals. - - if (allowed != ~uint256(0)) _allowance[from][msg.sender] = _sub(allowed, amount); - - _balanceOf[from] = _sub(_balanceOf[from], amount); - _balanceOf[to] = _add(_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"); - - 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 _pureChainId() == 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"), - _pureChainId(), - address(this) - ) - ); - } - - /*////////////////////////////////////////////////////////////// - INTERNAL MINT/BURN LOGIC - //////////////////////////////////////////////////////////////*/ - - function _mint(address to, uint256 amount) internal virtual { - _totalSupply = _add(_totalSupply, amount); - _balanceOf[to] = _add(_balanceOf[to], amount); - - emit Transfer(address(0), to, amount); - } - - function _burn(address from, uint256 amount) internal virtual { - _balanceOf[from] = _sub(_balanceOf[from], amount); - _totalSupply = _sub(_totalSupply, amount); - - emit Transfer(from, address(0), amount); - } - - /*////////////////////////////////////////////////////////////// - INTERNAL SAFE MATH LOGIC - //////////////////////////////////////////////////////////////*/ - - function _add(uint256 a, uint256 b) internal pure returns (uint256) { - uint256 c = a + b; - require(c >= a, "ERC20: addition overflow"); - return c; - } - - function _sub(uint256 a, uint256 b) internal pure returns (uint256) { - require(a >= b, "ERC20: subtraction underflow"); - return a - b; - } - - /*////////////////////////////////////////////////////////////// - HELPERS - //////////////////////////////////////////////////////////////*/ - - // 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(); - } -} diff --git a/lib/forge-std/src/mocks/MockERC721.sol b/lib/forge-std/src/mocks/MockERC721.sol deleted file mode 100644 index 7a4909e..0000000 --- a/lib/forge-std/src/mocks/MockERC721.sol +++ /dev/null @@ -1,231 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -import {IERC721Metadata, IERC721TokenReceiver} from "../interfaces/IERC721.sol"; - -/// @notice This is a mock contract of the ERC721 standard for testing purposes only, it SHOULD NOT be used in production. -/// @dev Forked from: https://github.com/transmissions11/solmate/blob/0384dbaaa4fcb5715738a9254a7c0a4cb62cf458/src/tokens/ERC721.sol -contract MockERC721 is IERC721Metadata { - /*////////////////////////////////////////////////////////////// - METADATA STORAGE/LOGIC - //////////////////////////////////////////////////////////////*/ - - string internal _name; - - string internal _symbol; - - function name() external view override returns (string memory) { - return _name; - } - - function symbol() external view override returns (string memory) { - return _symbol; - } - - function tokenURI(uint256 id) public view virtual override returns (string memory) {} - - /*////////////////////////////////////////////////////////////// - ERC721 BALANCE/OWNER STORAGE - //////////////////////////////////////////////////////////////*/ - - mapping(uint256 => address) internal _ownerOf; - - mapping(address => uint256) internal _balanceOf; - - function ownerOf(uint256 id) public view virtual override returns (address owner) { - require((owner = _ownerOf[id]) != address(0), "NOT_MINTED"); - } - - function balanceOf(address owner) public view virtual override returns (uint256) { - require(owner != address(0), "ZERO_ADDRESS"); - - return _balanceOf[owner]; - } - - /*////////////////////////////////////////////////////////////// - ERC721 APPROVAL STORAGE - //////////////////////////////////////////////////////////////*/ - - mapping(uint256 => address) internal _getApproved; - - mapping(address => mapping(address => bool)) internal _isApprovedForAll; - - function getApproved(uint256 id) public view virtual override returns (address) { - return _getApproved[id]; - } - - function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { - return _isApprovedForAll[owner][operator]; - } - - /*////////////////////////////////////////////////////////////// - INITIALIZE - //////////////////////////////////////////////////////////////*/ - - /// @dev A bool to track whether the contract has been initialized. - bool private initialized; - - /// @dev To hide constructor warnings across solc versions due to different constructor visibility requirements and - /// syntaxes, we add an initialization function that can be called only once. - function initialize(string memory name_, string memory symbol_) public { - require(!initialized, "ALREADY_INITIALIZED"); - - _name = name_; - _symbol = symbol_; - - initialized = true; - } - - /*////////////////////////////////////////////////////////////// - ERC721 LOGIC - //////////////////////////////////////////////////////////////*/ - - function approve(address spender, uint256 id) public payable virtual override { - 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 override { - _isApprovedForAll[msg.sender][operator] = approved; - - emit ApprovalForAll(msg.sender, operator, approved); - } - - function transferFrom(address from, address to, uint256 id) public payable virtual override { - 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. - _balanceOf[from]--; - - _balanceOf[to]++; - - _ownerOf[id] = to; - - delete _getApproved[id]; - - emit Transfer(from, to, id); - } - - function safeTransferFrom(address from, address to, uint256 id) public payable virtual override { - transferFrom(from, to, id); - - require( - !_isContract(to) - || IERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") - == IERC721TokenReceiver.onERC721Received.selector, - "UNSAFE_RECIPIENT" - ); - } - - function safeTransferFrom(address from, address to, uint256 id, bytes memory data) - public - payable - virtual - override - { - transferFrom(from, to, id); - - require( - !_isContract(to) - || IERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) - == IERC721TokenReceiver.onERC721Received.selector, - "UNSAFE_RECIPIENT" - ); - } - - /*////////////////////////////////////////////////////////////// - ERC165 LOGIC - //////////////////////////////////////////////////////////////*/ - - function supportsInterface(bytes4 interfaceId) public view virtual override 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. - - _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"); - - _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( - !_isContract(to) - || IERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") - == IERC721TokenReceiver.onERC721Received.selector, - "UNSAFE_RECIPIENT" - ); - } - - function _safeMint(address to, uint256 id, bytes memory data) internal virtual { - _mint(to, id); - - require( - !_isContract(to) - || IERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) - == IERC721TokenReceiver.onERC721Received.selector, - "UNSAFE_RECIPIENT" - ); - } - - /*////////////////////////////////////////////////////////////// - HELPERS - //////////////////////////////////////////////////////////////*/ - - function _isContract(address _addr) private view returns (bool) { - uint256 codeLength; - - // Assembly required for versions < 0.8.0 to check extcodesize. - assembly { - codeLength := extcodesize(_addr) - } - - return codeLength > 0; - } -} diff --git a/lib/forge-std/src/safeconsole.sol b/lib/forge-std/src/safeconsole.sol deleted file mode 100644 index 5714d09..0000000 --- a/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/forge-std/test/StdAssertions.t.sol b/lib/forge-std/test/StdAssertions.t.sol deleted file mode 100644 index ea79468..0000000 --- a/lib/forge-std/test/StdAssertions.t.sol +++ /dev/null @@ -1,145 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import "../src/StdAssertions.sol"; -import {Vm} from "../src/Vm.sol"; - -interface VmInternal is Vm { - function _expectCheatcodeRevert(bytes memory message) external; -} - -contract StdAssertionsTest is StdAssertions { - string constant errorMessage = "User provided message"; - uint256 constant maxDecimals = 77; - - bool constant SHOULD_REVERT = true; - bool constant SHOULD_RETURN = false; - - bool constant STRICT_REVERT_DATA = true; - bool constant NON_STRICT_REVERT_DATA = false; - - VmInternal constant vm = VmInternal(address(uint160(uint256(keccak256("hevm cheat code"))))); - - function testFuzz_AssertEqCall_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)); - - assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData); - } - - function testFuzz_RevertWhenCalled_AssertEqCall_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._expectCheatcodeRevert( - bytes( - string.concat( - "Call return data does not match: ", vm.toString(returnDataA), " != ", vm.toString(returnDataB) - ) - ) - ); - assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData); - } - - function testFuzz_AssertEqCall_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)); - - assertEqCall(targetA, callDataA, targetB, callDataB, NON_STRICT_REVERT_DATA); - } - - function testFuzz_RevertWhenCalled_AssertEqCall_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._expectCheatcodeRevert( - bytes( - string.concat( - "Call revert data does not match: ", vm.toString(revertDataA), " != ", vm.toString(revertDataB) - ) - ) - ); - assertEqCall(targetA, callDataA, targetB, callDataB, STRICT_REVERT_DATA); - } - - function testFuzz_RevertWhenCalled_AssertEqCall_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.expectRevert(bytes("assertion failed")); - this.assertEqCallExternal(targetA, callDataA, targetB, callDataB, strictRevertData); - - vm.expectRevert(bytes("assertion failed")); - this.assertEqCallExternal(targetB, callDataB, targetA, callDataA, strictRevertData); - } - - // Helper function to test outcome of assertEqCall via `expect` cheatcodes - function assertEqCallExternal( - address targetA, - bytes memory callDataA, - address targetB, - bytes memory callDataB, - bool strictRevertData - ) public { - assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData); - } - - function testFailFail() public { - fail(); - } -} - -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/forge-std/test/StdChains.t.sol b/lib/forge-std/test/StdChains.t.sol deleted file mode 100644 index 09059c2..0000000 --- a/lib/forge-std/test/StdChains.t.sol +++ /dev/null @@ -1,226 +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 test_ChainRpcInitialization() public { - // RPCs specified in `foundry.toml` should be updated. - assertEq(getChain(1).rpcUrl, "https://eth-mainnet.alchemyapi.io/v2/WV407BEiBmjNJfKo9Uo_55u0z0ITyCOX"); - assertEq(getChain("optimism_sepolia").rpcUrl, "https://sepolia.optimism.io/"); - assertEq(getChain("arbitrum_one_sepolia").rpcUrl, "https://sepolia-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://eth-mainnet.alchemyapi.io/v2/WV407BEiBmjNJfKo9Uo_55u0z0ITyCOX"); - - // 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"); - } - - // Named with a leading underscore to clarify this is not intended to be run as a normal test, - // and is intended to be used in the below `test_Rpcs` test. - 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. - // Currently commented out since this is slow and public RPCs are flaky, often resulting in failing CI. - // function test_Rpcs() public { - // _testRpc("mainnet"); - // _testRpc("sepolia"); - // _testRpc("holesky"); - // _testRpc("optimism"); - // _testRpc("optimism_sepolia"); - // _testRpc("arbitrum_one"); - // _testRpc("arbitrum_one_sepolia"); - // _testRpc("arbitrum_nova"); - // _testRpc("polygon"); - // _testRpc("polygon_amoy"); - // _testRpc("avalanche"); - // _testRpc("avalanche_fuji"); - // _testRpc("bnb_smart_chain"); - // _testRpc("bnb_smart_chain_testnet"); - // _testRpc("gnosis_chain"); - // _testRpc("moonbeam"); - // _testRpc("moonriver"); - // _testRpc("moonbase"); - // _testRpc("base_sepolia"); - // _testRpc("base"); - // _testRpc("blast_sepolia"); - // _testRpc("blast"); - // _testRpc("fantom_opera"); - // _testRpc("fantom_opera_testnet"); - // _testRpc("fraxtal"); - // _testRpc("fraxtal_testnet"); - // _testRpc("berachain_bartio_testnet"); - // } - - function test_ChainNoDefault() 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 test_SetChainFirstFails() 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 test_ChainBubbleUp() 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 test_CannotSetChain_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 test_SetChain() 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 test_SetNoEmptyAlias() 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 test_SetNoChainId0() 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 test_GetNoChainId0() 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 test_GetNoEmptyAlias() 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 test_ChainIdNotFound() 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 test_ChainAliasNotFound() 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 test_SetChain_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 test_DontUseDefaultRpcUrl() 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(); - stdChainsMock.exposed_getChain(31337); - vm.expectRevert(); - stdChainsMock.exposed_getChain("sepolia"); - } -} diff --git a/lib/forge-std/test/StdCheats.t.sol b/lib/forge-std/test/StdCheats.t.sol deleted file mode 100644 index 7bac428..0000000 --- a/lib/forge-std/test/StdCheats.t.sol +++ /dev/null @@ -1,618 +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"; -import "../src/StdToml.sol"; -import "../src/interfaces/IERC20.sol"; - -contract StdCheatsTest is Test { - Bar test; - - using stdJson for string; - - function setUp() public { - test = new Bar(); - } - - function test_Skip() public { - vm.warp(100); - skip(25); - assertEq(block.timestamp, 125); - } - - function test_Rewind() public { - vm.warp(100); - rewind(25); - assertEq(block.timestamp, 75); - } - - function test_Hoax() public { - hoax(address(1337)); - test.bar{value: 100}(address(1337)); - } - - function test_HoaxOrigin() public { - hoax(address(1337), address(1337)); - test.origin{value: 100}(address(1337)); - } - - function test_HoaxDifferentAddresses() public { - hoax(address(1337), address(7331)); - test.origin{value: 100}(address(1337), address(7331)); - } - - function test_StartHoax() public { - startHoax(address(1337)); - test.bar{value: 100}(address(1337)); - test.bar{value: 100}(address(1337)); - vm.stopPrank(); - test.bar(address(this)); - } - - function test_StartHoaxOrigin() 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 test_ChangePrankMsgSender() 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 test_ChangePrankMsgSenderAndTxOrigin() 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 test_MakeAccountEquivalence() public { - Account memory account = makeAccount("1337"); - (address addr, uint256 key) = makeAddrAndKey("1337"); - assertEq(account.addr, addr); - assertEq(account.key, key); - } - - function test_MakeAddrEquivalence() public { - (address addr,) = makeAddrAndKey("1337"); - assertEq(makeAddr("1337"), addr); - } - - function test_MakeAddrSigning() 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 test_Deal() public { - deal(address(this), 1 ether); - assertEq(address(this).balance, 1 ether); - } - - function test_DealToken() public { - Bar barToken = new Bar(); - address bar = address(barToken); - deal(bar, address(this), 10000e18); - assertEq(barToken.balanceOf(address(this)), 10000e18); - } - - function test_DealTokenAdjustTotalSupply() 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 test_DealERC1155Token() public { - BarERC1155 barToken = new BarERC1155(); - address bar = address(barToken); - dealERC1155(bar, address(this), 0, 10000e18, false); - assertEq(barToken.balanceOf(address(this), 0), 10000e18); - } - - function test_DealERC1155TokenAdjustTotalSupply() 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 test_DealERC721Token() 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 test_DeployCode() public { - address deployed = deployCode("StdCheats.t.sol:Bar", bytes("")); - assertEq(string(getCode(deployed)), string(getCode(address(test)))); - } - - function test_DestroyAccount() 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 test_DeployCodeNoArgs() public { - address deployed = deployCode("StdCheats.t.sol:Bar"); - assertEq(string(getCode(deployed)), string(getCode(address(test)))); - } - - function test_DeployCodeVal() 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 test_DeployCodeValNoArgs() 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 test_DeployCodeFail() 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 test_DeriveRememberKey() 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 test_BytesToUint() public pure { - 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 test_ParseJsonTxDetail() public view { - 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 test_ReadEIP1559Transaction() 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 test_ReadEIP1559Transactions() 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 test_ReadReceipt() public view { - 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 test_ReadReceipts() 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 test_GasMeteringModifier() 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(); - - 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 testFuzz_AssumeAddressIsNot(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 test_AssumePayable() 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 test_AssumeNotPayable() 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 testFuzz_AssumeNotPrecompile(address addr) external { - assumeNotPrecompile(addr, getChain("optimism_sepolia").chainId); - assertTrue( - addr < address(1) || (addr > address(9) && addr < address(0x4200000000000000000000000000000000000000)) - || addr > address(0x4200000000000000000000000000000000000800) - ); - } - - function testFuzz_AssumeNotForgeAddress(address addr) external pure { - assumeNotForgeAddress(addr); - assertTrue( - addr != address(vm) && addr != 0x000000000000000000636F6e736F6c652e6c6f67 - && addr != 0x4e59b44847b379578588920cA78FbF26c0B4956C - ); - } - - function test_CannotDeployCodeTo() 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 test_DeployCodeTo() 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 test_CannotAssumeNoBlacklisted_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 testFuzz_AssumeNotBlacklisted_TokenWithoutBlacklist(address addr) external view { - assumeNotBlacklisted(SHIB, addr); - assertTrue(true); - } - - function test_AssumeNoBlacklisted_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 testFuzz_AssumeNotBlacklisted_USDC(address addr) external view { - assumeNotBlacklisted(USDC, addr); - assertFalse(USDCLike(USDC).isBlacklisted(addr)); - } - - function test_AssumeNoBlacklisted_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 testFuzz_AssumeNotBlacklisted_USDT(address addr) external view { - assumeNotBlacklisted(USDT, addr); - assertFalse(USDTLike(USDT).isBlackListed(addr)); - } - - function test_dealUSDC() external { - // roll fork to the point when USDC contract updated to store balance in packed slots - vm.rollFork(19279215); - - uint256 balance = 100e6; - deal(USDC, address(this), balance); - assertEq(IERC20(USDC).balanceOf(address(this)), balance); - } -} - -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/forge-std/test/StdError.t.sol b/lib/forge-std/test/StdError.t.sol deleted file mode 100644 index a306eaa..0000000 --- a/lib/forge-std/test/StdError.t.sol +++ /dev/null @@ -1,120 +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 test_ExpectAssertion() public { - vm.expectRevert(stdError.assertionError); - test.assertionError(); - } - - function test_ExpectArithmetic() public { - vm.expectRevert(stdError.arithmeticError); - test.arithmeticError(10); - } - - function test_ExpectDiv() public { - vm.expectRevert(stdError.divisionError); - test.divError(0); - } - - function test_ExpectMod() public { - vm.expectRevert(stdError.divisionError); - test.modError(0); - } - - function test_ExpectEnum() public { - vm.expectRevert(stdError.enumConversionError); - test.enumConversion(1); - } - - function test_ExpectEncodeStg() public { - vm.expectRevert(stdError.encodeStorageError); - test.encodeStgError(); - } - - function test_ExpectPop() public { - vm.expectRevert(stdError.popError); - test.pop(); - } - - function test_ExpectOOB() public { - vm.expectRevert(stdError.indexOOBError); - test.indexOOBError(1); - } - - function test_ExpectMem() public { - vm.expectRevert(stdError.memOverflowError); - test.mem(); - } - - function test_ExpectIntern() 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/forge-std/test/StdJson.t.sol b/lib/forge-std/test/StdJson.t.sol deleted file mode 100644 index e32b92e..0000000 --- a/lib/forge-std/test/StdJson.t.sol +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import "../src/Test.sol"; - -contract StdJsonTest is Test { - using stdJson for string; - - string root; - string path; - - function setUp() public { - root = vm.projectRoot(); - path = string.concat(root, "/test/fixtures/test.json"); - } - - struct SimpleJson { - uint256 a; - string b; - } - - struct NestedJson { - uint256 a; - string b; - SimpleJson c; - } - - function test_readJson() public view { - string memory json = vm.readFile(path); - assertEq(json.readUint(".a"), 123); - } - - function test_writeJson() public { - string memory json = "json"; - json.serialize("a", uint256(123)); - string memory semiFinal = json.serialize("b", string("test")); - string memory finalJson = json.serialize("c", semiFinal); - finalJson.write(path); - - string memory json_ = vm.readFile(path); - bytes memory data = json_.parseRaw("$"); - NestedJson memory decodedData = abi.decode(data, (NestedJson)); - - assertEq(decodedData.a, 123); - assertEq(decodedData.b, "test"); - assertEq(decodedData.c.a, 123); - assertEq(decodedData.c.b, "test"); - } -} diff --git a/lib/forge-std/test/StdMath.t.sol b/lib/forge-std/test/StdMath.t.sol deleted file mode 100644 index ed0f9ba..0000000 --- a/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 test_GetAbs() external pure { - 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 testFuzz_GetAbs(int256 a) external pure { - uint256 manualAbs = getAbs(a); - - uint256 abs = stdMath.abs(a); - - assertEq(abs, manualAbs); - } - - function test_GetDelta_Uint() external pure { - 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 testFuzz_GetDelta_Uint(uint256 a, uint256 b) external pure { - uint256 manualDelta; - if (a > b) { - manualDelta = a - b; - } else { - manualDelta = b - a; - } - - uint256 delta = stdMath.delta(a, b); - - assertEq(delta, manualDelta); - } - - function test_GetDelta_Int() external pure { - 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 testFuzz_GetDelta_Int(int256 a, int256 b) external pure { - 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 test_GetPercentDelta_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 testFuzz_GetPercentDelta_Uint(uint192 a, uint192 b) external pure { - 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 test_GetPercentDelta_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 testFuzz_GetPercentDelta_Int(int192 a, int192 b) external pure { - 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/forge-std/test/StdStorage.t.sol b/lib/forge-std/test/StdStorage.t.sol deleted file mode 100644 index e1e6aa0..0000000 --- a/lib/forge-std/test/StdStorage.t.sol +++ /dev/null @@ -1,463 +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 test_StorageHidden() public { - assertEq(uint256(keccak256("my.random.var")), stdstore.target(address(test)).sig("hidden()").find()); - } - - function test_StorageObvious() public { - assertEq(uint256(0), stdstore.target(address(test)).sig("exists()").find()); - } - - function test_StorageExtraSload() public { - assertEq(16, stdstore.target(address(test)).sig(test.extra_sload.selector).find()); - } - - function test_StorageCheckedWriteHidden() public { - stdstore.target(address(test)).sig(test.hidden.selector).checked_write(100); - assertEq(uint256(test.hidden()), 100); - } - - function test_StorageCheckedWriteObvious() public { - stdstore.target(address(test)).sig(test.exists.selector).checked_write(100); - assertEq(test.exists(), 100); - } - - function test_StorageCheckedWriteSignedIntegerHidden() public { - stdstore.target(address(test)).sig(test.hidden.selector).checked_write_int(-100); - assertEq(int256(uint256(test.hidden())), -100); - } - - function test_StorageCheckedWriteSignedIntegerObvious() public { - stdstore.target(address(test)).sig(test.tG.selector).checked_write_int(-100); - assertEq(test.tG(), -100); - } - - function test_StorageMapStructA() 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 test_StorageMapStructB() 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 test_StorageDeepMap() 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 test_StorageCheckedWriteDeepMap() 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 test_StorageDeepMapStructA() 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 test_StorageDeepMapStructB() 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 test_StorageCheckedWriteDeepMapStructA() 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 test_StorageCheckedWriteDeepMapStructB() 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 test_StorageCheckedWriteMapStructA() 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 test_StorageCheckedWriteMapStructB() 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 test_StorageStructA() public { - uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(0).find(); - assertEq(uint256(7), slot); - } - - function test_StorageStructB() public { - uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(1).find(); - assertEq(uint256(7) + 1, slot); - } - - function test_StorageCheckedWriteStructA() 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 test_StorageCheckedWriteStructB() 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 test_StorageMapAddrFound() 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 test_StorageMapAddrRoot() public { - (uint256 slot, bytes32 key) = - stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).parent(); - assertEq(address(uint160(uint256(key))), address(this)); - assertEq(uint256(1), slot); - slot = stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).root(); - assertEq(uint256(1), slot); - } - - function test_StorageMapUintFound() 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 test_StorageCheckedWriteMapUint() public { - stdstore.target(address(test)).sig(test.map_uint.selector).with_key(100).checked_write(100); - assertEq(100, test.map_uint(100)); - } - - function test_StorageCheckedWriteMapAddr() 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 test_StorageCheckedWriteMapBool() public { - stdstore.target(address(test)).sig(test.map_bool.selector).with_key(address(this)).checked_write(true); - assertTrue(test.map_bool(address(this))); - } - - function testFuzz_StorageCheckedWriteMapPacked(address addr, uint128 value) public { - stdstore.enable_packed_slots().target(address(test)).sig(test.read_struct_lower.selector).with_key(addr) - .checked_write(value); - assertEq(test.read_struct_lower(addr), value); - - stdstore.enable_packed_slots().target(address(test)).sig(test.read_struct_upper.selector).with_key(addr) - .checked_write(value); - assertEq(test.read_struct_upper(addr), value); - } - - function test_StorageCheckedWriteMapPackedFullSuccess() 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 testFail_StorageConst() public { - // vm.expectRevert(abi.encodeWithSignature("NotStorage(bytes4)", bytes4(keccak256("const()")))); - stdstore.target(address(test)).sig("const()").find(); - } - - function testFuzz_StorageNativePack(uint248 val1, uint248 val2, bool boolVal1, bool boolVal2) public { - stdstore.enable_packed_slots().target(address(test)).sig(test.tA.selector).checked_write(val1); - stdstore.enable_packed_slots().target(address(test)).sig(test.tB.selector).checked_write(boolVal1); - stdstore.enable_packed_slots().target(address(test)).sig(test.tC.selector).checked_write(boolVal2); - stdstore.enable_packed_slots().target(address(test)).sig(test.tD.selector).checked_write(val2); - - assertEq(test.tA(), val1); - assertEq(test.tB(), boolVal1); - assertEq(test.tC(), boolVal2); - assertEq(test.tD(), val2); - } - - function test_StorageReadBytes32() public { - bytes32 val = stdstore.target(address(test)).sig(test.tE.selector).read_bytes32(); - assertEq(val, hex"1337"); - } - - function test_StorageReadBool_False() public { - bool val = stdstore.target(address(test)).sig(test.tB.selector).read_bool(); - assertEq(val, false); - } - - function test_StorageReadBool_True() public { - bool val = stdstore.target(address(test)).sig(test.tH.selector).read_bool(); - assertEq(val, true); - } - - function test_StorageReadBool_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 test_StorageReadAddress() public { - address val = stdstore.target(address(test)).sig(test.tF.selector).read_address(); - assertEq(val, address(1337)); - } - - function test_StorageReadUint() public { - uint256 val = stdstore.target(address(test)).sig(test.exists.selector).read_uint(); - assertEq(val, 1); - } - - function test_StorageReadInt() public { - int256 val = stdstore.target(address(test)).sig(test.tG.selector).read_int(); - assertEq(val, type(int256).min); - } - - function testFuzzPacked(uint256 val, uint8 elemToGet) public { - // This function tries an assortment of packed slots, shifts meaning number of elements - // that are packed. Shiftsizes are the size of each element, i.e. 8 means a data type that is 8 bits, 16 == 16 bits, etc. - // Combined, these determine how a slot is packed. Making it random is too hard to avoid global rejection limit - // and make it performant. - - // change the number of shifts - for (uint256 i = 1; i < 5; i++) { - uint256 shifts = i; - - elemToGet = uint8(bound(elemToGet, 0, shifts - 1)); - - uint256[] memory shiftSizes = new uint256[](shifts); - for (uint256 j; j < shifts; j++) { - shiftSizes[j] = 8 * (j + 1); - } - - test.setRandomPacking(val); - - uint256 leftBits; - uint256 rightBits; - for (uint256 j; j < shiftSizes.length; j++) { - if (j < elemToGet) { - leftBits += shiftSizes[j]; - } else if (elemToGet != j) { - rightBits += shiftSizes[j]; - } - } - - // we may have some right bits unaccounted for - leftBits += 256 - (leftBits + shiftSizes[elemToGet] + rightBits); - // clear left bits, then clear right bits and realign - uint256 expectedValToRead = (val << leftBits) >> (leftBits + rightBits); - - uint256 readVal = stdstore.target(address(test)).enable_packed_slots().sig( - "getRandomPacked(uint8,uint8[],uint8)" - ).with_calldata(abi.encode(shifts, shiftSizes, elemToGet)).read_uint(); - - assertEq(readVal, expectedValToRead); - } - } - - function testFuzzPacked2(uint256 nvars, uint256 seed) public { - // Number of random variables to generate. - nvars = bound(nvars, 1, 20); - - // This will decrease as we generate values in the below loop. - uint256 bitsRemaining = 256; - - // Generate a random value and size for each variable. - uint256[] memory vals = new uint256[](nvars); - uint256[] memory sizes = new uint256[](nvars); - uint256[] memory offsets = new uint256[](nvars); - - for (uint256 i = 0; i < nvars; i++) { - // Generate a random value and size. - offsets[i] = i == 0 ? 0 : offsets[i - 1] + sizes[i - 1]; - - uint256 nvarsRemaining = nvars - i; - uint256 maxVarSize = bitsRemaining - nvarsRemaining + 1; - sizes[i] = bound(uint256(keccak256(abi.encodePacked(seed, i + 256))), 1, maxVarSize); - bitsRemaining -= sizes[i]; - - uint256 maxVal; - uint256 varSize = sizes[i]; - assembly { - // mask = (1 << varSize) - 1 - maxVal := sub(shl(varSize, 1), 1) - } - vals[i] = bound(uint256(keccak256(abi.encodePacked(seed, i))), 0, maxVal); - } - - // Pack all values into the slot. - for (uint256 i = 0; i < nvars; i++) { - stdstore.enable_packed_slots().target(address(test)).sig("getRandomPacked(uint256,uint256)").with_key( - sizes[i] - ).with_key(offsets[i]).checked_write(vals[i]); - } - - // Verify the read data matches. - for (uint256 i = 0; i < nvars; i++) { - uint256 readVal = stdstore.enable_packed_slots().target(address(test)).sig( - "getRandomPacked(uint256,uint256)" - ).with_key(sizes[i]).with_key(offsets[i]).read_uint(); - - uint256 retVal = test.getRandomPacked(sizes[i], offsets[i]); - - assertEq(readVal, vals[i]); - assertEq(retVal, vals[i]); - } - } -} - -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; - bytes32 private tI = ~bytes32(hex"1337"); - - uint256 randomPacking; - - 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"); - } - - function extra_sload() public view returns (bytes32 t) { - // trigger read on slot `tE`, and make a staticcall to make sure compiler doesn't optimize this SLOAD away - assembly { - pop(staticcall(gas(), sload(tE.slot), 0, 0, 0, 0)) - } - t = tI; - } - - function setRandomPacking(uint256 val) public { - randomPacking = val; - } - - function _getMask(uint256 size) internal pure returns (uint256 mask) { - assembly { - // mask = (1 << size) - 1 - mask := sub(shl(size, 1), 1) - } - } - - function setRandomPacking(uint256 val, uint256 size, uint256 offset) public { - // Generate mask based on the size of the value - uint256 mask = _getMask(size); - // Zero out all bits for the word we're about to set - uint256 cleanedWord = randomPacking & ~(mask << offset); - // Place val in the correct spot of the cleaned word - randomPacking = cleanedWord | val << offset; - } - - function getRandomPacked(uint256 size, uint256 offset) public view returns (uint256) { - // Generate mask based on the size of the value - uint256 mask = _getMask(size); - // Shift to place the bits in the correct position, and use mask to zero out remaining bits - return (randomPacking >> offset) & mask; - } - - function getRandomPacked(uint8 shifts, uint8[] memory shiftSizes, uint8 elem) public view returns (uint256) { - require(elem < shifts, "!elem"); - uint256 leftBits; - uint256 rightBits; - - for (uint256 i; i < shiftSizes.length; i++) { - if (i < elem) { - leftBits += shiftSizes[i]; - } else if (elem != i) { - rightBits += shiftSizes[i]; - } - } - - // we may have some right bits unaccounted for - leftBits += 256 - (leftBits + shiftSizes[elem] + rightBits); - - // clear left bits, then clear right bits and realign - return (randomPacking << leftBits) >> (leftBits + rightBits); - } -} diff --git a/lib/forge-std/test/StdStyle.t.sol b/lib/forge-std/test/StdStyle.t.sol deleted file mode 100644 index e12c005..0000000 --- a/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 test_StyleColor() 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 test_StyleFontWeight() 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 test_StyleCombined() 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 test_StyleCustom() 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/forge-std/test/StdToml.t.sol b/lib/forge-std/test/StdToml.t.sol deleted file mode 100644 index 631b1b5..0000000 --- a/lib/forge-std/test/StdToml.t.sol +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import "../src/Test.sol"; - -contract StdTomlTest is Test { - using stdToml for string; - - string root; - string path; - - function setUp() public { - root = vm.projectRoot(); - path = string.concat(root, "/test/fixtures/test.toml"); - } - - struct SimpleToml { - uint256 a; - string b; - } - - struct NestedToml { - uint256 a; - string b; - SimpleToml c; - } - - function test_readToml() public view { - string memory json = vm.readFile(path); - assertEq(json.readUint(".a"), 123); - } - - function test_writeToml() public { - string memory json = "json"; - json.serialize("a", uint256(123)); - string memory semiFinal = json.serialize("b", string("test")); - string memory finalJson = json.serialize("c", semiFinal); - finalJson.write(path); - - string memory toml = vm.readFile(path); - bytes memory data = toml.parseRaw("$"); - NestedToml memory decodedData = abi.decode(data, (NestedToml)); - - assertEq(decodedData.a, 123); - assertEq(decodedData.b, "test"); - assertEq(decodedData.c.a, 123); - assertEq(decodedData.c.b, "test"); - } -} diff --git a/lib/forge-std/test/StdUtils.t.sol b/lib/forge-std/test/StdUtils.t.sol deleted file mode 100644 index 4994c6c..0000000 --- a/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 pure returns (int256) { - return bound(num, min, max); - } - - function exposed_bound(uint256 num, uint256 min, uint256 max) external pure 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 test_Bound() public pure { - 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 test_Bound_WithinRange() public pure { - 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 test_Bound_EdgeCoverage() public pure { - 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 test_Bound_DistributionIsEven(uint256 min, uint256 size) public pure { - 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 test_Bound(uint256 num, uint256 min, uint256 max) public pure { - 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 test_BoundUint256Max() public pure { - 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 test_CannotBoundMaxLessThanMin() 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 test_CannotBoundMaxLessThanMin(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 test_BoundInt() public pure { - 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 test_BoundInt_WithinRange() public pure { - 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 test_BoundInt_EdgeCoverage() public pure { - 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 test_BoundInt_DistributionIsEven(int256 min, uint256 size) public pure { - 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 test_BoundInt(int256 num, int256 min, int256 max) public pure { - 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 test_BoundIntInt256Max() public pure { - 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 test_BoundIntInt256Min() public pure { - 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 test_CannotBoundIntMaxLessThanMin() 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 test_CannotBoundIntMaxLessThanMin(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 test_BoundPrivateKey() public pure { - 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 test_BytesToUint() external pure { - 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 test_CannotConvertGT32Bytes() 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 test_ComputeCreateAddress() external pure { - address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9; - uint256 nonce = 14; - address createAddress = computeCreateAddress(deployer, nonce); - assertEq(createAddress, 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45); - } - - /*////////////////////////////////////////////////////////////////////////// - COMPUTE CREATE2 ADDRESS - //////////////////////////////////////////////////////////////////////////*/ - - function test_ComputeCreate2Address() external pure { - bytes32 salt = bytes32(uint256(31415)); - bytes32 initcodeHash = keccak256(abi.encode(0x6080)); - address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9; - address create2Address = computeCreate2Address(salt, initcodeHash, deployer); - assertEq(create2Address, 0xB147a5d25748fda14b463EB04B111027C290f4d3); - } - - function test_ComputeCreate2AddressWithDefaultDeployer() external pure { - 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 test_CannotGetTokenBalances_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 test_CannotGetTokenBalances_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 test_GetTokenBalances_Empty() external { - address[] memory addresses = new address[](0); - uint256[] memory balances = getTokenBalances(USDC, addresses); - assertEq(balances.length, 0); - } - - function test_GetTokenBalances_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 test_GetTokenBalances_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/forge-std/test/Vm.t.sol b/lib/forge-std/test/Vm.t.sol deleted file mode 100644 index 6f380ed..0000000 --- a/lib/forge-std/test/Vm.t.sol +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0 <0.9.0; - -import {Test} from "../src/Test.sol"; -import {Vm, VmSafe} from "../src/Vm.sol"; - -contract VmTest is Test { - // This test ensures that functions are never accidentally removed from a Vm interface, or - // inadvertently moved between Vm and VmSafe. This test must be updated each time a function is - // added to or removed from Vm or VmSafe. - function test_interfaceId() public pure { - assertEq(type(VmSafe).interfaceId, bytes4(0x1c17c241), "VmSafe"); - assertEq(type(Vm).interfaceId, bytes4(0xb91a22ba), "Vm"); - } -} diff --git a/lib/forge-std/test/compilation/CompilationScript.sol b/lib/forge-std/test/compilation/CompilationScript.sol deleted file mode 100644 index e205cff..0000000 --- a/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/forge-std/test/compilation/CompilationScriptBase.sol b/lib/forge-std/test/compilation/CompilationScriptBase.sol deleted file mode 100644 index ce8e0e9..0000000 --- a/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/forge-std/test/compilation/CompilationTest.sol b/lib/forge-std/test/compilation/CompilationTest.sol deleted file mode 100644 index 9beeafe..0000000 --- a/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/forge-std/test/compilation/CompilationTestBase.sol b/lib/forge-std/test/compilation/CompilationTestBase.sol deleted file mode 100644 index e993535..0000000 --- a/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/forge-std/test/fixtures/broadcast.log.json b/lib/forge-std/test/fixtures/broadcast.log.json deleted file mode 100644 index 0a0200b..0000000 --- a/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/forge-std/test/fixtures/test.json b/lib/forge-std/test/fixtures/test.json deleted file mode 100644 index caebf6d..0000000 --- a/lib/forge-std/test/fixtures/test.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "a": 123, - "b": "test", - "c": { - "a": 123, - "b": "test" - } -} \ No newline at end of file diff --git a/lib/forge-std/test/fixtures/test.toml b/lib/forge-std/test/fixtures/test.toml deleted file mode 100644 index 60692bc..0000000 --- a/lib/forge-std/test/fixtures/test.toml +++ /dev/null @@ -1,6 +0,0 @@ -a = 123 -b = "test" - -[c] -a = 123 -b = "test" diff --git a/lib/forge-std/test/mocks/MockERC20.t.sol b/lib/forge-std/test/mocks/MockERC20.t.sol deleted file mode 100644 index e246810..0000000 --- a/lib/forge-std/test/mocks/MockERC20.t.sol +++ /dev/null @@ -1,441 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import {MockERC20} from "../../src/mocks/MockERC20.sol"; -import {StdCheats} from "../../src/StdCheats.sol"; -import {Test} from "../../src/Test.sol"; - -contract Token_ERC20 is MockERC20 { - constructor(string memory name, string memory symbol, uint8 decimals) { - initialize(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); - } -} - -contract MockERC20Test is StdCheats, Test { - Token_ERC20 token; - - bytes32 constant PERMIT_TYPEHASH = - keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); - - function setUp() public { - token = new Token_ERC20("Token", "TKN", 18); - } - - function invariantMetadata() public view { - 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); - - vm.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); - - vm.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 = vm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = vm.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); - - vm.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); - - vm.prank(from); - token.approve(address(this), 1e18); - - token.transferFrom(from, address(0xBEEF), 1e18); - } - - function testFailPermitBadNonce() public { - uint256 privateKey = 0xBEEF; - address owner = vm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = vm.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 = vm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = vm.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 = vm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = vm.sign( - privateKey, - keccak256( - abi.encodePacked( - "\x19\x01", - token.DOMAIN_SEPARATOR(), - keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 0, oldTimestamp)) - ) - ) - ); - - vm.warp(block.timestamp + 1); - token.permit(owner, address(0xCAFE), 1e18, oldTimestamp, v, r, s); - } - - function testFailPermitReplay() public { - uint256 privateKey = 0xBEEF; - address owner = vm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = vm.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 { - Token_ERC20 tkn = new Token_ERC20(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); - - vm.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 = vm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = vm.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); - - vm.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); - - vm.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 = vm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = vm.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 = vm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = vm.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 = vm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = vm.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 = vm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = vm.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); - } -} diff --git a/lib/forge-std/test/mocks/MockERC721.t.sol b/lib/forge-std/test/mocks/MockERC721.t.sol deleted file mode 100644 index f986d79..0000000 --- a/lib/forge-std/test/mocks/MockERC721.t.sol +++ /dev/null @@ -1,721 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import {MockERC721, IERC721TokenReceiver} from "../../src/mocks/MockERC721.sol"; -import {StdCheats} from "../../src/StdCheats.sol"; -import {Test} from "../../src/Test.sol"; - -contract ERC721Recipient is IERC721TokenReceiver { - 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 IERC721TokenReceiver.onERC721Received.selector; - } -} - -contract RevertingERC721Recipient is IERC721TokenReceiver { - function onERC721Received(address, address, uint256, bytes calldata) public virtual override returns (bytes4) { - revert(string(abi.encodePacked(IERC721TokenReceiver.onERC721Received.selector))); - } -} - -contract WrongReturnDataERC721Recipient is IERC721TokenReceiver { - function onERC721Received(address, address, uint256, bytes calldata) public virtual override returns (bytes4) { - return 0xCAFEBEEF; - } -} - -contract NonERC721Recipient {} - -contract Token_ERC721 is MockERC721 { - constructor(string memory _name, string memory _symbol) { - initialize(_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); - } -} - -contract MockERC721Test is StdCheats, Test { - Token_ERC721 token; - - function setUp() public { - token = new Token_ERC721("Token", "TKN"); - } - - function invariantMetadata() public view { - 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); - - vm.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)); - - vm.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); - - vm.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); - - vm.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); - - vm.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); - - vm.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); - assertEq(recipient.data(), ""); - } - - function testSafeTransferFromToERC721RecipientWithData() public { - address from = address(0xABCD); - ERC721Recipient recipient = new ERC721Recipient(); - - token.mint(from, 1337); - - vm.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); - assertEq(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); - assertEq(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); - assertEq(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 Token_ERC721(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); - - vm.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)); - - vm.expectRevert("NOT_MINTED"); - token.ownerOf(id); - } - - function testApproveAll(address to, bool approved) public { - token.setApprovalForAll(to, approved); - - assertEq(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); - - vm.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); - - vm.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); - - vm.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); - - vm.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); - assertEq(recipient.data(), ""); - } - - function testSafeTransferFromToERC721RecipientWithData(uint256 id, bytes calldata data) public { - address from = address(0xABCD); - ERC721Recipient recipient = new ERC721Recipient(); - - token.mint(from, id); - - vm.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); - assertEq(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); - assertEq(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); - assertEq(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/openzeppelin-contracts/.changeset/chilled-walls-develop.md b/lib/openzeppelin-contracts/.changeset/chilled-walls-develop.md deleted file mode 100644 index 4108feb..0000000 --- a/lib/openzeppelin-contracts/.changeset/chilled-walls-develop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`Clones`: Add version of `clone` and `cloneDeterministic` that support sending value at creation. diff --git a/lib/openzeppelin-contracts/.changeset/chilly-humans-warn.md b/lib/openzeppelin-contracts/.changeset/chilly-humans-warn.md deleted file mode 100644 index 1301dfe..0000000 --- a/lib/openzeppelin-contracts/.changeset/chilly-humans-warn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': patch ---- - -`ProxyAdmin`: Fixed documentation for `UPGRADE_INTERFACE_VERSION` getter. diff --git a/lib/openzeppelin-contracts/.changeset/cold-cheetahs-check.md b/lib/openzeppelin-contracts/.changeset/cold-cheetahs-check.md deleted file mode 100644 index 0697dcd..0000000 --- a/lib/openzeppelin-contracts/.changeset/cold-cheetahs-check.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`CircularBuffer`: Add a data structure that stores the last `N` values pushed to it. diff --git a/lib/openzeppelin-contracts/.changeset/config.json b/lib/openzeppelin-contracts/.changeset/config.json deleted file mode 100644 index 66794fa..0000000 --- a/lib/openzeppelin-contracts/.changeset/config.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json", - "changelog": [ - "@changesets/changelog-github", - { - "repo": "OpenZeppelin/openzeppelin-contracts" - } - ], - "commit": false, - "access": "public", - "baseBranch": "master" -} diff --git a/lib/openzeppelin-contracts/.changeset/cool-mangos-compare.md b/lib/openzeppelin-contracts/.changeset/cool-mangos-compare.md deleted file mode 100644 index 470ee08..0000000 --- a/lib/openzeppelin-contracts/.changeset/cool-mangos-compare.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`Math`: add an `invMod` function to get the modular multiplicative inverse of a number in Z/nZ. diff --git a/lib/openzeppelin-contracts/.changeset/curvy-crabs-repeat.md b/lib/openzeppelin-contracts/.changeset/curvy-crabs-repeat.md deleted file mode 100644 index db3ef27..0000000 --- a/lib/openzeppelin-contracts/.changeset/curvy-crabs-repeat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`RSA`: Library to verify signatures according to RFC 8017 Signature Verification Operation diff --git a/lib/openzeppelin-contracts/.changeset/dirty-cobras-smile.md b/lib/openzeppelin-contracts/.changeset/dirty-cobras-smile.md deleted file mode 100644 index d71194c..0000000 --- a/lib/openzeppelin-contracts/.changeset/dirty-cobras-smile.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`Arrays`: add a `sort` functions for `address[]`, `bytes32[]` and `uint256[]` memory arrays. diff --git a/lib/openzeppelin-contracts/.changeset/eight-eyes-burn.md b/lib/openzeppelin-contracts/.changeset/eight-eyes-burn.md deleted file mode 100644 index 908c90c..0000000 --- a/lib/openzeppelin-contracts/.changeset/eight-eyes-burn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`GovernorCountingFractional`: Add a governor counting module that allows distributing voting power amongst 3 options (For, Against, Abstain). diff --git a/lib/openzeppelin-contracts/.changeset/eleven-planets-relax.md b/lib/openzeppelin-contracts/.changeset/eleven-planets-relax.md deleted file mode 100644 index a1f1bbf..0000000 --- a/lib/openzeppelin-contracts/.changeset/eleven-planets-relax.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': patch ---- - -`TransparentUpgradeableProxy`: Make internal `_proxyAdmin()` getter have `view` visibility. diff --git a/lib/openzeppelin-contracts/.changeset/flat-turtles-repeat.md b/lib/openzeppelin-contracts/.changeset/flat-turtles-repeat.md deleted file mode 100644 index 6b62720..0000000 --- a/lib/openzeppelin-contracts/.changeset/flat-turtles-repeat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`Arrays`: deprecate `findUpperBound` in favor of the new `lowerBound`. diff --git a/lib/openzeppelin-contracts/.changeset/fluffy-steaks-exist.md b/lib/openzeppelin-contracts/.changeset/fluffy-steaks-exist.md deleted file mode 100644 index b625e24..0000000 --- a/lib/openzeppelin-contracts/.changeset/fluffy-steaks-exist.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': patch ---- - -`Create2`, `Clones`: Mask `computeAddress` and `cloneDeterministic` outputs to produce a clean value for an `address` type (i.e. only use 20 bytes) diff --git a/lib/openzeppelin-contracts/.changeset/forty-dodos-visit.md b/lib/openzeppelin-contracts/.changeset/forty-dodos-visit.md deleted file mode 100644 index 7d5ae74..0000000 --- a/lib/openzeppelin-contracts/.changeset/forty-dodos-visit.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`Strings`: Added a utility function for converting an address to checksummed string. diff --git a/lib/openzeppelin-contracts/.changeset/friendly-nails-push.md b/lib/openzeppelin-contracts/.changeset/friendly-nails-push.md deleted file mode 100644 index 157bf05..0000000 --- a/lib/openzeppelin-contracts/.changeset/friendly-nails-push.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`ERC1363`: Add implementation of the token payable standard allowing execution of contract code after transfers and approvals. diff --git a/lib/openzeppelin-contracts/.changeset/gentle-bulldogs-turn.md b/lib/openzeppelin-contracts/.changeset/gentle-bulldogs-turn.md deleted file mode 100644 index 12bc87a..0000000 --- a/lib/openzeppelin-contracts/.changeset/gentle-bulldogs-turn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`DoubleEndedQueue`: Custom errors replaced with native panic codes. diff --git a/lib/openzeppelin-contracts/.changeset/gorgeous-badgers-vanish.md b/lib/openzeppelin-contracts/.changeset/gorgeous-badgers-vanish.md deleted file mode 100644 index ce75ed6..0000000 --- a/lib/openzeppelin-contracts/.changeset/gorgeous-badgers-vanish.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`SlotDerivation`: Add a library of methods for derivating common storage slots. diff --git a/lib/openzeppelin-contracts/.changeset/heavy-baboons-give.md b/lib/openzeppelin-contracts/.changeset/heavy-baboons-give.md deleted file mode 100644 index 5852748..0000000 --- a/lib/openzeppelin-contracts/.changeset/heavy-baboons-give.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`Packing`: Added a new utility for packing, extracting and replacing bytesXX values. diff --git a/lib/openzeppelin-contracts/.changeset/kind-planets-cough.md b/lib/openzeppelin-contracts/.changeset/kind-planets-cough.md deleted file mode 100644 index 988e24c..0000000 --- a/lib/openzeppelin-contracts/.changeset/kind-planets-cough.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`StorageSlot`: Add primitives for operating on the transient storage space using a typed-slot representation. diff --git a/lib/openzeppelin-contracts/.changeset/light-news-listen.md b/lib/openzeppelin-contracts/.changeset/light-news-listen.md deleted file mode 100644 index 1572d90..0000000 --- a/lib/openzeppelin-contracts/.changeset/light-news-listen.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`AccessManager`: Allow the `onlyAuthorized` modifier to restrict functions added to the manager. diff --git a/lib/openzeppelin-contracts/.changeset/lucky-crews-eat.md b/lib/openzeppelin-contracts/.changeset/lucky-crews-eat.md deleted file mode 100644 index 48592b5..0000000 --- a/lib/openzeppelin-contracts/.changeset/lucky-crews-eat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`Votes`: Set `_moveDelegateVotes` visibility to internal instead of private. diff --git a/lib/openzeppelin-contracts/.changeset/nervous-eyes-teach.md b/lib/openzeppelin-contracts/.changeset/nervous-eyes-teach.md deleted file mode 100644 index f85bc66..0000000 --- a/lib/openzeppelin-contracts/.changeset/nervous-eyes-teach.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`Create2`: Bubbles up returndata from a deployed contract that reverted during construction. diff --git a/lib/openzeppelin-contracts/.changeset/nervous-pans-grow.md b/lib/openzeppelin-contracts/.changeset/nervous-pans-grow.md deleted file mode 100644 index b86a075..0000000 --- a/lib/openzeppelin-contracts/.changeset/nervous-pans-grow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': patch ---- - -`SafeCast`: Add `toUint(bool)` for operating on `bool` values as `uint256`. diff --git a/lib/openzeppelin-contracts/.changeset/nice-paws-pull.md b/lib/openzeppelin-contracts/.changeset/nice-paws-pull.md deleted file mode 100644 index 11f48d5..0000000 --- a/lib/openzeppelin-contracts/.changeset/nice-paws-pull.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`SafeERC20`: Add "relaxed" function for interacting with ERC-1363 functions in a way that is compatible with EOAs. diff --git a/lib/openzeppelin-contracts/.changeset/odd-files-protect.md b/lib/openzeppelin-contracts/.changeset/odd-files-protect.md deleted file mode 100644 index 8b334ac..0000000 --- a/lib/openzeppelin-contracts/.changeset/odd-files-protect.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`Hashes`: A library with commonly used hash functions. diff --git a/lib/openzeppelin-contracts/.changeset/odd-lobsters-wash.md b/lib/openzeppelin-contracts/.changeset/odd-lobsters-wash.md deleted file mode 100644 index 578f7a4..0000000 --- a/lib/openzeppelin-contracts/.changeset/odd-lobsters-wash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`P256`: Library for verification and public key recovery of P256 (aka secp256r1) signatures. diff --git a/lib/openzeppelin-contracts/.changeset/poor-chefs-cheat.md b/lib/openzeppelin-contracts/.changeset/poor-chefs-cheat.md deleted file mode 100644 index 39db3d5..0000000 --- a/lib/openzeppelin-contracts/.changeset/poor-chefs-cheat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`ERC721Utils` and `ERC1155Utils`: Add reusable libraries with functions to perform acceptance checks on `IERC721Receiver` and `IERC1155Receiver` implementers. diff --git a/lib/openzeppelin-contracts/.changeset/shiny-poets-whisper.md b/lib/openzeppelin-contracts/.changeset/shiny-poets-whisper.md deleted file mode 100644 index 9249703..0000000 --- a/lib/openzeppelin-contracts/.changeset/shiny-poets-whisper.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`Math`: Add `modExp` function that exposes the `EIP-198` precompile. Includes `uint256` and `bytes memory` versions. diff --git a/lib/openzeppelin-contracts/.changeset/silver-swans-promise.md b/lib/openzeppelin-contracts/.changeset/silver-swans-promise.md deleted file mode 100644 index 1d2ff2e..0000000 --- a/lib/openzeppelin-contracts/.changeset/silver-swans-promise.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`Panic`: Add a library for reverting with panic codes. diff --git a/lib/openzeppelin-contracts/.changeset/smart-bugs-switch.md b/lib/openzeppelin-contracts/.changeset/smart-bugs-switch.md deleted file mode 100644 index 8a001ae..0000000 --- a/lib/openzeppelin-contracts/.changeset/smart-bugs-switch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`Math`: Custom errors replaced with native panic codes. diff --git a/lib/openzeppelin-contracts/.changeset/spotty-falcons-explain.md b/lib/openzeppelin-contracts/.changeset/spotty-falcons-explain.md deleted file mode 100644 index 28cb951..0000000 --- a/lib/openzeppelin-contracts/.changeset/spotty-falcons-explain.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`Math`, `SignedMath`: Add a branchless `ternary` function that computes`cond ? a : b` in constant gas cost. diff --git a/lib/openzeppelin-contracts/.changeset/spotty-queens-own.md b/lib/openzeppelin-contracts/.changeset/spotty-queens-own.md deleted file mode 100644 index 98fb2fb..0000000 --- a/lib/openzeppelin-contracts/.changeset/spotty-queens-own.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`MerkleProof`: Add variations of `verify`, `processProof`, `multiProofVerify` and `processMultiProof` (and equivalent calldata version) with support for custom hashing functions. diff --git a/lib/openzeppelin-contracts/.changeset/strong-singers-talk.md b/lib/openzeppelin-contracts/.changeset/strong-singers-talk.md deleted file mode 100644 index 7897980..0000000 --- a/lib/openzeppelin-contracts/.changeset/strong-singers-talk.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`Errors`: New library of common custom errors. diff --git a/lib/openzeppelin-contracts/.changeset/thick-pumpkins-report.md b/lib/openzeppelin-contracts/.changeset/thick-pumpkins-report.md deleted file mode 100644 index f17a208..0000000 --- a/lib/openzeppelin-contracts/.changeset/thick-pumpkins-report.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`Arrays`: add new functions `lowerBound`, `upperBound`, `lowerBoundMemory` and `upperBoundMemory` for lookups in sorted arrays with potential duplicates. diff --git a/lib/openzeppelin-contracts/.changeset/thin-walls-drop.md b/lib/openzeppelin-contracts/.changeset/thin-walls-drop.md deleted file mode 100644 index 8026002..0000000 --- a/lib/openzeppelin-contracts/.changeset/thin-walls-drop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`AccessManager`, `VestingWallet`, `TimelockController` and `ERC2771Forwarder`: Added a public `initializer` function in their corresponding upgradeable variants. diff --git a/lib/openzeppelin-contracts/.changeset/twenty-feet-grin.md b/lib/openzeppelin-contracts/.changeset/twenty-feet-grin.md deleted file mode 100644 index 69b4fe6..0000000 --- a/lib/openzeppelin-contracts/.changeset/twenty-feet-grin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`Base64`: Add `encodeURL` following section 5 of RFC4648 for URL encoding diff --git a/lib/openzeppelin-contracts/.changeset/violet-moons-tell.md b/lib/openzeppelin-contracts/.changeset/violet-moons-tell.md deleted file mode 100644 index be215e1..0000000 --- a/lib/openzeppelin-contracts/.changeset/violet-moons-tell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`AccessControlEnumerable`: Add a `getRoleMembers` method to return all accounts that have `role`. diff --git a/lib/openzeppelin-contracts/.changeset/warm-sheep-cover.md b/lib/openzeppelin-contracts/.changeset/warm-sheep-cover.md deleted file mode 100644 index f0a2eba..0000000 --- a/lib/openzeppelin-contracts/.changeset/warm-sheep-cover.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`MerkleTree`: A data structure that allows inserting elements into a merkle tree and updating its root hash. diff --git a/lib/openzeppelin-contracts/.changeset/wise-bobcats-speak.md b/lib/openzeppelin-contracts/.changeset/wise-bobcats-speak.md deleted file mode 100644 index 6ecd969..0000000 --- a/lib/openzeppelin-contracts/.changeset/wise-bobcats-speak.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`VestingWalletCliff`: Add an extension of the `VestingWallet` contract with an added cliff. diff --git a/lib/openzeppelin-contracts/.changeset/witty-chicken-smile.md b/lib/openzeppelin-contracts/.changeset/witty-chicken-smile.md deleted file mode 100644 index 6fae3e7..0000000 --- a/lib/openzeppelin-contracts/.changeset/witty-chicken-smile.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`ReentrancyGuardTransient`: Added a variant of `ReentrancyGuard` that uses transient storage. diff --git a/lib/openzeppelin-contracts/.changeset/yellow-deers-walk.md b/lib/openzeppelin-contracts/.changeset/yellow-deers-walk.md deleted file mode 100644 index ad370b3..0000000 --- a/lib/openzeppelin-contracts/.changeset/yellow-deers-walk.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`EnumerableMap`: add `UintToBytes32Map`, `AddressToAddressMap`, `AddressToBytes32Map` and `Bytes32ToAddressMap`. diff --git a/lib/openzeppelin-contracts/.changeset/yellow-moles-hammer.md b/lib/openzeppelin-contracts/.changeset/yellow-moles-hammer.md deleted file mode 100644 index b13971a..0000000 --- a/lib/openzeppelin-contracts/.changeset/yellow-moles-hammer.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': minor ---- - -`SignatureChecker`: refactor `isValidSignatureNow` to avoid validating ECDSA signatures if there is code deployed at the signer's address. diff --git a/lib/openzeppelin-contracts/.codecov.yml b/lib/openzeppelin-contracts/.codecov.yml deleted file mode 100644 index 5bee914..0000000 --- a/lib/openzeppelin-contracts/.codecov.yml +++ /dev/null @@ -1,15 +0,0 @@ -comment: off -github_checks: - annotations: false -coverage: - status: - patch: - default: - target: 95% - only_pulls: true - project: - default: - threshold: 1% -ignore: - - "test" - - "contracts/mocks" diff --git a/lib/openzeppelin-contracts/.editorconfig b/lib/openzeppelin-contracts/.editorconfig deleted file mode 100644 index f162e8d..0000000 --- a/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/openzeppelin-contracts/.eslintrc b/lib/openzeppelin-contracts/.eslintrc deleted file mode 100644 index a5418c5..0000000 --- a/lib/openzeppelin-contracts/.eslintrc +++ /dev/null @@ -1,20 +0,0 @@ -{ - "root": true, - "extends" : [ - "eslint:recommended", - "prettier", - ], - "env": { - "es2022": true, - "browser": true, - "node": true, - "mocha": true, - }, - "globals" : { - "artifacts": "readonly", - "contract": "readonly", - "web3": "readonly", - "extendEnvironment": "readonly", - "expect": "readonly", - } -} diff --git a/lib/openzeppelin-contracts/.githooks/pre-push b/lib/openzeppelin-contracts/.githooks/pre-push deleted file mode 100755 index a51f388..0000000 --- a/lib/openzeppelin-contracts/.githooks/pre-push +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -if [ "${CI:-"false"}" != "true" ]; then - npm run lint -fi diff --git a/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/bug_report.md b/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 35ad097..0000000 --- a/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/openzeppelin-contracts/.github/ISSUE_TEMPLATE/config.yml b/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index 4018cef..0000000 --- a/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/openzeppelin-contracts/.github/ISSUE_TEMPLATE/feature_request.md b/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index ff596b0..0000000 --- a/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/openzeppelin-contracts/.github/PULL_REQUEST_TEMPLATE.md b/lib/openzeppelin-contracts/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 2394518..0000000 --- a/lib/openzeppelin-contracts/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,20 +0,0 @@ - - - - - -Fixes #???? - - - - - -#### PR Checklist - - - - - -- [ ] Tests -- [ ] Documentation -- [ ] Changeset entry (run `npx changeset add`) diff --git a/lib/openzeppelin-contracts/.github/actions/gas-compare/action.yml b/lib/openzeppelin-contracts/.github/actions/gas-compare/action.yml deleted file mode 100644 index 23a756f..0000000 --- a/lib/openzeppelin-contracts/.github/actions/gas-compare/action.yml +++ /dev/null @@ -1,50 +0,0 @@ -name: Compare gas costs -description: Compare gas costs between branches -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/openzeppelin-contracts/.github/actions/setup/action.yml b/lib/openzeppelin-contracts/.github/actions/setup/action.yml deleted file mode 100644 index b68fec6..0000000 --- a/lib/openzeppelin-contracts/.github/actions/setup/action.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Setup -description: Common environment setup - -runs: - using: composite - steps: - - uses: actions/setup-node@v4 - with: - node-version: 20.x - - uses: actions/cache@v4 - id: cache - with: - path: '**/node_modules' - key: npm-v3-${{ hashFiles('**/package-lock.json') }} - - name: Install dependencies - run: npm ci - shell: bash - if: steps.cache.outputs.cache-hit != 'true' - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly diff --git a/lib/openzeppelin-contracts/.github/actions/storage-layout/action.yml b/lib/openzeppelin-contracts/.github/actions/storage-layout/action.yml deleted file mode 100644 index 573564b..0000000 --- a/lib/openzeppelin-contracts/.github/actions/storage-layout/action.yml +++ /dev/null @@ -1,56 +0,0 @@ -name: Compare storage layouts -description: Compare storage layouts between branches -inputs: - token: - description: github token - required: true - buildinfo: - description: compilation artifacts - required: false - default: artifacts/build-info/*.json - layout: - description: extracted storage layout - required: false - default: HEAD.layout.json - out_layout: - description: storage layout to upload - required: false - default: ${{ github.ref_name }}.layout.json - ref_layout: - description: storage layout for the reference branch - required: false - default: ${{ github.base_ref }}.layout.json - -runs: - using: composite - steps: - - name: Extract layout - run: | - node scripts/checks/extract-layout.js ${{ inputs.buildinfo }} > ${{ inputs.layout }} - shell: bash - - name: Download reference - 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 layout - env: - GITHUB_TOKEN: ${{ inputs.token }} - shell: bash - continue-on-error: true - id: reference - - name: Compare layouts - if: steps.reference.outcome == 'success' && github.event_name == 'pull_request' - run: | - node scripts/checks/compare-layout.js --head ${{ inputs.layout }} --ref ${{ inputs.ref_layout }} - shell: bash - - name: Rename artifacts for upload - if: github.event_name != 'pull_request' - run: | - mv ${{ inputs.layout }} ${{ inputs.out_layout }} - shell: bash - - name: Save artifacts - if: github.event_name != 'pull_request' - uses: actions/upload-artifact@v3 - with: - name: layout - path: ${{ inputs.out_layout }} diff --git a/lib/openzeppelin-contracts/.github/workflows/actionlint.yml b/lib/openzeppelin-contracts/.github/workflows/actionlint.yml deleted file mode 100644 index 3e42c8a..0000000 --- a/lib/openzeppelin-contracts/.github/workflows/actionlint.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: lint workflows - -on: - pull_request: - paths: - - '.github/**/*.ya?ml' - -jobs: - lint: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Add problem matchers - run: | - # https://github.com/rhysd/actionlint/blob/3a2f2c7/docs/usage.md#problem-matchers - curl -LO https://raw.githubusercontent.com/rhysd/actionlint/main/.github/actionlint-matcher.json - echo "::add-matcher::actionlint-matcher.json" - - uses: docker://rhysd/actionlint:latest diff --git a/lib/openzeppelin-contracts/.github/workflows/changeset.yml b/lib/openzeppelin-contracts/.github/workflows/changeset.yml deleted file mode 100644 index efc5c53..0000000 --- a/lib/openzeppelin-contracts/.github/workflows/changeset.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: changeset - -on: - pull_request: - branches: - - master - types: - - opened - - synchronize - - labeled - - unlabeled - -concurrency: - group: changeset-${{ github.ref }} - cancel-in-progress: true - -jobs: - check: - runs-on: ubuntu-latest - if: ${{ !contains(github.event.pull_request.labels.*.name, 'ignore-changeset') }} - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # Include history so Changesets finds merge-base - - name: Set up environment - uses: ./.github/actions/setup - - name: Check changeset - run: npx changeset status --since=origin/${{ github.base_ref }} diff --git a/lib/openzeppelin-contracts/.github/workflows/checks.yml b/lib/openzeppelin-contracts/.github/workflows/checks.yml deleted file mode 100644 index c280885..0000000 --- a/lib/openzeppelin-contracts/.github/workflows/checks.yml +++ /dev/null @@ -1,132 +0,0 @@ -name: checks - -on: - push: - branches: - - master - - next-v* - - release-v* - pull_request: {} - workflow_dispatch: {} - -concurrency: - group: checks-${{ github.ref }} - cancel-in-progress: true - -env: - NODE_OPTIONS: --max_old_space_size=8192 - -jobs: - lint: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up environment - uses: ./.github/actions/setup - - run: npm run lint - - tests: - runs-on: ubuntu-latest - env: - FORCE_COLOR: 1 - # Needed for "eth-gas-reporter" to produce a "gasReporterOutput.json" as documented in - # https://github.com/cgewecke/eth-gas-reporter/blob/v0.2.27/docs/gasReporterOutput.md - CI: true - GAS: true - steps: - - uses: actions/checkout@v4 - - 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 - run: npm run test:generation - - name: Compare gas costs - uses: ./.github/actions/gas-compare - with: - token: ${{ github.token }} - - tests-upgradeable: - runs-on: ubuntu-latest - env: - FORCE_COLOR: 1 - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # Include history so patch conflicts are resolved automatically - - name: Set up environment - uses: ./.github/actions/setup - - name: Copy non-upgradeable contracts as dependency - run: | - mkdir -p lib/openzeppelin-contracts - cp -rnT contracts lib/openzeppelin-contracts/contracts - - name: Transpile to upgradeable - run: bash scripts/upgradeable/transpile.sh - - name: Run tests - run: npm run test - - name: Check linearisation of the inheritance graph - run: npm run test:inheritance - - name: Check storage layout - uses: ./.github/actions/storage-layout - continue-on-error: ${{ contains(github.event.pull_request.labels.*.name, 'breaking change') }} - with: - token: ${{ github.token }} - - tests-foundry: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - submodules: recursive - - name: Set up environment - uses: ./.github/actions/setup - - name: Run tests - run: forge test -vv - - coverage: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up environment - uses: ./.github/actions/setup - - name: Run coverage - run: npm run coverage - - uses: codecov/codecov-action@v4 - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - - harnesses: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up environment - uses: ./.github/actions/setup - - name: Compile harnesses - run: | - make -C certora apply - npm run compile:harnesses - - slither: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up environment - uses: ./.github/actions/setup - - run: rm foundry.toml - - uses: crytic/slither-action@v0.4.0 - with: - node-version: 18.15 - slither-version: 0.10.1 - - codespell: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Run CodeSpell - uses: codespell-project/actions-codespell@v2.0 - with: - check_hidden: true - check_filenames: true - skip: package-lock.json,*.pdf diff --git a/lib/openzeppelin-contracts/.github/workflows/docs.yml b/lib/openzeppelin-contracts/.github/workflows/docs.yml deleted file mode 100644 index 04b8131..0000000 --- a/lib/openzeppelin-contracts/.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@v4 - - 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/openzeppelin-contracts/.github/workflows/formal-verification.yml b/lib/openzeppelin-contracts/.github/workflows/formal-verification.yml deleted file mode 100644 index 517ec55..0000000 --- a/lib/openzeppelin-contracts/.github/workflows/formal-verification.yml +++ /dev/null @@ -1,86 +0,0 @@ -name: formal verification - -on: - pull_request: - types: - - opened - - reopened - - synchronize - - labeled - workflow_dispatch: {} - -env: - PIP_VERSION: '3.10' - JAVA_VERSION: '11' - SOLC_VERSION: '0.8.20' - -concurrency: ${{ github.workflow }}-${{ github.ref }} - -jobs: - apply-diff: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Apply patches - run: make -C certora apply - - verify: - runs-on: ubuntu-latest - if: github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'formal-verification') - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Set up environment - uses: ./.github/actions/setup - - name: identify specs that need to be run - id: arguments - run: | - if [[ ${{ github.event_name }} = 'pull_request' ]]; - then - RESULT=$(git diff ${{ github.event.pull_request.head.sha }}..${{ github.event.pull_request.base.sha }} --name-only certora/specs/*.spec | while IFS= read -r file; do [[ -f $file ]] && basename "${file%.spec}"; done | tr "\n" " ") - else - RESULT='--all' - fi - echo "result=$RESULT" >> "$GITHUB_OUTPUT" - - name: Install python - uses: actions/setup-python@v5 - with: - python-version: ${{ env.PIP_VERSION }} - cache: 'pip' - cache-dependency-path: 'fv-requirements.txt' - - name: Install python packages - run: pip install -r fv-requirements.txt - - name: Install java - uses: actions/setup-java@v3 - with: - distribution: temurin - java-version: ${{ env.JAVA_VERSION }} - - name: Install solc - run: | - wget https://github.com/ethereum/solidity/releases/download/v${{ env.SOLC_VERSION }}/solc-static-linux - sudo mv solc-static-linux /usr/local/bin/solc - chmod +x /usr/local/bin/solc - - name: Verify specification - run: | - make -C certora apply - node certora/run.js ${{ steps.arguments.outputs.result }} >> "$GITHUB_STEP_SUMMARY" - env: - CERTORAKEY: ${{ secrets.CERTORAKEY }} - - halmos: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up environment - uses: ./.github/actions/setup - - name: Install python - uses: actions/setup-python@v5 - with: - python-version: ${{ env.PIP_VERSION }} - cache: 'pip' - cache-dependency-path: 'fv-requirements.txt' - - name: Install python packages - run: pip install -r fv-requirements.txt - - name: Run Halmos - run: halmos --match-test '^symbolic|^testSymbolic' -vv diff --git a/lib/openzeppelin-contracts/.github/workflows/release-cycle.yml b/lib/openzeppelin-contracts/.github/workflows/release-cycle.yml deleted file mode 100644 index fc12955..0000000 --- a/lib/openzeppelin-contracts/.github/workflows/release-cycle.yml +++ /dev/null @@ -1,212 +0,0 @@ -# D: Manual Dispatch -# M: Merge release PR -# C: Commit -# ┌───────────┐ ┌─────────────┐ ┌────────────────┐ -# │Development├──D──►RC-Unreleased│ ┌──►Final-Unreleased│ -# └───────────┘ └─┬─────────▲─┘ │ └─┬────────────▲─┘ -# │ │ │ │ │ -# M C D M C -# │ │ │ │ │ -# ┌▼─────────┴┐ │ ┌▼────────────┴┐ -# │RC-Released├───┘ │Final-Released│ -# └───────────┘ └──────────────┘ -name: Release Cycle - -on: - push: - branches: - - release-v* - workflow_dispatch: {} - -concurrency: ${{ github.workflow }}-${{ github.ref }} - -jobs: - state: - name: Check state - permissions: - pull-requests: read - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up environment - uses: ./.github/actions/setup - - id: state - name: Get state - uses: actions/github-script@v7 - env: - TRIGGERING_ACTOR: ${{ github.triggering_actor }} - with: - result-encoding: string - script: await require('./scripts/release/workflow/state.js')({ github, context, core }) - outputs: - # Job Flags - start: ${{ steps.state.outputs.start }} - changesets: ${{ steps.state.outputs.changesets }} - promote: ${{ steps.state.outputs.promote }} - publish: ${{ steps.state.outputs.publish }} - merge: ${{ steps.state.outputs.merge }} - - # Global variables - is_prerelease: ${{ steps.state.outputs.is_prerelease }} - - start: - needs: state - name: Start new release candidate - permissions: - contents: write - actions: write - if: needs.state.outputs.start == 'true' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up environment - uses: ./.github/actions/setup - - run: bash scripts/git-user-config.sh - - id: start - name: Create branch with release candidate - run: bash scripts/release/workflow/start.sh - - name: Re-run workflow - uses: actions/github-script@v7 - env: - REF: ${{ steps.start.outputs.branch }} - with: - script: await require('./scripts/release/workflow/rerun.js')({ github, context }) - - promote: - needs: state - name: Promote to final release - permissions: - contents: write - actions: write - if: needs.state.outputs.promote == 'true' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up environment - uses: ./.github/actions/setup - - run: bash scripts/git-user-config.sh - - name: Exit prerelease state - if: needs.state.outputs.is_prerelease == 'true' - run: bash scripts/release/workflow/exit-prerelease.sh - - name: Re-run workflow - uses: actions/github-script@v7 - with: - script: await require('./scripts/release/workflow/rerun.js')({ github, context }) - - changesets: - needs: state - name: Update PR to release - permissions: - contents: write - pull-requests: write - if: needs.state.outputs.changesets == 'true' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # To get all tags - - name: Set up environment - uses: ./.github/actions/setup - - name: Set release title - uses: actions/github-script@v7 - with: - result-encoding: string - script: await require('./scripts/release/workflow/set-changesets-pr-title.js')({ core }) - - name: Create PR - uses: changesets/action@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PRERELEASE: ${{ needs.state.outputs.is_prerelease }} - with: - version: npm run version - title: ${{ env.TITLE }} - commit: ${{ env.TITLE }} - body: | # Wait for support on this https://github.com/changesets/action/pull/250 - This is an automated PR for releasing ${{ github.repository }} - Check [CHANGELOG.md](${{ github.repository }}/CHANGELOG.md) - - publish: - needs: state - name: Publish to npm - environment: npm - permissions: - contents: write - if: needs.state.outputs.publish == 'true' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up environment - uses: ./.github/actions/setup - - id: pack - name: Pack - run: bash scripts/release/workflow/pack.sh - env: - PRERELEASE: ${{ needs.state.outputs.is_prerelease }} - - name: Upload tarball artifact - uses: actions/upload-artifact@v4 - with: - name: ${{ github.ref_name }} - path: ${{ steps.pack.outputs.tarball }} - - name: Publish - run: bash scripts/release/workflow/publish.sh - env: - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - TARBALL: ${{ steps.pack.outputs.tarball }} - TAG: ${{ steps.pack.outputs.tag }} - - name: Create Github Release - uses: actions/github-script@v7 - env: - PRERELEASE: ${{ needs.state.outputs.is_prerelease }} - with: - script: await require('./scripts/release/workflow/github-release.js')({ github, context }) - outputs: - tarball_name: ${{ steps.pack.outputs.tarball_name }} - - integrity_check: - needs: publish - name: Tarball Integrity Check - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Download tarball artifact - id: artifact - uses: actions/download-artifact@v4 - with: - name: ${{ github.ref_name }} - - name: Check integrity - run: bash scripts/release/workflow/integrity-check.sh - env: - TARBALL: ${{ steps.artifact.outputs.download-path }}/${{ needs.publish.outputs.tarball_name }} - - merge: - needs: state - name: Create PR back to master - permissions: - contents: write - pull-requests: write - if: needs.state.outputs.merge == 'true' - runs-on: ubuntu-latest - env: - MERGE_BRANCH: merge/${{ github.ref_name }} - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # All branches - - name: Set up environment - uses: ./.github/actions/setup - - run: bash scripts/git-user-config.sh - - name: Create branch to merge - run: | - git checkout -B "$MERGE_BRANCH" "$GITHUB_REF_NAME" - git push -f origin "$MERGE_BRANCH" - - name: Create PR back to master - uses: actions/github-script@v7 - with: - script: | - await github.rest.pulls.create({ - owner: context.repo.owner, - repo: context.repo.repo, - head: process.env.MERGE_BRANCH, - base: 'master', - title: '${{ format('Merge {0} branch', github.ref_name) }}' - }); diff --git a/lib/openzeppelin-contracts/.github/workflows/upgradeable.yml b/lib/openzeppelin-contracts/.github/workflows/upgradeable.yml deleted file mode 100644 index 46bf15a..0000000 --- a/lib/openzeppelin-contracts/.github/workflows/upgradeable.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: transpile upgradeable - -on: - push: - branches: - - master - - release-v* - -jobs: - transpile: - environment: push-upgradeable - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - repository: OpenZeppelin/openzeppelin-contracts-upgradeable - fetch-depth: 0 - token: ${{ secrets.GH_TOKEN_UPGRADEABLE }} - - name: Fetch current non-upgradeable branch - run: | - git fetch "$REMOTE" master # Fetch default branch first for patch to apply cleanly - git fetch "$REMOTE" "$REF" - git checkout FETCH_HEAD - env: - REF: ${{ github.ref }} - REMOTE: https://github.com/${{ github.repository }}.git - - name: Set up environment - uses: ./.github/actions/setup - - run: bash scripts/git-user-config.sh - - name: Transpile to upgradeable - run: bash scripts/upgradeable/transpile-onto.sh ${{ github.ref_name }} origin/${{ github.ref_name }} - env: - SUBMODULE_REMOTE: https://github.com/${{ github.repository }}.git - - run: git push origin ${{ github.ref_name }} diff --git a/lib/openzeppelin-contracts/.gitignore b/lib/openzeppelin-contracts/.gitignore deleted file mode 100644 index b2b1eab..0000000 --- a/lib/openzeppelin-contracts/.gitignore +++ /dev/null @@ -1,66 +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 - -# macOS -.DS_Store - -# 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 - -# hardat-exposed -contracts-exposed - -# Hardhat -/cache -/artifacts - -# Foundry -/out -/cache_forge - -# Certora -.certora* -.last_confs -certora_* -.zip-output-url.txt diff --git a/lib/openzeppelin-contracts/.gitmodules b/lib/openzeppelin-contracts/.gitmodules deleted file mode 100644 index 4939cd2..0000000 --- a/lib/openzeppelin-contracts/.gitmodules +++ /dev/null @@ -1,10 +0,0 @@ -[submodule "lib/forge-std"] - branch = v1 - path = lib/forge-std - url = https://github.com/foundry-rs/forge-std -[submodule "lib/erc4626-tests"] - path = lib/erc4626-tests - url = https://github.com/a16z/erc4626-tests.git -[submodule "lib/halmos-cheatcodes"] - path = lib/halmos-cheatcodes - url = https://github.com/a16z/halmos-cheatcodes diff --git a/lib/openzeppelin-contracts/.mocharc.js b/lib/openzeppelin-contracts/.mocharc.js deleted file mode 100644 index 920662d..0000000 --- a/lib/openzeppelin-contracts/.mocharc.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - require: 'hardhat/register', - timeout: 4000, -}; diff --git a/lib/openzeppelin-contracts/.prettierrc b/lib/openzeppelin-contracts/.prettierrc deleted file mode 100644 index 39c004c..0000000 --- a/lib/openzeppelin-contracts/.prettierrc +++ /dev/null @@ -1,15 +0,0 @@ -{ - "printWidth": 120, - "singleQuote": true, - "trailingComma": "all", - "arrowParens": "avoid", - "overrides": [ - { - "files": "*.sol", - "options": { - "singleQuote": false - } - } - ], - "plugins": ["prettier-plugin-solidity"] -} diff --git a/lib/openzeppelin-contracts/.solcover.js b/lib/openzeppelin-contracts/.solcover.js deleted file mode 100644 index e0dea5e..0000000 --- a/lib/openzeppelin-contracts/.solcover.js +++ /dev/null @@ -1,13 +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/openzeppelin-contracts/CHANGELOG.md b/lib/openzeppelin-contracts/CHANGELOG.md deleted file mode 100644 index f327a1c..0000000 --- a/lib/openzeppelin-contracts/CHANGELOG.md +++ /dev/null @@ -1,1037 +0,0 @@ -# Changelog - -### Breaking changes - -- `ERC1967Utils`: Removed duplicate declaration of the `Upgraded`, `AdminChanged` and `BeaconUpgraded` events. These events are still available through the `IERC1967` interface located under the `contracts/interfaces/` directory. Minimum pragma version is now 0.8.21. -- `Governor`, `GovernorCountingSimple`: The `_countVotes` virtual function now returns an `uint256` with the total votes casted. This change allows for more flexibility for partial and fractional voting. Upgrading users may get a compilation error that can be fixed by adding a return statement to the `_countVotes` function. - -### Custom error changes - -This version comes with changes to the custom error identifiers. Contracts previously depending on the following errors should be replaced accordingly: - -- Replace `Address.FailedInnerCall` with `Errors.FailedCall` -- Replace `Address.AddressInsufficientBalance` with `Errors.InsufficientBalance` -- Replace `Clones.Create2InsufficientBalance` with `Errors.InsufficientBalance` -- Replace `Clones.ERC1167FailedCreateClone` with `Errors.FailedDeployment` -- Replace `Clones.Create2FailedDeployment` with `Errors.FailedDeployment` -- `SafeERC20`: Replace `Address.AddressEmptyCode` with `SafeERC20FailedOperation` if there is no code at the token's address. -- `SafeERC20`: Replace generic `Error(string)` with `SafeERC20FailedOperation` if the returned data can't be decoded as `bool`. -- `SafeERC20`: Replace generic `SafeERC20FailedOperation` with the revert message from the contract call if it fails. - -## 5.0.2 (2024-02-29) - -- `Base64`: Fix issue where dirty memory located just after the input buffer is affecting the result. ([#4926](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4926)) - -## 5.0.1 (2023-12-07) - -- `ERC2771Context` and `Context`: Introduce a `_contextPrefixLength()` getter, used to trim extra information appended to `msg.data`. -- `Multicall`: Make aware of non-canonical context (i.e. `msg.sender` is not `_msgSender()`), allowing compatibility with `ERC2771Context`. - -## 5.0.0 (2023-10-05) - -### Additions Summary - -The following contracts and libraries were added: - -- `AccessManager`: A consolidated system for managing access control in complex systems. - - `AccessManaged`: A module for connecting a contract to an authority in charge of its access control. - - `GovernorTimelockAccess`: An adapter for time-locking governance proposals using an `AccessManager`. - - `AuthorityUtils`: A library of utilities for interacting with authority contracts. -- `GovernorStorage`: A Governor module that stores proposal details in storage. -- `ERC2771Forwarder`: An ERC2771 forwarder for meta transactions. -- `ERC1967Utils`: A library with ERC1967 events, errors and getters. -- `Nonces`: An abstraction for managing account nonces. -- `MessageHashUtils`: A library for producing digests for ECDSA operations. -- `Time`: A library with helpers for manipulating time-related objects. - -### Removals Summary - -The following contracts, libraries, and functions were removed: - -- `Address.isContract` (because of its ambiguous nature and potential for misuse) -- `Checkpoints.History` -- `Counters` -- `ERC20Snapshot` -- `ERC20VotesComp` -- `ERC165Storage` (in favor of inheritance based approach) -- `ERC777` -- `ERC1820Implementer` -- `GovernorVotesComp` -- `GovernorProposalThreshold` (deprecated since 4.4) -- `PaymentSplitter` -- `PullPayment` -- `SafeMath` -- `SignedSafeMath` -- `Timers` -- `TokenTimelock` (in favor of `VestingWallet`) -- All escrow contracts (`Escrow`, `ConditionalEscrow` and `RefundEscrow`) -- All cross-chain contracts, including `AccessControlCrossChain` and all the vendored bridge interfaces -- All presets in favor of [OpenZeppelin Contracts Wizard](https://wizard.openzeppelin.com/) - -These removals were implemented in the following PRs: [#3637](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3637), [#3880](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3880), [#3945](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3945), [#4258](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4258), [#4276](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4276), [#4289](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4289) - -### Changes by category - -#### General - -- Replaced revert strings and require statements with custom errors. ([#4261](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4261)) -- Bumped minimum compiler version required to 0.8.20 ([#4288](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4288), [#4489](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4489)) -- Use of `abi.encodeCall` in place of `abi.encodeWithSelector` and `abi.encodeWithSignature` for improved type-checking of parameters ([#4293](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4293)) -- Replaced some uses of `abi.encodePacked` with clearer alternatives (e.g. `bytes.concat`, `string.concat`). ([#4504](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4504)) ([#4296](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4296)) -- Overrides are now used internally for a number of functions that were previously hardcoded to their default implementation in certain locations: `ERC1155Supply.totalSupply`, `ERC721.ownerOf`, `ERC721.balanceOf` and `ERC721.totalSupply` in `ERC721Enumerable`, `ERC20.totalSupply` in `ERC20FlashMint`, and `ERC1967._getImplementation` in `ERC1967Proxy`. ([#4299](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4299)) -- Removed the `override` specifier from functions that only override a single interface function. ([#4315](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4315)) -- Switched to using explicit Solidity import statements. Some previously available symbols may now have to be separately imported. ([#4399](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4399)) -- `Governor`, `Initializable`, and `UUPSUpgradeable`: Use internal functions in modifiers to optimize bytecode size. ([#4472](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4472)) -- Upgradeable contracts now use namespaced storage (EIP-7201). ([#4534](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4534)) -- Upgradeable contracts no longer transpile interfaces and libraries. ([#4628](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4628)) - -#### Access - -- `Ownable`: Added an `initialOwner` parameter to the constructor, making the ownership initialization explicit. ([#4267](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4267)) -- `Ownable`: Prevent using address(0) as the initial owner. ([#4531](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4531)) -- `AccessControl`: Added a boolean return value to the internal `_grantRole` and `_revokeRole` functions indicating whether the role was granted or revoked. ([#4241](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4241)) -- `access`: Moved `AccessControl` extensions to a dedicated directory. ([#4359](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4359)) -- `AccessManager`: Added a new contract for managing access control of complex systems in a consolidated location. ([#4121](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4121)) -- `AccessManager`, `AccessManaged`, `GovernorTimelockAccess`: Ensure that calldata shorter than 4 bytes is not padded to 4 bytes. ([#4624](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4624)) -- `AccessManager`: Use named return parameters in functions that return multiple values. ([#4624](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4624)) -- `AccessManager`: Make `schedule` and `execute` more conservative when delay is 0. ([#4644](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4644)) - -#### Finance - -- `VestingWallet`: Fixed revert during 1 second time window when duration is 0. ([#4502](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4502)) -- `VestingWallet`: Use `Ownable` instead of an immutable `beneficiary`. ([#4508](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4508)) - -#### Governance - -- `Governor`: Optimized use of storage for proposal data ([#4268](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4268)) -- `Governor`: Added validation in ERC1155 and ERC721 receiver hooks to ensure Governor is the executor. ([#4314](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4314)) -- `Governor`: Refactored internals to implement common queuing logic in the core module of the Governor. Added `queue` and `_queueOperations` functions that act at different levels. Modules that implement queuing via timelocks are expected to override `_queueOperations` to implement the timelock-specific logic. Added `_executeOperations` as the equivalent for execution. ([#4360](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4360)) -- `Governor`: Added `voter` and `nonce` parameters in signed ballots, to avoid forging signatures for random addresses, prevent signature replay, and allow invalidating signatures. Add `voter` as a new parameter in the `castVoteBySig` and `castVoteWithReasonAndParamsBySig` functions. ([#4378](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4378)) -- `Governor`: Added support for casting votes with ERC-1271 signatures by using a `bytes memory signature` instead of `r`, `s` and `v` arguments in the `castVoteBySig` and `castVoteWithReasonAndParamsBySig` functions. ([#4418](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4418)) -- `Governor`: Added a mechanism to restrict the address of the proposer using a suffix in the description. -- `GovernorStorage`: Added a new governor extension that stores the proposal details in storage, with an interface that operates on `proposalId`, as well as proposal enumerability. This replaces the old `GovernorCompatibilityBravo` module. ([#4360](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4360)) -- `GovernorTimelockAccess`: Added a module to connect a governor with an instance of `AccessManager`, allowing the governor to make calls that are delay-restricted by the manager using the normal `queue` workflow. ([#4523](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4523)) -- `GovernorTimelockControl`: Clean up timelock id on execution for gas refund. ([#4118](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4118)) -- `GovernorTimelockControl`: Added the Governor instance address as part of the TimelockController operation `salt` to avoid operation id collisions between governors using the same TimelockController. ([#4432](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4432)) -- `TimelockController`: Changed the role architecture to use `DEFAULT_ADMIN_ROLE` as the admin for all roles, instead of the bespoke `TIMELOCK_ADMIN_ROLE` that was used previously. This aligns with the general recommendation for `AccessControl` and makes the addition of new roles easier. Accordingly, the `admin` parameter and timelock will now be granted `DEFAULT_ADMIN_ROLE` instead of `TIMELOCK_ADMIN_ROLE`. ([#3799](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3799)) -- `TimelockController`: Added a state getter that returns an `OperationState` enum. ([#4358](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4358)) -- `Votes`: Use Trace208 for checkpoints. This enables EIP-6372 clock support for keys but reduces the max supported voting power to uint208. ([#4539](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4539)) - -#### Metatx - -- `ERC2771Forwarder`: Added `deadline` for expiring transactions, batching, and more secure handling of `msg.value`. ([#4346](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4346)) -- `ERC2771Context`: Return the forwarder address whenever the `msg.data` of a call originating from a trusted forwarder is not long enough to contain the request signer address (i.e. `msg.data.length` is less than 20 bytes), as specified by ERC-2771. ([#4481](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4481)) -- `ERC2771Context`: Prevent revert in `_msgData()` when a call originating from a trusted forwarder is not long enough to contain the request signer address (i.e. `msg.data.length` is less than 20 bytes). Return the full calldata in that case. ([#4484](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4484)) - -#### Proxy - -- `ProxyAdmin`: Removed `getProxyAdmin` and `getProxyImplementation` getters. ([#3820](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3820)) -- `TransparentUpgradeableProxy`: Removed `admin` and `implementation` getters, which were only callable by the proxy owner and thus not very useful. ([#3820](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3820)) -- `ERC1967Utils`: Refactored the `ERC1967Upgrade` abstract contract as a library. ([#4325](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4325)) -- `TransparentUpgradeableProxy`: Admin is now stored in an immutable variable (set during construction) to avoid unnecessary storage reads on every proxy call. This removed the ability to ever change the admin. Transfer of the upgrade capability is exclusively handled through the ownership of the `ProxyAdmin`. ([#4354](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4354)) -- Moved the logic to validate ERC-1822 during an upgrade from `ERC1967Utils` to `UUPSUpgradeable`. ([#4356](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4356)) -- `UUPSUpgradeable`, `TransparentUpgradeableProxy` and `ProxyAdmin`: Removed `upgradeTo` and `upgrade` functions, and made `upgradeToAndCall` and `upgradeAndCall` ignore the data argument if it is empty. It is no longer possible to invoke the receive function (or send value with empty data) along with an upgrade. ([#4382](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4382)) -- `BeaconProxy`: Reject value in initialization unless a payable function is explicitly invoked. ([#4382](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4382)) -- `Proxy`: Removed redundant `receive` function. ([#4434](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4434)) -- `BeaconProxy`: Use an immutable variable to store the address of the beacon. It is no longer possible for a `BeaconProxy` to upgrade by changing to another beacon. ([#4435](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4435)) -- `Initializable`: Use the namespaced storage pattern to avoid putting critical variables in slot 0. Allow reinitializer versions greater than 256. ([#4460](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4460)) -- `Initializable`: Use intermediate variables to improve readability. ([#4576](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4576)) - -#### Token - -- `ERC20`, `ERC721`, `ERC1155`: Deleted `_beforeTokenTransfer` and `_afterTokenTransfer` hooks, added a new internal `_update` function for customizations, and refactored all extensions using those hooks to use `_update` instead. ([#3838](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3838), [#3876](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3876), [#4377](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4377)) -- `ERC20`: Removed `Approval` event previously emitted in `transferFrom` to indicate that part of the allowance was consumed. With this change, allowances are no longer reconstructible from events. See the code for guidelines on how to re-enable this event if needed. ([#4370](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4370)) -- `ERC20`: Removed the non-standard `increaseAllowance` and `decreaseAllowance` functions. ([#4585](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4585)) -- `ERC20Votes`: Changed internal vote accounting to reusable `Votes` module previously used by `ERC721Votes`. Removed implicit `ERC20Permit` inheritance. Note that the `DOMAIN_SEPARATOR` getter was previously guaranteed to be available for `ERC20Votes` contracts, but is no longer available unless `ERC20Permit` is explicitly used; ERC-5267 support is included in `ERC20Votes` with `EIP712` and is recommended as an alternative. ([#3816](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3816)) -- `SafeERC20`: Refactored `safeDecreaseAllowance` and `safeIncreaseAllowance` to support USDT-like tokens. ([#4260](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4260)) -- `SafeERC20`: Removed `safePermit` in favor of documentation-only `permit` recommendations. Based on recommendations from @trust1995 ([#4582](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4582)) -- `ERC721`: `_approve` no longer allows approving the owner of the tokenId. ([#4377](https://github.com/OpenZeppelin/openzeppelin-contracts/issues/4377)) `_setApprovalForAll` no longer allows setting address(0) as an operator. ([#4377](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4377)) -- `ERC721`: Renamed `_requireMinted` to `_requireOwned` and added a return value with the current owner. Implemented `ownerOf` in terms of `_requireOwned`. ([#4566](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4566)) -- `ERC721Consecutive`: Added a `_firstConsecutiveId` internal function that can be overridden to change the id of the first token minted through `_mintConsecutive`. ([#4097](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4097)) -- `ERC721URIStorage`: Allow setting the token URI prior to minting. ([#4559](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4559)) -- `ERC721URIStorage`, `ERC721Royalty`: Stop resetting token-specific URI and royalties when burning. ([#4561](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4561)) -- `ERC1155`: Optimized array allocation. ([#4196](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4196)) -- `ERC1155`: Removed check for address zero in `balanceOf`. ([#4263](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4263)) -- `ERC1155`: Optimized array accesses by skipping bounds checking when unnecessary. ([#4300](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4300)) -- `ERC1155`: Bubble errors triggered in the `onERC1155Received` and `onERC1155BatchReceived` hooks. ([#4314](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4314)) -- `ERC1155Supply`: Added a `totalSupply()` function that returns the total amount of token circulating, this change will restrict the total tokens minted across all ids to 2\*\*256-1 . ([#3962](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3962)) -- `ERC1155Receiver`: Removed in favor of `ERC1155Holder`. ([#4450](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4450)) - -#### Utils - -- `Address`: Removed the ability to customize error messages. A common custom error is always used if the underlying revert reason cannot be bubbled up. ([#4502](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4502)) -- `Arrays`: Added `unsafeMemoryAccess` helpers to read from a memory array without checking the length. ([#4300](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4300)) -- `Arrays`: Optimized `findUpperBound` by removing redundant SLOAD. ([#4442](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4442)) -- `Checkpoints`: Library moved from `utils` to `utils/structs` ([#4275](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4275)) -- `DoubleEndedQueue`: Refactored internal structure to use `uint128` instead of `int128`. This has no effect on the library interface. ([#4150](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4150)) -- `ECDSA`: Use unchecked arithmetic for the `tryRecover` function that receives the `r` and `vs` short-signature fields separately. ([#4301](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4301)) -- `EIP712`: Added internal getters for the name and version strings ([#4303](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4303)) -- `Math`: Makes `ceilDiv` to revert on 0 division even if the numerator is 0 ([#4348](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4348)) -- `Math`: Optimized stack operations in `mulDiv`. ([#4494](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4494)) -- `Math`: Renamed members of `Rounding` enum, and added a new rounding mode for "away from zero". ([#4455](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4455)) -- `MerkleProof`: Use custom error to report invalid multiproof instead of reverting with overflow panic. ([#4564](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4564)) -- `MessageHashUtils`: Added a new library for creating message digest to be used along with signing or recovery such as ECDSA or ERC-1271. These functions are moved from the `ECDSA` library. ([#4430](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4430)) -- `Nonces`: Added a new contract to keep track of user nonces. Used for signatures in `ERC20Permit`, `ERC20Votes`, and `ERC721Votes`. ([#3816](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3816)) -- `ReentrancyGuard`, `Pausable`: Moved to `utils` directory. ([#4551](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4551)) -- `Strings`: Renamed `toString(int256)` to `toStringSigned(int256)`. ([#4330](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4330)) -- Optimized `Strings.equal` ([#4262](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4262)) - -### How to migrate from 4.x - -#### ERC20, ERC721, and ERC1155 - -These breaking changes will require modifications to ERC20, ERC721, and ERC1155 contracts, since the `_afterTokenTransfer` and `_beforeTokenTransfer` functions were removed. Thus, any customization made through those hooks should now be done overriding the new `_update` function instead. - -Minting and burning are implemented by `_update` and customizations should be done by overriding this function as well. `_transfer`, `_mint` and `_burn` are no longer virtual (meaning they are not overridable) to guard against possible inconsistencies. - -For example, a contract using `ERC20`'s `_beforeTokenTransfer` hook would have to be changed in the following way. - -```diff --function _beforeTokenTransfer( -+function _update( - address from, - address to, - uint256 amount - ) internal virtual override { -- super._beforeTokenTransfer(from, to, amount); - require(!condition(), "ERC20: wrong condition"); -+ super._update(from, to, amount); - } -``` - -#### More about ERC721 - -In the case of `ERC721`, the `_update` function does not include a `from` parameter, as the sender is implicitly the previous owner of the `tokenId`. The address of this previous owner is returned by the `_update` function, so it can be used for a posteriori checks. In addition to `to` and `tokenId`, a third parameter (`auth`) is present in this function. This parameter enabled an optional check that the caller/spender is approved to do the transfer. This check cannot be performed after the transfer (because the transfer resets the approval), and doing it before `_update` would require a duplicate call to `_ownerOf`. - -In this logic of removing hidden SLOADs, the `_isApprovedOrOwner` function was removed in favor of a new `_isAuthorized` function. Overrides that used to target the `_isApprovedOrOwner` should now be performed on the `_isAuthorized` function. Calls to `_isApprovedOrOwner` that preceded a call to `_transfer`, `_burn` or `_approve` should be removed in favor of using the `auth` argument in `_update` and `_approve`. This is showcased in `ERC721Burnable.burn` and in `ERC721Wrapper.withdrawTo`. - -The `_exists` function was removed. Calls to this function can be replaced by `_ownerOf(tokenId) != address(0)`. - -#### More about ERC1155 - -Batch transfers will now emit `TransferSingle` if the batch consists of a single token, while in previous versions the `TransferBatch` event would be used for all transfers initiated through `safeBatchTransferFrom`. Both behaviors are compliant with the ERC-1155 specification. - -#### ERC165Storage - -Users that were registering EIP-165 interfaces with `_registerInterface` from `ERC165Storage` should instead do so by overriding the `supportsInterface` function as seen below: - -```solidity -function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { - return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); -} -``` - -#### SafeMath - -Methods in SafeMath superseded by native overflow checks in Solidity 0.8.0 were removed along with operations providing an interface for revert strings. The remaining methods were moved to `utils/Math.sol`. - -```diff -- import "@openzeppelin/contracts/utils/math/SafeMath.sol"; -+ import "@openzeppelin/contracts/utils/math/Math.sol"; - - function tryOperations(uint256 x, uint256 y) external view { -- (bool overflowsAdd, uint256 resultAdd) = SafeMath.tryAdd(x, y); -+ (bool overflowsAdd, uint256 resultAdd) = Math.tryAdd(x, y); -- (bool overflowsSub, uint256 resultSub) = SafeMath.trySub(x, y); -+ (bool overflowsSub, uint256 resultSub) = Math.trySub(x, y); -- (bool overflowsMul, uint256 resultMul) = SafeMath.tryMul(x, y); -+ (bool overflowsMul, uint256 resultMul) = Math.tryMul(x, y); -- (bool overflowsDiv, uint256 resultDiv) = SafeMath.tryDiv(x, y); -+ (bool overflowsDiv, uint256 resultDiv) = Math.tryDiv(x, y); - // ... - } -``` - -#### Adapting Governor modules - -Custom Governor modules that override internal functions may require modifications if migrated to v5. In particular, the new internal functions `_queueOperations` and `_executeOperations` may need to be used. If assistance with this migration is needed reach out via the [OpenZeppelin Support Forum](https://forum.openzeppelin.com/c/support/contracts/18). - -#### ECDSA and MessageHashUtils - -The `ECDSA` library is now focused on signer recovery. Previously it also included utility methods for producing digests to be used with signing or recovery. These utilities have been moved to the `MessageHashUtils` library and should be imported if needed: - -```diff - import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -+import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; - - contract Verifier { - using ECDSA for bytes32; -+ using MessageHashUtils for bytes32; - - function _verify(bytes32 data, bytes memory signature, address account) internal pure returns (bool) { - return data - .toEthSignedMessageHash() - .recover(signature) == account; - } - } -``` - -#### Interfaces and libraries in upgradeable contracts - -The upgradeable version of the contracts library used to include a variant suffixed with `Upgradeable` for every contract. These variants, which are produced automatically, mainly include changes for dealing with storage that don't apply to libraries and interfaces. - -The upgradeable library no longer includes upgradeable variants for libraries and interfaces. Projects migrating to 5.0 should replace their library and interface imports with their corresponding non-upgradeable version: - -```diff - // Libraries --import {AddressUpgradeable} from '@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol'; -+import {Address} from '@openzeppelin/contracts/utils/Address.sol'; - - // Interfaces --import {IERC20Upgradeable} from '@openzeppelin/contracts-upgradeable/interfaces/IERC20.sol'; -+import {IERC20} from '@openzeppelin/contracts/interfaces/IERC20.sol'; -``` - -#### Offchain Considerations - -Some changes may affect offchain systems if they rely on assumptions that are changed along with these new breaking changes. These cases are: - -##### Relying on revert strings for processing errors - -A concrete example is AccessControl, where it was previously advised to catch revert reasons using the following regex: - -``` -/^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ -``` - -Instead, contracts now revert with custom errors. Systems that interact with smart contracts outside of the network should consider reliance on revert strings and possibly support the new custom errors. - -##### Relying on storage locations for retrieving data - -After 5.0, the storage location of some variables were changed. This is the case for `Initializable` and all the upgradeable contracts since they now use namespaced storaged locations. Any system relying on storage locations for retrieving data or detecting capabilities should be updated to support these new locations. - -## 4.9.6 (2024-02-29) - -- `Base64`: Fix issue where dirty memory located just after the input buffer is affecting the result. ([#4929](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4929)) - -## 4.9.5 (2023-12-08) - -- `Multicall`: Make aware of non-canonical context (i.e. `msg.sender` is not `_msgSender()`), allowing compatibility with `ERC2771Context`. Patch duplicated `Address.functionDelegateCall` in v4.9.4 (removed). - -## 4.9.3 (2023-07-28) - -- `ERC2771Context`: Return the forwarder address whenever the `msg.data` of a call originating from a trusted forwarder is not long enough to contain the request signer address (i.e. `msg.data.length` is less than 20 bytes), as specified by ERC-2771. ([#4481](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4481)) -- `ERC2771Context`: Prevent revert in `_msgData()` when a call originating from a trusted forwarder is not long enough to contain the request signer address (i.e. `msg.data.length` is less than 20 bytes). Return the full calldata in that case. ([#4484](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4484)) - -## 4.9.2 (2023-06-16) - -- `MerkleProof`: Fix a bug in `processMultiProof` and `processMultiProofCalldata` that allows proving arbitrary leaves if the tree contains a node with value 0 at depth 1. - -## 4.9.1 (2023-06-07) - -- `Governor`: Add a mechanism to restrict the address of the proposer using a suffix in the description. - -## 4.9.0 (2023-05-23) - -- `ReentrancyGuard`: Add a `_reentrancyGuardEntered` function to expose the guard status. ([#3714](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3714)) -- `ERC721Wrapper`: add a new extension of the `ERC721` token which wraps an underlying token. Deposit and withdraw guarantee that the ownership of each token is backed by a corresponding underlying token with the same identifier. ([#3863](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3863)) -- `EnumerableMap`: add a `keys()` function that returns an array containing all the keys. ([#3920](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3920)) -- `Governor`: add a public `cancel(uint256)` function. ([#3983](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3983)) -- `Governor`: Enable timestamp operation for blockchains without a stable block time. This is achieved by connecting a Governor's internal clock to match a voting token's EIP-6372 interface. ([#3934](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3934)) -- `Strings`: add `equal` method. ([#3774](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3774)) -- `IERC5313`: Add an interface for EIP-5313 that is now final. ([#4013](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4013)) -- `IERC4906`: Add an interface for ERC-4906 that is now Final. ([#4012](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4012)) -- `StorageSlot`: Add support for `string` and `bytes`. ([#4008](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4008)) -- `Votes`, `ERC20Votes`, `ERC721Votes`: support timestamp checkpointing using EIP-6372. ([#3934](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3934)) -- `ERC4626`: Add mitigation to the inflation attack through virtual shares and assets. ([#3979](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3979)) -- `Strings`: add `toString` method for signed integers. ([#3773](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3773)) -- `ERC20Wrapper`: Make the `underlying` variable private and add a public accessor. ([#4029](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4029)) -- `EIP712`: add EIP-5267 support for better domain discovery. ([#3969](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3969)) -- `AccessControlDefaultAdminRules`: Add an extension of `AccessControl` with additional security rules for the `DEFAULT_ADMIN_ROLE`. ([#4009](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4009)) -- `SignatureChecker`: Add `isValidERC1271SignatureNow` for checking a signature directly against a smart contract using ERC-1271. ([#3932](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3932)) -- `SafeERC20`: Add a `forceApprove` function to improve compatibility with tokens behaving like USDT. ([#4067](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4067)) -- `ERC1967Upgrade`: removed contract-wide `oz-upgrades-unsafe-allow delegatecall` annotation, replaced by granular annotation in `UUPSUpgradeable`. ([#3971](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3971)) -- `ERC20Wrapper`: self wrapping and deposit by the wrapper itself are now explicitly forbidden. ([#4100](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4100)) -- `ECDSA`: optimize bytes32 computation by using assembly instead of `abi.encodePacked`. ([#3853](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3853)) -- `ERC721URIStorage`: Emit ERC-4906 `MetadataUpdate` in `_setTokenURI`. ([#4012](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4012)) -- `ShortStrings`: Added a library for handling short strings in a gas efficient way, with fallback to storage for longer strings. ([#4023](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4023)) -- `SignatureChecker`: Allow return data length greater than 32 from EIP-1271 signers. ([#4038](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4038)) -- `UUPSUpgradeable`: added granular `oz-upgrades-unsafe-allow-reachable` annotation to improve upgrade safety checks on latest version of the Upgrades Plugins (starting with `@openzeppelin/upgrades-core@1.21.0`). ([#3971](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3971)) -- `Initializable`: optimize `_disableInitializers` by using `!=` instead of `<`. ([#3787](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3787)) -- `Ownable2Step`: make `acceptOwnership` public virtual to enable usecases that require overriding it. ([#3960](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3960)) -- `UUPSUpgradeable.sol`: Change visibility to the functions `upgradeTo ` and `upgradeToAndCall ` from `external` to `public`. ([#3959](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3959)) -- `TimelockController`: Add the `CallSalt` event to emit on operation schedule. ([#4001](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4001)) -- Reformatted codebase with latest version of Prettier Solidity. ([#3898](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3898)) -- `Math`: optimize `log256` rounding check. ([#3745](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3745)) -- `ERC20Votes`: optimize by using unchecked arithmetic. ([#3748](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3748)) -- `Multicall`: annotate `multicall` function as upgrade safe to not raise a flag for its delegatecall. ([#3961](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3961)) -- `ERC20Pausable`, `ERC721Pausable`, `ERC1155Pausable`: Add note regarding missing public pausing functionality ([#4007](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4007)) -- `ECDSA`: Add a function `toDataWithIntendedValidatorHash` that encodes data with version 0x00 following EIP-191. ([#4063](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4063)) -- `MerkleProof`: optimize by using unchecked arithmetic. ([#3745](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3745)) - -### Breaking changes - -- `EIP712`: Addition of ERC5267 support requires support for user defined value types, which was released in Solidity version 0.8.8. This requires a pragma change from `^0.8.0` to `^0.8.8`. -- `EIP712`: Optimization of the cache for the upgradeable version affects the way `name` and `version` are set. This is no longer done through an initializer, and is instead part of the implementation's constructor. As a consequence, all proxies using the same implementation will necessarily share the same `name` and `version`. Additionally, an implementation upgrade risks changing the EIP712 domain unless the same `name` and `version` are used when deploying the new implementation contract. - -### Deprecations - -- `ERC20Permit`: Added the file `IERC20Permit.sol` and `ERC20Permit.sol` and deprecated `draft-IERC20Permit.sol` and `draft-ERC20Permit.sol` since [EIP-2612](https://eips.ethereum.org/EIPS/eip-2612) is no longer a Draft. Developers are encouraged to update their imports. ([#3793](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3793)) -- `Timers`: The `Timers` library is now deprecated and will be removed in the next major release. ([#4062](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4062)) -- `ERC777`: The `ERC777` token standard is no longer supported by OpenZeppelin. Our implementation is now deprecated and will be removed in the next major release. The corresponding standard interfaces remain available. ([#4066](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4066)) -- `ERC1820Implementer`: The `ERC1820` pseudo-introspection mechanism is no longer supported by OpenZeppelin. Our implementation is now deprecated and will be removed in the next major release. The corresponding standard interfaces remain available. ([#4066](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4066)) - -## 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-12) - -- `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 (2022-08-10) - -### 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 (2022-07-25) - -- `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 (2022-07-18) - -- `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. ([#2849](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2849)) -- `GovernorTimelockCompound`: fix ability to use Ether stored in the Timelock contract. ([#2849](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2849)) - -## 4.3.3 (2021-11-08) - -- `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 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 (2021-07-24) - -- `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 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/openzeppelin-contracts/CODE_OF_CONDUCT.md b/lib/openzeppelin-contracts/CODE_OF_CONDUCT.md deleted file mode 100644 index f7cdce9..0000000 --- a/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, socioeconomic 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 contact@openzeppelin.com. 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/openzeppelin-contracts/CONTRIBUTING.md b/lib/openzeppelin-contracts/CONTRIBUTING.md deleted file mode 100644 index 1a44cc2..0000000 --- a/lib/openzeppelin-contracts/CONTRIBUTING.md +++ /dev/null @@ -1,36 +0,0 @@ -# Contributing Guidelines - -There are many ways to contribute to OpenZeppelin Contracts. - -## Troubleshooting - -You can help other users in the community to solve their smart contract issues in the [OpenZeppelin Forum]. - -[OpenZeppelin Forum]: https://forum.openzeppelin.com/ - -## Opening an issue - -You can [open an issue] to suggest a feature or report a minor bug. For serious bugs please do not open an issue, instead refer to our [security policy] for appropriate steps. - -If you believe your issue may be due to user error and not a problem in the library, consider instead posting a question on the [OpenZeppelin Forum]. - -Before opening an issue, be sure to search through the existing open and closed issues, and consider posting a comment in one of those instead. - -When requesting a new feature, include as many details as you can, especially around the use cases that motivate it. Features are prioritized according to the impact they may have on the ecosystem, so we appreciate information showing that the impact could be high. - -[security policy]: https://github.com/OpenZeppelin/openzeppelin-contracts/security -[open an issue]: https://github.com/OpenZeppelin/openzeppelin-contracts/issues/new/choose - -## Submitting a pull request - -If you would like to contribute code or documentation you may do so by forking the repository and submitting a pull request. - -Any non-trivial code contribution must be first discussed with the maintainers in an issue (see [Opening an issue](#opening-an-issue)). Only very minor changes are accepted without prior discussion. - -Make sure to read and follow the [engineering guidelines](./GUIDELINES.md). Run linter and tests to make sure your pull request is good before submitting it. - -Changelog entries should be added to each pull request by using [Changesets](https://github.com/changesets/changesets/). - -When opening the pull request you will be presented with a template and a series of instructions. Read through it carefully and follow all the steps. Expect a review and feedback from the maintainers afterwards. - -If you're looking for a good place to start, look for issues labelled ["good first issue"](https://github.com/OpenZeppelin/openzeppelin-contracts/labels/good%20first%20issue)! diff --git a/lib/openzeppelin-contracts/FUNDING.json b/lib/openzeppelin-contracts/FUNDING.json deleted file mode 100644 index c672862..0000000 --- a/lib/openzeppelin-contracts/FUNDING.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "drips": { - "ethereum": { - "ownedBy": "0xAeb37910f93486C85A1F8F994b67E8187554d664" - } - } -} diff --git a/lib/openzeppelin-contracts/GUIDELINES.md b/lib/openzeppelin-contracts/GUIDELINES.md deleted file mode 100644 index 97fa729..0000000 --- a/lib/openzeppelin-contracts/GUIDELINES.md +++ /dev/null @@ -1,148 +0,0 @@ -# Engineering Guidelines - -## Testing - -Code must be thoroughly tested with quality unit tests. - -We defer to the [Moloch Testing Guide](https://github.com/MolochVentures/moloch/tree/master/test#readme) for specific recommendations, though not all of it is relevant here. Note the introduction: - -> Tests should be written, not only to verify correctness of the target code, but to be comprehensively reviewed by other programmers. Therefore, for mission critical Solidity code, the quality of the tests are just as important (if not more so) than the code itself, and should be written with the highest standards of clarity and elegance. - -Every addition or change to the code must come with relevant and comprehensive tests. - -Refactors should avoid simultaneous changes to tests. - -Flaky tests are not acceptable. - -The test suite should run automatically for every change in the repository, and in pull requests tests must pass before merging. - -The test suite coverage must be kept as close to 100% as possible, enforced in pull requests. - -In some cases unit tests may be insufficient and complementary techniques should be used: - -1. Property-based tests (aka. fuzzing) for math-heavy code. -2. Formal verification for state machines. - -## Code style - -Solidity code should be written in a consistent format enforced by a linter, following the official [Solidity Style Guide](https://docs.soliditylang.org/en/latest/style-guide.html). See below for further [Solidity Conventions](#solidity-conventions). - -The code should be simple and straightforward, prioritizing readability and understandability. Consistency and predictability should be maintained across the codebase. In particular, this applies to naming, which should be systematic, clear, and concise. - -Sometimes these guidelines may be broken if doing so brings significant efficiency gains, but explanatory comments should be added. - -Modularity should be pursued, but not at the cost of the above priorities. - -## Documentation - -For contributors, project guidelines and processes must be documented publicly. - -For users, features must be abundantly documented. Documentation should include answers to common questions, solutions to common problems, and recommendations for critical decisions that the user may face. - -All changes to the core codebase (excluding tests, auxiliary scripts, etc.) must be documented in a changelog, except for purely cosmetic or documentation changes. - -## Peer review - -All changes must be submitted through pull requests and go through peer code review. - -The review must be approached by the reviewer in a similar way as if it was an audit of the code in question (but importantly it is not a substitute for and should not be considered an audit). - -Reviewers should enforce code and project guidelines. - -External contributions must be reviewed separately by multiple maintainers. - -## Automation - -Automation should be used as much as possible to reduce the possibility of human error and forgetfulness. - -Automations that make use of sensitive credentials must use secure secret management, and must be strengthened against attacks such as [those on GitHub Actions worklows](https://github.com/nikitastupin/pwnhub). - -Some other examples of automation are: - -- Looking for common security vulnerabilities or errors in our code (eg. reentrancy analysis). -- Keeping dependencies up to date and monitoring for vulnerable dependencies. - -## Pull requests - -Pull requests are squash-merged to keep the `master` branch history clean. The title of the pull request becomes the commit message, so it should be written in a consistent format: - -1) Begin with a capital letter. -2) Do not end with a period. -3) Write in the imperative: "Add feature X" and not "Adds feature X" or "Added feature X". - -This repository does not follow conventional commits, so do not prefix the title with "fix:" or "feat:". - -Work in progress pull requests should be submitted as Drafts and should not be prefixed with "WIP:". - -Branch names don't matter, and commit messages within a pull request mostly don't matter either, although they can help the review process. - -# Solidity Conventions - -In addition to the official Solidity Style Guide we have a number of other conventions that must be followed. - -* All state variables should be private. - - Changes to state should be accompanied by events, and in some cases it is not correct to arbitrarily set state. Encapsulating variables as private and only allowing modification via setters enables us to ensure that events and other rules are followed reliably and prevents this kind of user error. - -* Internal or private state variables or functions should have an underscore prefix. - - ```solidity - contract TestContract { - uint256 private _privateVar; - uint256 internal _internalVar; - function _testInternal() internal { ... } - function _testPrivate() private { ... } - } - ``` - -* Functions should be declared virtual, with few exceptions listed below. The - contract logic should be written considering that these functions may be - overridden by developers, e.g. getting a value using an internal getter rather - than reading directly from a state variable. - - If function A is an "alias" of function B, i.e. it invokes function B without - significant additional logic, then function A should not be virtual so that - any user overrides are implemented on B, preventing inconsistencies. - -* Events should generally be emitted immediately after the state change that they - represent, and should be named in the past tense. Some exceptions may be made for gas - efficiency if the result doesn't affect observable ordering of events. - - ```solidity - function _burn(address who, uint256 value) internal { - super._burn(who, value); - emit TokensBurned(who, value); - } - ``` - - Some standards (e.g. ERC-20) use present tense, and in those cases the - standard specification is used. - -* Interface names should have a capital I prefix. - - ```solidity - interface IERC777 { - ``` - -* Contracts not intended to be used standalone should be marked abstract - so they are required to be inherited to other contracts. - - ```solidity - abstract contract AccessControl is ..., { - ``` - -* Unchecked arithmetic blocks should contain comments explaining why overflow is guaranteed not to happen. If the reason is immediately apparent from the line above the unchecked block, the comment may be omitted. - -* Custom errors should be declared following the [EIP-6093](https://eips.ethereum.org/EIPS/eip-6093) rationale whenever reasonable. Also, consider the following: - - * The domain prefix should be picked in the following order: - 1. Use `ERC` if the error is a violation of an ERC specification. - 2. Use the name of the underlying component where it belongs (eg. `Governor`, `ECDSA`, or `Timelock`). - - * The location of custom errors should be decided in the following order: - 1. Take the errors from their underlying ERCs if they're already defined. - 2. Declare the errors in the underlying interface/library if the error makes sense in its context. - 3. Declare the error in the implementation if the underlying interface/library is not suitable to do so (eg. interface/library already specified in an ERC). - 4. Declare the error in an extension if the error only happens in such extension or child contracts. - - * Custom error names should not be declared twice along the library to avoid duplicated identifier declarations when inheriting from multiple contracts. diff --git a/lib/openzeppelin-contracts/LICENSE b/lib/openzeppelin-contracts/LICENSE deleted file mode 100644 index b2fee8f..0000000 --- a/lib/openzeppelin-contracts/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016-2024 Zeppelin Group Ltd - -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/openzeppelin-contracts/README.md b/lib/openzeppelin-contracts/README.md deleted file mode 100644 index fa7b4e3..0000000 --- a/lib/openzeppelin-contracts/README.md +++ /dev/null @@ -1,107 +0,0 @@ -# OpenZeppelin - -[![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) -[![GitPOAPs](https://public-api.gitpoap.io/v1/repo/OpenZeppelin/openzeppelin-contracts/badge)](https://www.gitpoap.io/gh/OpenZeppelin/openzeppelin-contracts) -[![Docs](https://img.shields.io/badge/docs-%F0%9F%93%84-yellow)](https://docs.openzeppelin.com/contracts) -[![Forum](https://img.shields.io/badge/forum-%F0%9F%92%AC-yellow)](https://docs.openzeppelin.com/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 mission-critical developer security platform to code, audit, deploy, monitor, and operate with confidence. - -> [!IMPORTANT] -> OpenZeppelin Contracts uses semantic versioning to communicate backwards compatibility of its API and storage layout. For upgradeable contracts, the storage layout of different major versions should be assumed incompatible, for example, it is unsafe to upgrade from 4.9.3 to 5.0.0. Learn more at [Backwards Compatibility](https://docs.openzeppelin.com/contracts/backwards-compatibility). - -## Overview - -### Installation - -#### Hardhat (npm) - -``` -$ npm install @openzeppelin/contracts -``` - -#### Foundry (git) - -> [!WARNING] -> When installing via git, it is a common error to use the `master` branch. This is a development branch that should be avoided in favor of tagged releases. The release process involves security measures that the `master` branch does not guarantee. - -> [!WARNING] -> Foundry installs the latest version initially, but subsequent `forge update` commands will use the `master` branch. - -``` -$ forge install OpenZeppelin/openzeppelin-contracts -``` - -Add `@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/` in `remappings.txt.` - -### Usage - -Once installed, you can use the contracts in the library by importing them: - -```solidity -pragma solidity ^0.8.20; - -import {ERC721} from "@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 [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). -* [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/), 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) with the goal of providing a secure and reliable library of smart contract components for the ecosystem. We address security through risk management in various areas such as engineering and open source best practices, scoping and API design, multi-layered review processes, and incident response preparedness. - -The [OpenZeppelin Contracts Security Center](https://contracts.openzeppelin.com/security) contains more details about the secure development process. - -The security policy is detailed in [`SECURITY.md`](./SECURITY.md) as well, and specifies how you can report security vulnerabilities, which versions will receive security patches, and how to stay informed about them. We run a [bug bounty program on Immunefi](https://immunefi.com/bounty/openzeppelin) to reward the responsible disclosure of vulnerabilities. - -The engineering guidelines we follow to promote project quality can be found in [`GUIDELINES.md`](./GUIDELINES.md). - -Past audits can be found in [`audits/`](./audits). - -Smart contracts are a nascent technology and carry a high level of technical risk and uncertainty. Although OpenZeppelin is well known for its security audits, using OpenZeppelin Contracts is not a substitute for a security audit. - -OpenZeppelin Contracts is made available under the MIT License, which disclaims all warranties in relation to the project and which limits the liability of those that contribute and maintain the project, including OpenZeppelin. As set out further in the Terms, you acknowledge that you are solely responsible for any use of OpenZeppelin Contracts and you assume all risks associated with any such use. - -## 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). - -## Legal - -Your use of this Project is governed by the terms found at www.openzeppelin.com/tos (the "Terms"). diff --git a/lib/openzeppelin-contracts/RELEASING.md b/lib/openzeppelin-contracts/RELEASING.md deleted file mode 100644 index 06dd218..0000000 --- a/lib/openzeppelin-contracts/RELEASING.md +++ /dev/null @@ -1,45 +0,0 @@ -# Releasing - -OpenZeppelin Contracts uses a fully automated release process that takes care of compiling, packaging, and publishing the library, all of which is carried out in a clean CI environment (GitHub Actions), implemented in the ([`release-cycle`](.github/workflows/release-cycle.yml)) workflow. This helps to reduce the potential for human error and inconsistencies, and ensures that the release process is ongoing and reliable. - -## Changesets - -[Changesets](https://github.com/changesets/changesets/) is used as part of our release process for `CHANGELOG.md` management. Each change that is relevant for the codebase is expected to include a changeset. - -## Branching model - -The release cycle happens on release branches called `release-vX.Y`. Each of these branches starts as a release candidate (rc) and is eventually promoted to final. - -A release branch can be updated with cherry-picked patches from `master`, or may sometimes be committed to directly in the case of old releases. These commits will lead to a new release candidate or a patch increment depending on the state of the release branch. - -```mermaid - %%{init: {'gitGraph': {'mainBranchName': 'master'}} }%% - gitGraph - commit id: "Feature A" - commit id: "Feature B" - branch release-vX.Y - commit id: "Start release" - commit id: "Release vX.Y.0-rc.0" - - checkout master - commit id: "Feature C" - commit id: "Fix A" - - checkout release-vX.Y - cherry-pick id: "Fix A" tag: "" - commit id: "Release vX.Y.0-rc.1" - commit id: "Release vX.Y.0" - - checkout master - merge release-vX.Y - commit id: "Feature D" - commit id: "Patch B" - - checkout release-vX.Y - cherry-pick id: "Patch B" tag: "" - commit id: "Release vX.Y.1" - - checkout master - merge release-vX.Y - commit id: "Feature E" -``` diff --git a/lib/openzeppelin-contracts/SECURITY.md b/lib/openzeppelin-contracts/SECURITY.md deleted file mode 100644 index 9922c45..0000000 --- a/lib/openzeppelin-contracts/SECURITY.md +++ /dev/null @@ -1,43 +0,0 @@ -# Security Policy - -Security vulnerabilities should be disclosed to the project maintainers through [Immunefi], or alternatively by email to security@openzeppelin.com. - -[Immunefi]: https://immunefi.com/bounty/openzeppelin - -## Bug Bounty - -Responsible disclosure of security vulnerabilities is rewarded through a bug bounty program on [Immunefi]. - -There is a bonus reward for issues introduced in release candidates that are reported before making it into a stable release. Learn more about release candidates at [`RELEASING.md`](./RELEASING.md). - -## Security Patches - -Security vulnerabilities will be patched as soon as responsibly possible, and published as an advisory on this repository (see [advisories]) and on the affected npm packages. - -[advisories]: https://github.com/OpenZeppelin/openzeppelin-contracts/security/advisories - -Projects that build on OpenZeppelin Contracts are encouraged to clearly state, in their source code and websites, how to be contacted about security issues in the event that a direct notification is considered necessary. We recommend including it in the NatSpec for the contract as `/// @custom:security-contact security@example.com`. - -Additionally, we recommend installing the library through npm and setting up vulnerability alerts such as [Dependabot]. - -[Dependabot]: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-supply-chain-security#what-is-dependabot - -### Supported Versions - -Security patches will be released for the latest minor of a given major release. For example, if an issue is found in versions >=4.6.0 and the latest is 4.8.0, the patch will be released only in version 4.8.1. - -Only critical severity bug fixes will be backported to past major releases. - -| Version | Critical security fixes | Other security fixes | -| ------- | ----------------------- | -------------------- | -| 5.x | :white_check_mark: | :white_check_mark: | -| 4.9 | :white_check_mark: | :x: | -| 3.4 | :white_check_mark: | :x: | -| 2.5 | :x: | :x: | -| < 2.0 | :x: | :x: | - -Note as well that the Solidity language itself only guarantees security updates for the latest release. - -## Legal - -Smart contracts are a nascent technology and carry a high level of technical risk and uncertainty. OpenZeppelin Contracts is made available under the MIT License, which disclaims all warranties in relation to the project and which limits the liability of those that contribute and maintain the project, including OpenZeppelin. Your use of the project is also governed by the terms found at www.openzeppelin.com/tos (the "Terms"). As set out in the Terms, you are solely responsible for any use of OpenZeppelin Contracts and you assume all risks associated with any such use. This Security Policy in no way evidences or represents an on-going duty by any contributor, including OpenZeppelin, to correct any flaws or alert you to all or any of the potential risks of utilizing the project. diff --git a/lib/openzeppelin-contracts/audits/2017-03.md b/lib/openzeppelin-contracts/audits/2017-03.md deleted file mode 100644 index 4cd6dbf..0000000 --- a/lib/openzeppelin-contracts/audits/2017-03.md +++ /dev/null @@ -1,292 +0,0 @@ -# OpenZeppelin Audit - -NOTE ON 2021-07-19: This report makes reference to Zeppelin, OpenZeppelin, OpenZeppelin Contracts, 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 Contracts 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/openzeppelin-contracts/audits/2018-10.pdf b/lib/openzeppelin-contracts/audits/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/openzeppelin-contracts/audits/2022-10-Checkpoints.pdf b/lib/openzeppelin-contracts/audits/2022-10-Checkpoints.pdf deleted file mode 100644 index 7e0d08387ad3be0a3e74201566eca3167aead1c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 155606 zcmcFr2V4}%(iagF6c8myMiCTn7j~CjSjiwDIp-`nrzJ-NK@m8KN|Y=a$r%wzB1!Th zK{ApgXZ!~6PVS!Gd%W-7@8>$rbamCgs=8~sr>lov=8iB30%pgh{~8ybgbSf%rM0?e zip#}?%c9_HZ9vN+qibYfhsz>vqHjm5PKyBQRDOpncLf$SXtUJ0;cJ4M27%U6g?Z z!0*>g*dXj+7=i!A4$yw@;eRm{ z9LWYovi{J~(h6l@2h!CCx-y`pt~ubaBYS_>`R54!irxws7cSq&1xU}>K+nwD3b39X z$lT(@(#TE^;CN{Aqapkk zCH^Yj&fdZTkaF1IXz2f&1}NQo<^~`uLlDr-4*J+(r#^}u|E8tArM(?sY-?K+2cSQJ z4DBuT{^%Y@0p>3ZU`Pa@8WM^;7^<4Ing^r%=->A+bD-hxV_e7yB_e;&Q4dG1E(FYa zSkTj@g&Z_u;s5=PApg;wgPSVS_e_DFen@Eof&-%$!O9AUK_O5!Bn*aN<)DSI9mRnp=^wFZON+bt`1d4;!PZ#keEsozv=+hj z(EIrK<7sT`*kLL}NfZg)7_`m~>>06;Wy9R4i>)VY zH(4oeIP}!Dj4X@Gzp?txb4)&KtBtD#N>J(HH1 zMJb~O&;1_Tp4Tg!W0*J8y;GE*=wQt772`w8^S1dCX&p~3YI>N?Q=>mizv5o?MW7?2fpRQ_nRMMuN+Uc>+eV4mg>VCb_LU3q!TI zlnM=?j9EJ!Et>h(vln(Bf7#uTD4WKJh8y2ho2{F!jbnO?c%RstfH80G5~*Qd%dc@M zc%3$Oufwc^gm{lk?4p&ed}q!F{sjNB>iAHB`#EQBTD*mKu+tK)RY=rkZ-xIxbJ~p! zl~f6x^?le*$ajz6Om=pDhIDgK1nI-R37Ydl&h)|}j}c#3aKf)^E9;^gg?fn#@n5Lr zbkA>>*B523F?)WRRUTW##qt)?8`!4!Agd={q?unoZsCgPZZh9+v$J=1T++)mGVU=S zEtusAwDeG4eDVJBEctR|2dwm45BEFr_mve6^E6+CAzlaL;d|%)J~9r%@$Vz!#}wsY z$k_rh=J#i{q=CMPu7H&j5TXx;790r&L)qbQAU<%gLBJdwNOlAp5GH^L$x&#cJ)EiF zvd9_OS=rm_0Z;YAmXN~RgVyibCnlq8^d*LPGeuZQ0uSM_Vi5RfLD_Dw<;PK%t>3x(0%+x2b;@n ze=^@1KU%W!3HQuR%DFa{#67Ffl7QD6O0m^$uG<6heJ*(G!!v#vG*a5%I`(6~Jp%P0 z)I1z$HfFJHX>GBp!lsHnn`&yyz-`-LcX4Xb;~P

2ojH?x0tMLX1p#1!i~6c>Ik8Oj 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 diff --git a/lib/openzeppelin-contracts/audits/2022-10-ERC4626.pdf b/lib/openzeppelin-contracts/audits/2022-10-ERC4626.pdf deleted file mode 100644 index 154fe75212e317a87cfa249b9101a04e789281bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 204184 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 P3ADOAJw3B!^LYOO&o2YP diff --git a/lib/openzeppelin-contracts/audits/2023-05-v4.9.pdf b/lib/openzeppelin-contracts/audits/2023-05-v4.9.pdf deleted file mode 100644 index 21cd7f59307483e93957a3b2c94aa11c0efe40ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 485395 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

DA5c*CxgHUhhcBZ>@bV^8E) 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 z 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

O=UN>c$5c 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

&uA=()A&${K3d1zHWJ6254Xdjgnm9RgW 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

B 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

Pt)xA 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

f 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 %|OBt__ zvOGK-UsIn^->XYD%~E`(v_QT?39X}85nf^Z<7&)1IWk^*WHs?3T1C~w=_+_xX+LXU zY;QTFJr*%OcT_owHHmf`yC`w?c2>CPs6J04(51tr zp6a)i$BMs$i@WyApWELkHzIb4pXul1<`D+CiP-wLmKx?) z(^q>|v09Ngm^Sh_^f%U=u}*R4(H3Ycx~AdRw#}B8hAqA7?7jE;ig%0QGD0#EGD=wS ztRXGvo2+b$8dw^uEIYnJUZZ?1E$-*g=TaL}Eo)C}QEJKd3U?iL9|!M-$Odg?^rRtV z)sn8sW_a!8cbAB#3faZ+;QYRE&>_@z=KtS z6@Ty|yQ5M6G@**7-jpW}?KfySYHP zHamUWywKt7jHRn7zxLpA_V|KBg_DMJ#1X}5>hgIeal)}+JLmTv*y4RYVNR-eB4?7h!|62; zgNM;&Tq%uR|1d`#qpoVwCB4HZdOUNIee0-ryn|^14wf&BhX_JVFv&K@Jv^r%s%O#dU>!dXvtEuHr zJ<2+j@{+*RWa%QKsfjj<>4%d`$vC)+QcDsSqy&#UUyuLr&!e^&50I36Bk-{Z%f zus+pj5L|ZG`M2X=hBia6c&=QXUqKhYxXCJIF1d{DExuVK=GG=tvsXM8@6Q(4>$AQ(w~-i={#$m^2YiYV*>Ctd@|pk9};%Se6t(5_PkjxTHf!H zXd`vb-A^8Gdw(CR%Ic!Ee|{8SRBo@aUomZ3yI);@j)#W9$?~Flzkih-)$Jc0=t^~B zzhYiLY&Naic6GUa#J<<=mJCeob@lpke`$Y)eoRGnrTe;m+OnRXj8>V zXQc*o?gKb+6r-;Pv2CmeQEQ~fz!GAprVF!P4Fbrb$E)YRwNOZzmMsI}0&uX_+|Ue%=zp-d>^cye^oRoBEvFi?O4IYO zhx@mJ1lKEXl*-5bMw~A%DMi8CuG*8UVTpqx)7wk}Ub1+K(23yOuZj*c(o>%FM% zdg@%6SgnOms(Dyry)!wS$Y8xnwKd&J*hrN6Fp^&xU7U4r_=*O=;&8pVZ_!SQ$f?N2 z!Sa;;A|PyY+gse=mfWlWn7RW=ePeNMa@E%5p7s0movvO73E}jem3kjvoo~CNn5!0a zU0J-yy4X*P=9YNO-PWH~CG0F{qa_!tWXz1}tZNvmE6nSK7nTNB;d6mJ^kZCzlvl!e%+<)P z1p;4U^vPe$ZGAhzv4(Znn)}c}1o{ziHNwPv-PTgKAgA64zf0NY5yS77_JsnNcd)y* zRIxB@V1+|09o~27Or*ojpej4!!x#@M^JH_!baM8sw`XxY= zbn_Mt)7dFx8=@@2mg&_&gZ_ADA1A*?d(IPW2K&?D|GFqg&2&>oDy~aMvCyB!#J*XW zkf-w})oGNQ!F+ThmFb~MDxIZPd@j!sGsEe$pOm^ekl!$J8wB;zm3p1mKllpEaL3%W z(N3g2m@&^fMD6+0(`cunt=8^QTixxoA9d1ya&D!!h5iS)BO$Ww&Zj+Ck*CdVJ6i(L zol>mA&^=zPHc}~;DjgPqa`-zSaWTQ5h~I2qs+l$*>jmA)>}{v07-j=OzlS+2V?udv z$c}zUsFlgGnqN>bXf_jSes$u6;-}M>_sOSIgYW%RdA@;D!RN^Z-q}YJ+Oeyc{VD0` zi`~MRbyma~ zUbS7w#XL8Fwu)LQN2^#3J1vEe^~RIu8i%)+L9bFybyU8}r_Lc{yxmZ4TBc=Ia0hvq z0&wO>g%39j3gt(bi%o9Q!hq)&*+M01=0{15w|Hf5bF5k_o>REufnJYP3RIQv8=s!r zN14T!<^kUhz^sl{hVd@q4dZzZ7(-FLB^az$Lf;6)FwEf>4gl2&HW8F*T){}L|K+d@ zYT`V3VwGN`S-Lu{E~QMrsFH`1i=S1bG2RA^W6@$=nTLO8oVlbQWl<Onf2vp$$ielCCK zl@p#})v#Z}?M-#Nra&>6H{8%Kno_T2U1h^^=!TqAEdRz<^W#jT+P*VY=y)bwT-)kj zafj=SAiqHV`Yi~p1yTiwH;eGOCQZ(!O0H{tL-r$DeYj;lJOFP14%41&?&+(X z2K~cPdOpft;WU&h)tPyy*7K!k46-lXlu#octeYrGw*+Job0lcf}dN6gc;Y zcIlR-iwd&Ir7a4wN531kg)L`g%}&|U7>gQNX0fYsNQVwYEv>moOKoYIVTbq~h=(de zK6LvwCG|qR(57#I70+baa!nG3rhvN`*+3(Kh%(pYc{O%7g&#^;V~BL8Ko5c0yR8z| zu(k!8auplqS1gg?Kc1tdr42Aj&9&cI6uj9y@lH+fCRamO*G209yRM&R0-b=lio1#k z@d4iv>rCR*6P~^*LVZBBuIx#DN{nvOj=PWzO2LkbePlKxD_;>wG%pe>z_ctX0b0q^ zXgG)vf1ald)T#|f9@@AM)#kVoMd#Z#2VZMGp7Ex&Z~8y!C7s12qrJ-v)uPTADyS}t zp2hv7#TPm14yD=s&OJsrBzRK!jWp~{a@oug)Zj?`G#T%H&0c%uK0l$Gx?T%!iE`Yh zcE@syJH{cx<2?T&#T)Z7?i>C69zTIU3qUcGAyq;y@mP`*TGkD-?|Cp z1>*`@@b|&Qjxfz_FP=?riSIsJY6exa0PZ@kLC z2fhp+zk3^3db%_*wKxs7g)@@AzKC?I3|v!`RZKS ztD{b&!yjN2D4iW4S8J;Lo`JgU1+VeO2B+G;fNFvCE;|qf35jS-;Ty+u<6U>|}`8-dpzMT)P zcyfQep?~m>;eYu--*l3+^eAB%jGlbSysCKzht(<3>sahlu2YFF)g1|?0B0o6Jh%=J zvsnMyWLy#bPAFD^doEaO@|2=Xf!R#v;b(v47<+O0d|M2~Iye7N*{YIpnB1!QG#$dKF|ovDMZCK@~aAUmafcr>rM62U^NTw!dRTt(cU21Df3(A1MGnJPB! z;M|noT}z*`c))6t6fA3@pQxT}WwY zYzuq`YRx*oXI(jwwPqb1AtYnWvQo?#N>4b5H@fo7h}3eq-HLh^*^6Ips68aUNgh}G zo$AzypeoyV$ZI}42~*er`JULYSW+)yO&k+!mHqi=)>dTjFzJgno-x_qUa$35$ZBcp zFrD_NwvLUAh7R@v!B4}7a`q8-q;t)JPOe|FN_~t-{}*X*85~EGw2O*avS7r_%#0S3 z#mr12X0l{4%VK6`i*Ca#;ew4&uOAb!-GuY zEQIZ`yUFPO4U9R4SpOa=esz{i-kX5X);vnGR(S8=8_7Hni5l)BZeA71uFKk80pr{R zmvVM`(E3I!RO^v_PsUL&^zlFjyXRSaCmMT0Z-PTkoTaHvpCL2bC+h zN|vlq+BBj45X3HybGvxjb91~QV5Kv?_^`2o6I}qxL~#$Np^Ec}oN}xBmfW{%fH?`# zv0diL4ls9*#sI7&p$G0K zBlJCHgI%l0_lVvn8bQkbceN`z4e$pCH8GD}Cc7(rkS{by9KM$Ugv+;bR&WndEz@m~ z{bw%d1alAwErKY>kD$ziUeGaLz>M@2%O6u1GWCoeE1eFGu#LWR8cW<#H&f+qnZCOK ztU=qlQQluA+VtaHYj{8%;Cq^S@UEEL)u3q8+T46)0S@WiYHgKVNNs(F@y*^Y7wcFY zzj;CI7F1?4QmaZS-fRD(NzAF1m057x6=l5^n%+3P0* zSd}INml!uWyEqo@?ZmfKso*Zz1|9a1NuxJI(6>CCD9&$Y?%($W>cSuNjumK|y3xPX z9ZIE&{%M|coOh`gilOUx+7N1q{2Hb6i_axp!vX&KB`VPLUS4Zs7@N9r$jvsW8&)cRw5EP zKNjVleH(Sh_O-PS95?U#oaYu-o@Xt(pgGeZ^Bx#)KENiAh3FRSU4MSt!tYl95rk+r zEU;Dx6t zz@|=ZBQ9wu<`Irr!R!!v!J7JlEAc}dTQ?^yJk~_KO%Zy&=SG$4ivMbGZ za?Gvi*2VMh2(u1d=pG01GjVGQ1vQ2Q7F(b#joK~M7B?^=F3{b?^gg?`57(+CVzVTK#MR5?#giiYVZGsCiMeis+(8WzL~+aMYiww0xGYy!>cHb6mk8YV zV-G!2&MXPe-;as0xDWV6?AA$<*V?r{e23IAoj-U_)?rN4ALJn6Kh>JP1k+-5h499l zCZL9V{~A-e#Pa1UH@(NZu9x;`6Q5BrB@1HLEH}3S8`jv9M!D5FCi3HPJ^Yg!(XPS;34(aIs`yBismYt$eH0%yHypta;6c@%ZD&Hvr1Tp; zi*Ktk$zp*@r8v@7o7e_BHFMBhW9Hf)#D(G>KLJ63p|{4XScEgRppU2n8>SeJnM*rU zI1hodAk&m~Qt&;Z?^Q8gPC~5;5^?Q>`LrVA^Q=^FN8C8z?2O~@`3!f2%unr{gg@7O z2c2skXbvy3^W)QR5|i56pA703nV&i^37ZJ$V(X5G$4|r`H%U4li5(u%4x9*2BsC_) z1(LqSf**uD%{dM%gb#Z6UinvVGAfOK^s0q$AKAmW&E2P$>aq`g*nd<$4XJVJFWMMp zd+l-L@TjDM-))qAUB5-Ctp*fxgyJai& zMJeSLF+$jhar33tmd>-ar-|j_U45_jjM=xr@J5d0yR3s1#m%JZkOv0oA5*!F(KX=* z%?W|{CpAf*l%M0B@1_c(+KXj)A|KepB%7EkDKjav?9e^f*k@S<wc70E4tPS% zWb_zHM9_nQf-*CK$R@7zbjQfQzJMA+4*!NBjWF;!%{*Q{w=nZOx>%mai-U&YK9q7q z?tBt+91GYxU0JY1hu#aYJJ#*YI(a#*D)Tfz{ePABLk;4UW_h0}DA^K;a=;ILl)w#) zUy!uk!d=&BUGuLR2RAtU-L?#mL_V1N-(#}HJu=_*_z^WdaqVARKV3Z9`i6Jq1oh+D zd;R=&s6UsA7eeo>BacKM_hW3C^Sfb~+RLOhtZSRtfiB65{CXk63*3Rkjf~DVUW-&P zq_j4aQDxILOllUFfpl=XmdC1{SKqxVMwCp7EKPnTu3|th-FV1p>?dTFd3|@f^~w{i z99$W#Jqs*jjVF~NuM4Y0$1`P+C`6qA{Gj-S3Mpq@F}y0XXuOT$9n}k$N=+%9S-L{J zhC7|AWaa1Vuv_x)8*^SV?V)**CJ+I;EJJNO1*fZfAN9XG-75dQMq%FC(MNaTJWkTHXN- zx=i$_lH`UacDsSQ{R3qg<|BH3A2WpxJ8Sv&`AY0;3(`XyuH591f(X9m z4BNo#xzrSf=^e}@KF*B5LXYru(_HQT5k6 zxL0FIC>+po%E4v0H}*u|KskpCpTqBwl91V`jR-GrE8QX@rxv&?0Tvyllh+JO=vm4W z?Xu}l*}Vi@2WPk`l2J%}=(WLUH$w&f^Z`Cw`9|Wf5u)tmR(S33dnpdTgp~Vma4U$F zBM^vxAY?|HXAh3RO;n}W90?5|=UGZ&NgQcj!Fi|Bo2F&Y*e7OL!FWNq$vEMY zH$$DKs0)Q?fEUA8PSDS*J5fd_6?yR&o7(2`3_5i^z|XHa4c|! zvf5wKaQ8Me?qH2`?lzi3$=4lCwohhVY8t572XSbbkNx<)e)|ny*?G8KcoF|q^Wm-r z9Cd;Fl6o^TdV2bKyzP~KO~2hn#Iu&{(jg1)`gWsJ7-KM!wsPB}y$RzP@v(Oh*XPzY zW8IT;V&gmK#+F)VQS#N-+#g=M{^Pf2@e#qRxDmOnrrb?pE+{C`T(Ar&(S4(F< zs&8!HZb82gfa=ehKdreh6}weutf_VM7mG%Bp6O4AKV4(~>EA}TF%tRX^NCp=R6HO3 zpLRw5hFSjKbG}$u{)W~q8Kx7{W7*4u5PbOq4u4goCS6y=z!|}DNh|3b6i-_UF~S;f z7}J!!6NE%jE%g2&|CZEQ&qyDH@G>y%l41z6hke*wEpp_5P%wf1v~{zQxGKv*O>f^c zfnA&wTylbQ7ZU1pfQ~dN@ZhfUGD5&T1rt*B%?)Cmp4xjiFri0q)^|_{s$==imJ&j@ zTKQD$iw8gK?ctLSny~82tsNF7|HLql$v4un6-jo5E@^hS;g4CjGQzcWM~AOrt0^OZ z$M;T$8-DjdNBFuuYF;X#Mi{@Vnj!!iOauNsX*Wm?q}_kqKKdK3xiHY#Nx{@n#LmXv z&h`_ugNW;Ig*^XEqLXkm^!QI%bdsh(a|>r8W;U*WCDgHfQXClCm@;ZGD!Ujt|5Y9H zkAj>3fmiuw%?+bE(8Sr|^RB-^Xh?>g^)Q2ifPnnYc`r3b{F3we@qd%8#m~8)Lc0D> zbN`P5o`2>5{vS>HcU98A3=$Pl`Daq#|85Q|3)g3U;6DwLHFUE2L^Syy5c~f-^FEe7 zE|3NiqI20%yu z#{vB>!TE;}{3WEH^4S_49Ua*J-v&O`K_Eb2Ke|CsU_cT;V!%O2KtNGI!BD_H`attQ zK)}F3K%oCNkINQ4v(9b#)fzlV;2iG__rOiD&hK}khT!~9u$^;t8<#myruA}S^>At@!T zq^zQWn^q(YG!T$v~+ZGc5!uc_we-d4+snj4hanlkBd)8OiE5kP0P*8FDNW3 zE-5Xmt*dWnY-(<4?fKo?*FP{gG(0jrGdnlGu(-6mvc0prw|{VWbbNAkeRF$v|M2+q z{DShA%3u&s@&7jG(|QyLNMdFvRN+s3|FY|IM*g8O$-gxIx57gIQdsf-tHw3|_bPv^ zfFOKM5GV>53dmOwOJ5K$WDq3qX#^3H;tUbV6$mMoU67*C1|=B#8}29~5v@^vv!^O%F}F;oo*2+SA|5EwxSBqb6Xx*!x3S@!mv z<^m8gdx|NYEjV&*TCO0)Xy!gAg@te_3_NkBLTjpECaF&hvPsB1V2>VZEhq$65J>?| z0V-MbUoGi>Oj(Aa(iSUQNU^mH4FxF#vXya`fKk&^vq5ZwK<1IFTKy_08y4h7$EvDj zL&aeN?$6M>R7R?h`Mm046GI4`FvYcD>HtC7Nb182A4Kq zz%}3JC6mJRhL+-f&sVtwL&XwCX%=Zuo1@|aaFv8RIuFq}CZ+WvfSY1an<^yvuW1Yg zvfY#gOIij}i?%%hxEfgeS|UD5J=-h1bUfVynEs@eIkJa3oM` zP;}0z6cB+P5`{l7rzlXP}&{Y zm72miVD+(T?%`v*SQSy11ZfVllzAX2{Q8pD8Pqd0kYA_;(^k-(uf z=|**|Z&KH>)Y&PF6Qfqt8hWMRat2o#b+N(wEy{hT)EI9`S0NSy1jtgVQuotTHLY4n z&VG{0PRSCNn5E_7!q9J!nHFdCbI3rZ!4Ojs^(jvEpde%B;k9rWjkY6Xb48M5h-ts( z)w1+xTTxXQ!A_lexaM1n6|HfFXN!oELfpzy!z~B{zWIrmWDv19kEGB-QgfyR8y*bD zNg0}|(VWFon<$YllogUO-wDT7+bSI=u#I4U2A74?l#r|P$`P^pr|DE$fe596H2}Wo zrr8s$R||AZyrx(sU>;rH@YrlL?OCBpRbI)=201KX7s-f#+P9Lcy3`UCHO`+#I?@WT zYhWS($_&CK!xfSy@-r9%iz{f_WdCE@GScyKA#8{mmFTmUKgEPt#YVwec-sqng2uXt zjcMEokPwhkVl<&XQi^~As6#Uew-J+d8Zr?Pp<$l7g(-Bvw@FB>aCXU3!b&2BS>oOo z$1rdLfWY&Kir9x_kWw<_sEk@{(E#h6Z}I{5iC8(?a6;l>Cv>Itj?=L+5+XD>q-Q}^ z0Jum+NO7v)gLDS@1@)MIirn}twTg;x$<&gfO7#Mr!~t1#3gIa-=sc<384fstQ6h>7 zhHOY|XiIgHK;l3wL8Dkf9Y__09%5vOXf9N=yi!bU5*uMEiD{TA^2EldI8mc05>kMQ zeUL2;lT<`G3dagpXu1tPQD{G&s00<4@NXI_sfY>`mfysZ>dSCKaoP|xViq_l!rlVm z>a&&s6=_jCT1NoB0W>KX=!_IfbWl1;7#WcnDZ?!yBALX%G}CX~AV)xrS{k0vNd~r^ zjJk1REd-*eh&yJPZVaPYX+>Wn7UG;{B-D=?%b=4dNpg0SXe+)&7AWMA%6pO#HA5t( z@C=c8dj%y4_Q+r-Aw8NtL1CqsK6RJ^O+XwqobNZmgM{muIG8gu>0q^ha0yU{NEOo^ z@-kUwi)60iP(vhT7`RC4L~&{-ERn!s7!|?55y6>6LE%tTNNP-MBs>}7QRI?@QFuU0 z1rrLgqqKc6GKEqftr-d2H$#*_W5{YJM1CQiB6OZiW{|~|f<0JJS(A)vSYLy%o#rVN z3YNVX>A<>3Y7Ju8KfyLU}DtC$mZO#N@v&xV%o0LSrkq05Obs&jfZF4i<45 zl%K^uy%fK+7&r1!*;f3gTLi_@#P~7)KQCnv7+p~3(@a6FW1|dU8A*z8LO9BUQjoL_ zO;p_{@<%*WwHybIa7eCX$tXjEX6ws%4*w zlOH0o9w>SM#R=*%BC?i<7yv~fHZHVZNP?{hPdFjEv1jaaYwr*z)-sSxkPk#q8I+;O zh-lX^Mv)oIArbqIDN%?G66h2ys-Pk+jz?8;p7(oDlRB|BogL;kAk>s5gkVZ2v=?Gq zlB7@y8?O%>VmF8gL{AM3`<&IkleT; z0Wv9(85U*+`2a2iPds)`+{E7>MsR|>ATd14F(s55P8^38TuTrHRHZ@^1O$TdW8q%| zBL1|mGj(BT*g++&Rg8h`#XqT|l}0w-&Vsxu`5WFGwZ2X3>`k3_HgO3lyl%{Y{)7208FB5DrER z!WSG{fd~Wy`QQCa{k@-0pEmH*oBwpnVFW+B{pTs>$MSzzg|qz)Eb>3B!v6<=lbz|` zD@ImUw$BnQj{kto}=@;UXFT7Dju?h`=Eo0r>5~Zo|`vP8%sPjDYx{-uq#B ze0P=p$NO{I8^hAwhn}~O$Nk-NygvWi`_0?M@w$9h=kvkM-tlRh`qw`v5tsUJ=QpS6 z5??#Lp3iOq1nfEwBNn5dDT6ocetcZ@=QD|XTR;*p4P1KH9w7P zCZX7Mdb+;u-K*JldS1U>j56xKS$&*WObggJMA>d3y}r!Pnq#h0x`7X;SK0YAuf5%` zcD)@(d_0d6GETmGw0wVgdN>`8#(aG_x|rX;xc+L}`Q!Q|WYzrPgjXUj(Ej%7;$eAq zP@m7|=Bzd-UBWGy@V)(~y8oxZ-t&31mvi+mO2 z<@Rk?mpuU%EP=q&LqFl?adS19lTy)+z^nKbHnr)Cb8yY^bhJ+!II)cx>`);m)rMD7 zNC%X|o22%J5~22TuVRzgZD$Dmd`se76cu%-_AlA$$0Tt0C@Nx$MzRO~#rg&V!bZNL zXl_DkJ5)4Rv+?k*s`TdW6Fye~L|JWY?RcI0ghqmq1+MDkU+@B#T*U(|4GV~CN7IWO zn^yS`tWDl8P?4!=KcVzV?E_PO=7504eI~Z4nE$Ynsl%qrbdzKyQ?9@RLZhTFSPxlD z6C2|8Hb%8LfyLB?n!vMNs%Gz2d!TUj3JYQdg@w}L!!I-a%so3qoY1zM!%@@@3D6bg zjQ{lF1&2u~n8{^(dCZ)f=o;rc?8VIl7TSPkoHW%|WBb2$GX!+f|C@YF%~}HdPtx4UH!V7t~A3eIjerB<5czT{i7Sp00hI!nlkk<0@+t z2bNsp+bY}OqozwI@pTFg#GIp%A47SFqyc0tIM1gPZVp$6(EZ1?c7i$uQCtmnYM8(p zfeBlLcw&bgIS21ycQ^;mr<%xeYd;6LR@oy4Dk zJ3cUAzSBEOjQDCH;0f=*kSE@~tF+25J4!P2C|q@jaYHo6^uL>s7W)LI9$fd%R&;Qk z7tYCuRO42e5Y7`G>>C&*+3&=6$5`0B<%fmR)8A|CD&icB zbtNyj8CJQaxv^f0Z_Vh2MFjr3YlPWEL_&(aDhjP^)Wf9H;QIdcVV^9T1YEi3wU}g7 zt%!G#<=KaM70Rb5bW?dM#m{mTZ8F{BrjULk{Fn7>ApR(`PkbA zMe@cglai7I2NqLm^=!R(ySC1}A^~O$OFDegn|UE{^l}Dx^kTPy&C?WV2evc;-!_@n znja{3XPxCeIDYcv1N7BTR!_&Sa+M>D{Nmyh&ZxV0``JUcG*U5m9Zx_2xQ`%ZV1U+q9FlSQTy4L}?0!(ln-Xbil zK6*IgB^#vd_A?Z9x^su-z=FQu%Jud$(8W-!*A4!8_Xi8|LdBQOhI^^vu2Yvhy1y$|M{? z@Wlqj+X6l=&(@7@`f8I#fWI+!>JjmIjJ3oLAIQE*)&-W)QMbE+82J|XHkA9FMyd-3 zs>p#yq$mV<*d8?EAEC1VV?7fs%l(>`wJ|D!6vVKTm?JAne|bsE({C6EHI8#ZMMGR= z>9#@FZ4r5t+yO*2@ReiT)ezQ^?M_;aGE{}=Kk7Tz%{Tj;j`8y`OfAqheBeiv)r_E; zwpjPPD@<|#Ze0=a@0r?tU)p6(KW^V76-ofP*2)_4*j1I1Y`Zn2T4u3|+{z`!W;#B# zv@)?xRpl83XUe;&;kw&~vZAeMQ613hXcsvAhEf=JVHQJbgoFVv8y3@U(u>!+N8W`h zkAvBMe_ri3uqRhFs{g>^U9z5h&Dk52_)^}aKT;}2TNur9<>^jPDYZUn)xnz;`7%VM zU{hHSKMdb-k==K2sPKeO(>Xf)x;v=gW2d9?y7Uy$?EHm+#=R_${Pg4C?aNO}b2*^Y zsKq-;*wbZ{M17wI_9r#E($1d%=_l4fQ{Y$b&e8B$YH!OotZ()`aQ4xX(s=ZQwkj&& z&(`4xf!|Q{zm*E1$*2`p6y=_^j|EAi_GlCr^U&FU92AQheDf%ZSs$ndEnaqlsh zeq$c2Eik~DrD7Q>4Kp}!3LhAKB;K-X5Al{IPVhi4Q=)}g+rh@#)btrZl6d81QRvkQ zXWS)oZLHOGkyR_E2}$Qjt%fvq3oPcRoDuHnF25L(>(DmyJ^io_u_vbQIoixM3AUs% z?@n!H!)vgq)E#4FD&HD!j40*|lw1R?!x`!vArNRxhb^cprXLL^ZKgVKv z25_D9u8!OrW)`ZmCpkFfSNBj!$D({hW#c%n5)&%%z#ZS8@+cVM`-%q zCgstmCw^wh)+;TIF}!SC120H%iCA5JTjOL&vT`}I5+@rxf!OyRt0SPrT!!4D0*D05 zGX7oa;wf1rwNg49i!?4>Z0tCo6Op+8eIcU*TyO+M1T`;ZGBnA<6}67V&NNkVkkcwT zBhn&gK5lR)O$D@XHMQG{8GRuRfADNx?{+k*+`ezDF{}e@kh%#syo&jWtodLz0==^0Y;k=fzxrU4 zmqiN0B=ExU?2q1z3Cb3W^EeuhP0!N(?9x5g!>rtbs&a#zOi0k5I}H_(I}N$Y(I<~` zFfm_)cP)W3#Hg!}a0i9>6IGBUYA`jEtQp`LZRtGOh1nG^(x@%Y+4tp3iBSl|?j+M0 zr8U*62^m?gTF*b<;v4f2$)b#e*aRLfg0!jAK?EN*UW5sFMG!exy?GU?<29Bx$}w|+ zDd>$jGwTtpv9)524Lq`ewKvrWSvQuguA+!)DSrA?B!%G?(2^+eE>_OglLVI2+d{1O zSQp`Kc~de?Lt5$qU^8_i{;x71hs(gTJOPD6PAU{88FBrJS7^0w)eJ0VEA<#b)F7# z8!TsB2sD}Q(1z`qp;x!i2bccF^_B+V<-$>?Ia@(~^c&Vn|jLz21qj3 zz{QY|Aj#Sc_nqKNUmZ3vsz&%x?uee+N~>yZwJH@$lCB<8vQZdUyI66?uhF?3>cq0N zydx{;oX}Z{E|#%xMSe;CbadW=&vcvL570tvo2`_HM(KRV=5FT~g9wK4VFnkky^B-q~2MfzVARMAy6T zJjRcL4+_gJ0#YCjjDv_$t`1rZwY5}4mY&A-OEU?^#Lrd??U`jZIgBHC$k&_~o$JjH^3 zT}6r1{h`L3qtX}tXIVBHoqQk>XJB&yAAoO%Dz_&nz(ZcHN-Bk6K9bB0!+4!Pf}D=R zqyQxhPO#6!jBR^e6jOJlirb4Ppi7VDxfjd(3Qpndv?{k{s)tUa>cJDVI8%Y52*+3APAJm6_M{_ixCR%N(R zu*6@(;@uu({1okZIGIZNcAwsE*H54fUk{!>KtX6zpKZBFS}PuS>5-sFtxVP-^3l> zD1)jj@GG~}2Q1oABY7vT;l|7iASwZ9e2AN~GBD>?BTRm-TO%yF9?gz2Sfp1p#=o(> zqKjpUe(#{0$7#2-hLFRAxE;hvk^lZ4E;W8Vp~DK~GV)88rv0r;N2e9s#svlM+KUSE zB@dNaS$O+#OASu{ccOvx?gTY)YOP_1F!Mg%yP8FjGX4)k15B}}ITm_+Ba|p$X0SYK z(N9r27SokH&V)S~^CLWRNLC<*K;jro;T2qlpMd}8G6t45IT)K)N7F0=F`LJ1wpuTh zd9-(SpxW4<-9ffQ{owaGS{( zcG%`DwG+paq|-sIuONI)>OdrKH4X;v&@I**5;A1k~sG&{o~c=qYqKKU=}HV zxkZ#0+#~t@M>BQc)lpG5&C`j<#uE*e!}h(+bmDu+Z0kvy*L;HvuTS&`B=Oq z`*BdxYA1SY&&@A|u3~R*ayl-_axcrG>mio&Z>&-i@c(u?SHCygEqB=frEuIQqcV1h zYdK~(RgpcHQ+uyEP57ADcxpez-K=fbVr}-hR;WpT-v*`YFwy54=|q+?i*o&8?x0aR zQd{c%$ou`HpVPE+9b+E+d)K|J2FJ^L8DpCfyo3G0=v$cX^SrSh`gxJ5SihVa?PjC8 zN8;Bfvq;5rrVBNJei(FmP<<@t`5_0h9WGvnj8GoiI1*FPO%IpzCYRY~_67$ss;%(8 z6aEri&$ElS_Mf}REhTDOsd@c#25vS(2~944Qk~T-Vbg^{SV4r$y-w)(9g^^uGpwIB zwba!2XQejz7i6yqyUgrfEYWv@G7nT$-Od`!4>#Y+LNX1SqGi{=^3_7&Kd*l2`olF) z`Z$&tr&#Drauz!{U>!PRdd7@@jTN4L$lg)T8~XZTNO|hww{;t*tMcel2g@v3gBzy! zE#1WHLXg#Ii%Ugrr1m{cy*mF4qV~e1&E|x$=cT8n98AEgUw{v6lBJU?1wqddmxUhF5vIWl3)80o=C%yF(jqh*HeUMibuL9nOfN~^@HBm(il=e7tAqOX;ktIh&zz&@ zqAI%6Uq&Q~r%M1G`1D&9G&|?xw{~&2A=c@Az$HO(hI1%^Y~fb`a4HE5{NRx^r)?a? zcmp9)^U$i=b%V_Xd~T^RCMo{z(2J>T=vQsE>TQJ*ulx7S)YwZTd%dgm6za;i)+0{l z$LSQ`^vn#?SbNq->Jjf83BHkd%lp6v&^1s`NlL<3dVr$O76nZVRkSaIoO9AO5b50J zl0WW~^~9y-!z?#JaRXfp=v2J9)ahSbzKPLF7#g!ETi7 zm{2NNzmA1D%A~ttvBWAhehYCjma7p)myly8b##0+yZWD1B4&o7oc%cZA{PkHckpqy z`d@`P5WD&a8=>`uAw9uG*OR%?^-Z#Xp&q@N89eiHuGSf5i(;?Xw5RFqRK)WPVhWO< zw+F${9gW$Iz5oMm61?eomeyMX*`4LjFgJ6uObmEYs2i36f)(s7{Y zHH%39Q8%1UspP8Q$kLC)!C5?nxLP$q@JmjyoOHgN8TKoSdEUWVEO*OX#=a&=^w@F< zw}*+Gf~eTDod4xoR>=dKpwmU?TWeU!FTKo#bQ?_rbYUehGuRu+=&nf-O0%L?Wu37k4$bm_Wb<*YRTmRrQDN6b>amZ+Y%U2RuGn5>F^WE4mKB*M4tMu`pdBQpC(41~A3(fL|23!L+emK}#TW|4fA_x@#sDk$3!QXx8fkAh-$(1a;si$70p z)q=_yFzz=?@>0OS+OCRX#;#}eC~!(p{}#&9`-;vM!(uy;(cn@zYtcJoy|Bu^vDNQG zsJ|6Cu5Ln=UG5 zX^Lou-GGV*te;B?%a2|~xG5OZjQCgzR1W};*27ua97(q*R`W1znoPHE@oF(FKA2RAfD_q&#m@P;{oGpoL+b7pQv zbvmr>seb>G3exV;Z?Jv{C*35A*4jD_y~1B=1PVu ze1v#ZyQ8d_x0L#d9N2rYWjD$E4HVZ3%`X~UrX7bKI=sty%Yn_T#R@u=*Oe_OGJzup zQ<;0#kVXr6u9+wh^sJm-1-y%KOCgVg+uaLYg&1k=B0I_Rd(DXA^h%D23XOj^68^|) zYo8x`Xk9M~M2o{)VZFjF@OwR1L7nkpP7Bh>rO{E^RO;T6A0t6(;ok7*537OsE!|Go z)~Dy@TO#3M#cu~mP)$mT$h%thul2wD#y>|GPFo+LTaHhHFK{iKodw#kcrpoiPmBT%$2J`hO2;#0oWs9dMUI&(-oEjM zO#0ARP+6~(_O+xQIOpbvU&co>NoL6zLO{$pa1bdio@=VE!qg{_8eVWDs;US zdwg!fsSt>c&@-JbW@d0Yg#L5_`O~pJ=Fho&`==zR5J+tz6<^#Z6zRke~Hq z>bq-a%cQyq4!3kNkUmaj+(KOfsLoiV+kgetL9e(n&w*Ow0J9J`-Y83!JuHN8s>N@% zvifL#`6#o>&?ue6k58_dDGSk!Q=s&y^0My-MAv+p2~4NXKBme{gUv(&xZ)H=wQ*@! zYx|+fk9(oznOJi5py!&eOsS)IbZxUav8GP*23ux z60ICosE}V_b(c*gUa*LunirH9#+;f8d)8SG%s#~c$AwFQSQ}9 z?(dv7rgjdFx)9!-<=frxT(i8qK2DBq9g)o8E{R_O<$l|@W!eb7CeXNrZnPAljrZFz_V0U}J!NEr^4+Uih4B*; z;vTEgMsLpVkX@bx;#H*EA|b5YX{^YUw#p-HT zhm>_80dmzJfEb?DBaWqsE=TURZN z$48%K^Gzd-f+n4Wh)j)%@VocW!f3%}Dt=z>*|&6hw){3@kZv|^C@cck_J`~n4n0;# z>M)k{qi2Wk2**ZcH0S4)kG4TpU}zq}_k~=$0V4sb5qpyKuR+CJuF$4!lx&ln+8W3w z&Zvx~Vi|I0pTy-<`Mez&+|NctBg>QD<=0=I zazSGyTo|PHZDsZ^Uv1rmfnPQH%`Lz53I5I@l%0{-mBA#pmyooE$*TLIE$ncPR5!mJ z%^K5F{xAgmKsNx{WDB?cPmBJ)F=l)cg?tied@_f!{S^sN`d5xoAb4hEy3Xptjhlmp8orYz`p%3wg0DhUdmSZqR1G}wkEIi*r8 z2ufc2Jqf%}>`@Oi!6_>*ApP+4-ebG zj^mS&{$GC%t=6I1{55fnlzY}*2SVHkzjk6!lJ3wQrlLmDEMPJg^|51zCd;ZC;-KoR z@H8J0(9vD|;+$r`@4*u;kx`H>yl^^_LR#6?sCO{s2{k)aV|e$sI_=Fy-s2vJ*$uy^ zy>4GoslD%ZH(XcK>pSi$*ua3_~-p(j!TcvT#&I0FfEE#UHASDV(R_ z&eb#FZZ`^(oyH;>-SiPGX`cz37f#knY7{SO6nF$dzhfs0lt?@dtu0`QS8^NOq`s9h zT~^M@&geQ+DXT<18bh|xedo~-Fy}*iUA^%D+6|Xyy;YRvbDAR9pV4Qqqm0QOT|^Sc z7>yx@n`yx%cD9Mcpuy-oQubn^+0%-vw+z~H$~9)kdR4%-4sl_t`JMjRCWBU`@`UMF zktj)Tt!JuQJ@Mf4E#GdYvwOIgQjD$}l0NLjCK%XW?9XT<72fZy$d z*{O8*Mv%oxjU2NYUTCj=YS6v?jA3o>vxCqLxlUn^pGJ{h&*8&$&Fb*u#?@uVg?$1E!TrQ`wfs7o#O|3`U<~o~eu8i)PsmdgBEOJ?j zf)yAcJ>bI;bN5h9%fHu8JAr?=Ie_1uDyP^)iY!3Jc{H!2;2cob+qf_hGHMj{3lL`R z?TQH0^tA*q7O`HNMX;~1A&qaY{k|@fZq)z9_wsH)mRP5b^qqP{Thb`B@1xH!pVU9< zPZyIEi_SX%b~e$jXO)IEYy|Xahjyw;`J|1mKxPgm!&;BE)fGaE%l;^1za1zPh_iE7 z_*d*K479~!UAp*}56SSnOh&T^>!kgNWtKK=gj3z5O}g3;=%>i6 z&J}@fP8LcyEn+}NZQ=#)^mr}dRUke&DBmDUMl=ND+t4f;lxIg)Fwa)ak3A4_D8@5T z!qJb~=+??%#j2r?j7{O=Bhj3xWr74(8rO#0uL{e)(kR6i#+x}2nLSwD9F4`C_8F-D z9O$N;k5>dXM3W36%YRUDLMTUWp5aC;5FkscfkV1UWo&{2NBN5cCFN61g5Fw|#@tME zNUBpha%c@whKTdqy^gIwaOc)&f~Y-VtNg*vI2JCi;c@JrfqIC<@%P)=T*^;@&>`q9 zM;kc{I+$LMW+nFO-F5XR4Kr(f+X&DO_Pq!mRXw3|sP430=N5QmQ zbv1jm)pm2qM@w2gSQ^W_n&EYoWno_`zF(ZK<3-xId&<~>d+kVwv2$70ANDFh;+Lr) zvq!;1QFtD!KG}Hh1p`ls>f1TBN{on(jFPHsiJr^0Pn6lj5;>s!F1_cR`0+i_WoaxL za5y$ec_@MxF=Xkn8RW9}ADxy8dVGJHtjYx2#EZjn>`rq6yE!1eT8bDU7$6uZ?3tCc zr>({6GA$bOi(u&aq*^nF+(+)=Newd?(rc>nU6#*r^Q)9BQnzhyJm z)8)ys9@pF2&f44hk36%|3P1Srl{42{%7*LU8L^Ts>R?nv|cbi<_6CpR%+y{z^;{%6MBrT8e1m?W`_G&wR^k<3=4F{Fn7 zNvjAzNy*dBUeQQhb9g+sQkI7B+(S`8!PnPU-j^!x?&+XFX0zD}B#HusA_pzxy!_p~ zt^MTOyyo+OjKERndf9q9d3ZayyGbEjYa4eTZ)Is|9O&mi-o)%|e~#nfX_=m%IdZc+0o5Qo*<6At-Gs&pS1^cBK>72k6&i>r%q4-ov44=2}aV> z`}?t6T@`*30OqG;XRB!M?&)gntzzxr;o@X#jg(M;L6j8!sQQB#*xuHYYwhjsN$}z) zi3p|`bGQ8YE{=dyb#YQL@Zh?w=X!W>U7XyM6ozm90T^2ncmE87z~Vm#L^Qmeyj{3| z9*!6bKA-UCyMG{o5~Jv1?dG5??I#C6rnB~O@s|D*W>Ts?c23?>MqCefPw&4&^UtFY zX#S3n60k#2jYljKcXyXR4Wy*-d+i^zAUf)~+d0|$tHbvmR8S-2$Rs%u)r7=Wgt(l< zmLt&=NhBVSUt0bKgBYCqKY{T}%imy(*oprMls~oo1rCUlB7Dcr&c~MPsba>p_VPFM zbb{aM(wXvPB^0(lYJcfPNVB54yR8rEmyWuMkB^g`A`?DzXH90>$uXF=Tsbm>W-rGk zGbnO)6c&DMkHY4XSOi`4^nUI8A8>Wtyu7X5Y`G(FDO@hahQYFvqcYi4IXgCN_}fq@ zHga5h1aHftbIG6+Je+>%I}Dd6D!&*LLIint!Bl~nRQPEp|3f-|D$)PW!XFd<-wE|M zSpN?48$tg5@?UcOJ$-(w{g+(75#;YL|0UPo)91I^f64V5LH_>oUvm9DeSWL`J8}v9 zvC@J>p|Z3utfT&FDfjnp$mit{N8XMPFUQBvfRX=OqJma_ZS`2ysiAMpUNK*ukNXfO z!ICG_rjcii$y3ucVND4NN?N*#)Ke|7^?>lGsqdz$3 zLvO)X%fWm#-;(*8x6leb{8Ic=M4TiXw|~O_KDaLH3j31#CG72#{JCLAow)1cOrNb@ zuOnOh`1dyrQOpF>o2OWKJjwhGU*9!d17;x z=&%%ax!0fBKcQ`?=lHBkqsn~(mJF<3pdivP#;bs>e#Rg)LT%qE+anFv!tRhqO)mt@|P}Jey7LbE?*Vr+7 zRQWEJ!Cy`CmsjENUISxj?dj@;-=KDP@o{zYlA^;`q`7uZwy{p$IadyK4(qhy<}!M2f>Ck znvuIZyl96`=6&_r*eQUESHlmznHzEK70ftfDfkq&HzEUga6P8PvXuWpkXVJ0UhUJGfg!sEsgyd$HtKD2{cr)Hmb*9EQ!*5SJ zY&0fK6FE9FE}jz?|NV!23Ddq&*UKTQAbdsPka9h{d3jCk+R{bAv=e5fH=G#9w;gz} zQ*5u=odp8ELIQ;XGBLB(h|sH(Q?b^-gV#I9lV53da3$9S*_80 z}#%}A0Tr5){wca(c!|l0k>O_fx*sfGMtIsT%7wh`XeEQ_q z3o9!o%ExXaJ+M8JVl~QGlfN`R;H}Vo-CgC@v8D>!Y#h#xHEwU1^$tENcWq3j`s>%O znrqA)g(>&ndSBnFuD4|?fA(gR5*5#LR4$*mf<*e0(Z}kg51A^uExl+Jl4pO%B5xKg z*~qu`N$89f7lxmj^GqTD%kUBNB^N4zl^!us<#%bvZy2gF0V#n=uy6ks; z?1#?h;Yx{Px?N1lH|W0z*uG{H-(~eJ1HPI=agTKQPL(?ijrpiB{e?k_x)yh(nRkzZ zR>0g(dRta3Pe1Wtar)5VnD$v3HKGNt+*O?i_pEN3dn&OgTO{p5=a^5=e6#!5H4-@$ zsTmgaR8t=_){UtL#P7*ozj4-AeOuKFj#tH(<&55Jf%L6oJ{{jZsIrmrs@UEu)cps& zI-}CI@4R@XlKI_<`SlB~eXh|i6idw5aBpFEyHHf!sCz;52aY}4zkjMIbIfwm>YGAJ z>d`&7&262DDR=oZc)#HV3$Yi4A$>ZcAN#i|_2|%gIwiBJERy3IrLyV!cL?lj^Gk>r zyJ&FN)FUw}!TryA>z2CYz$>i|$<`PCr)h!}wx_qBCwxVLOlC}3xKP7D6Fx5g%k#0T zT)14jfA~PXn!6k9r+Irxkr`z4h(-!(p6(w1&`A%>o%KJo0V@e`(Nv+AFj6q$db#^} z+H!|2r@N;yq(ixAMvX~7U%3Uw6ZZGCjJ+W-165kQDiQ%e%b1Mq2>XUc77)kYBrE6+ zsR(mSLQAlIbT;lK!YnD+k3q(St`UHP1d6RO*PEkYsIIAC!u9j! zy_ZbQQepU|WH6SFD+#t832ap0ADCRkQwnUXr<3bHkb`*k*wEU6t3m`L_#!e2q+Wl1 zmh|6j^1s<+NbCP8bNz2N`TqmiWGeIjlx*^Em<;bw5t-*d)>BG<$`}71noYK)Q*2l) zdwV$+Y?H}Rt!WfF8(XTK9E(k++K|~~vMtm4-)!>#jWzRcP5;*~{}81Abr}EH^WQ=K zkwm{X_?KM2QsW=X|B~w;N%U)jf64VLHU6>uFS-7aM87upf1Of{q=m zoSnS=<+Oi3ScJ<*SZBJgb8~`5klJIAc^N=rU5SAHSXU0O@i)7^RT9d*iv;N2h zYVW;dX0d-k;k4~nt=2x7WO-bxk>CEr-Bd1V&azq?$pf##%Ox1p>*>d$g0mY+9)G-2 zzFwAEqN{FdXO{rKo4RtC6SVZkk0}dFlUL|p4IXk}1`kwy>uascWS?DFQYBQ8ryyVT zy^l3J<9R~!yZmRPnm+YZv?q88xnBu(I59_OLX19t@ICp$(-&XVPn0-xTUpWfN?H00 z*9Fru)YJ4%hE49c(PI~JO2JKKrDnsH_tt%r9zP6c%9M{|Esqf$Joz!S^2~u8^%T9q zWkdcyme5Qr*WBqjsdR3`bDw9v>$~#&Ul%$re&4nHvzk$v-_x$MlqHkuFDbq`?V!{$ zbgpCb_^W5$PCmN0=EL$&Qpry)P7dC`*|#oZ{zs9sl3CBV=7&VXX)T|x1$I__k|Zr3 zU953^3|sDuoo=M5R#s_!p1NT6vbYCJf@f|On0P#OUQd8s)t2)jqNxzDixO*wc2u-1f6`iaBT3 zwWnJyM_=2^9ACd^KeKmUf9kv?fv+SCGDL5*xUYUV<+$6X-EvtI5(}4^A2}45ZV?{+ z*5uN`sns7x7dsVo^|l>3BJ#e$?2NbWyqe8h-5x(pVDy(U{j6`kjkTF-+p72J%V0Qp z$rwi;kHD9*Q_Z7l^gqkgsFp-rV!mKi?w;pRB@*UXuYP;>#>&Z}k7-r&oUfWM@0zCd;2iQ|CNpRnnk>@_09-+pU{`5`j_DnhXn#P*QkIq^ddbfQ-rra!^G^Si2#B2R3 zk&BmN#A7lJW}d2vxO1)FUF*Ai!T_J>H~&}Ts#-VQn-Q5{kT6eof(QKBNbTZC*QmvY2nQ7w3ts=Y`A!sn54A6>wc5l{1XZ7$$iWsAC3Szkl0tUBc_} z((A!IysbI>FG)u_5FT!ok${<}!JR|~#Rea(06oX=N^xo0)oN36XteS)IrJ@cGh z8cpkJPi~Z)o#yC~3 zw^2ybJh^d3=FX6q(6amh!{QGOyUdFMkKf;28h^oaW{CSOiq6$?F*3(kxpm$LnTwW_ z#V<^<(#de=WNcDu`t;;RviM*xyYJ@BQ5OrJ)LLlRb~iL0i#G30G2zd7UM*0!T{1b< z@JF=A>$`JiOImMF5?yBa=}yN@3mug=kL`~yySI%#Gx+=&%Z8wOuCY^dr|*cn%kl=0-V`e zwny@Fw%hxwY@vsiEFHZrO`l=Ms)bL*c3bB+9;lD{I)6r-)1)&`zHUFQ6iL=r z)>m1i7-@Q9t%qms5?S%Nb1x*M=4&Sz=_-mAmMu3Zdt$z@adDelg8U)w{^W8o+oVuc zU&^y4(emU)?XMJ-<{OXW3lC#IX_H(fEg2edH2;*?;&r}uiaWeT4vsTfI@dn_QQ-A0 zCeK^Pu3#1^ODe^xXHJM1I2qmbg8ZI(E^d?erDc~loUILz*)aKCnfOy z^9Cy^k@wQ$C%WG_o$3`OD^ep+TIl)B#MOJ%TG1Zcm;JK?4$jk)2wy3@N3c`mXyDFg zGo%-GJv9l9%uP5uDsuEW!3A0i)*i{f9CA?m0so=LUJHE1M3&ITX{&GV7y z@=P&qIF|d+!S?1ewIa0{OJeqWavLukS^jYT^T&!U?vCrKM>)0HJ@7V^w;4UNO^l?- zzGD6UQQzVRarakJDUr8pj;zT&`Z+Uk$+8K4tF5!931?m2|4=6S;Hoj&@NvJXN(aBD znC=}lOKhI3gA{`?y&-;_VCa~Aol~@StQ5^-s+LVDwm<12zv11%U7I(&cV7_K#xi~8 zx?tBlW43X_sF`P_R$CjLJ6c(=Hezo0X==tE$H;=w4`?S27uQxlXRUT_n6vmY-ySRf z_tVvuWe6^C7E(OXRS;rBGubPgK1EQ~RakM}MEjJ2#+|e&6Q|CM&o?RY+u$zJR~JzH zRQG7u=zzTv=(P=YU&f@#q-H*v%1Br_j=N}a>i0($lr?ch>#SYMSh@SS znvTT>JQ75rQx7yI^v(*kI^4X0t22rlc3?-62xV%3eQ1T9_u_?Ac7IaLhL_wX&#rjk zv$SYkFHMtU^OJ9Uq9vBb%30+)YsOOK-q7b}TA6-%;5M=TOz+H{C#H)V?^Yo5sjZfs zEK^7_Icb@ozAH3q)4NdlbeU&br-Z`}%y=Uc<>1x)&SplIc87?^>V4v2s|7y=Fy<_M zI3s~PS=dP@?1WKK@Hpw|=NnV*l(ZGT4B3-?b!BJ*-&)lavXqg7@Sc693xfC7%1>6m zXsUQB%!c~L|ANGk=+a)pUh2lrLk~YjYSbvXN zH6bzZW5NYl*mY)4;ttiY+1wUey8GZOmlwAom3He5A%{IWsyN+w5NVQp#u zl<_}SzgX2`c45)(%VrnGUA8*Ee)EsjXKrphf8;O+egX>Ta@nJvV(qhxbBxOKE3TLv zbeFm#KdbZTYNvZfGO2GZ8dTqYClzrbkMSw*nQr;&!`^*DmM*8yj7w-ApK2k(M5^xN6pL`ddTekpLU6%l(UaVbU>Cn)z0jJib*QjH?S5 zHuz+^XUX|5E8jd#KigJw;r7%WrYjT+M48*y$xH9Ec*77fxik4{RNie5GwQCo4&&la z!c%{I{`RISqvDX?Mje-js^|CZy)10d#F|~b`?&bYlZRIJ4DPc$7`^R-)7>LVi7VO; zAI-ShB-yrbp3OJg_-T=e7dxAKdiusknN#{(T#a6 zkS{fPcYFWLZ9BWnojKN%6?^ipG%ue#jypRrxFu%&YK2w0N}4u?UfrRUA75VLpNLo84*%>`RR1waMz=HQZeM43ZsPq3Z)>k#@7t%9++Ezue?&gwX5v=az&3di zqx2^F#q1xfGx&hPl{t(_|GA3?(fY_^6dZUIme^gg#AX=34~O~x9LoRy{*y(+r28MO zz|?fqjs3m6xvsp2DHxRD4MH7t6L&2gbv^juz{nCzLEQ{r9Yi9w8%G{M#^*d36nyWJ z(a!}Mz{FJ;F2^XmM_h;%pc#k6p_72AmK1pQg2H4;(KsYax)g&bGdZxKNM}pYC=5$7 zY)6u%=yV2ba&j0{s9>@z$#fWrXhLRksC0@H17IN(DvQlKQ>m5|suYz%^n}e{Dvfua zE=6S$t*I;y0%bu*28|`fV9}+RfIE{!lVae2OqvuEP{4bL3LVy!4A@O2`Y_?QBiNR~ z>r0%WKf)pUK^?+iQy9dVfDhLQhYGmh84*STP@pXxP@=P`e>zjx3<4I6XUQT-!S*h; zWKlSX2vMX%2bcg1Xvtzqv0!Kb!D4f81cXclA`uOs%%np#=o8+j0XPB+fQM(m1c(e9 z!Xzle49FxJ2WN*f7?~xUp$!{20h9o2$)Jz$(I5g5GKGeev?No2DHNy&%8`LjWFR?? z56?GoXgCHH%YXxMk4>)q2t(0XiEnU;XDC0l@Jf$D(qCVm_U8N6LI;;4ZshtaU7t7 zC7B7^;?Rc1z%zqG$Q={r4sZxMG1(l%g-n7*u)~7HwIs6u5fBBCTsY$&laM_GkM2JW(ff(%eS)FBuIxlAF%iYHnWDv1MB0tEs% z!zu(1P;h_~a1RuTN|$00X9gi{!xSSph5Cbac#ohk8x#>ZiJSU_)X{(-!+29@Y!2XR zNdYcVfSZIq&?y{{P`C%uMLfMgVZcln!=?t?20i=WEGSD!9 zl=7q<&ck*Fr5fpt8b??L2EYW3W&)*Iz;}G=g$Xi5XcCTt+CqhKKtrf>5Kg#9rGs$7 zcmzIhP4Ew82{=QTC?>!Hu3#G;K5)kIkSjnkI#@L}$P)Z~hLBByJg5**N7OTTbVv9| zE*j7Q2m)#i+5z;(iNgfp3`Aj|N`nwF*(eskQ25>)9as*ug%My@1Oos|`2gxTZ=eTS z4xI1EnE-%TA)sH+!`QGuvXLJkCBu#eM*lgbkXhRO0)-x(9psW_dysyr9cNP zX<%SzC}@BS4J;cCEE~}tEE^3h88K-T1aLcqa)Hj!K@)j+qmc022t20=!pZAP2V;fs zk>Yev3OYn5M0=bwDg@AjPN8#v8G_5J$p26K)8F9PXi_fWi>28ciC|nP?9_p9$?~1g=a=IvOMJEKHyy9cWKS&j7d) zMi^`ndI$#CqLE054E$gqZGo1AVJ4F~1l@2NAoD3EaP z=tdbpQz}Y3&=g!c@E!01ug3u6!+=l%JR6)rS!pz0I~w8o|7eE>l?G-P+tEoJ#0LzJ zB?BWkH263MokqA?2Dozu;6(v`Fz68F;TUia=f?!4VgWs=AX|85fx%&+n*e^}+;|2X z=7YF`Ors3LkMxMJ2Iot-d@wW&aEc?gnhtHTjtTNcz(CnUdkyfI!)}E|;mJBdKcGF0 za13ydkTc)~@`KPZ@(XW%uqfrls|I0h#Jydv-i*(PJ0hk&SH!@&Sp!Vff|0SG%>vp~REDBK7f1so?1 z_lYwwj7())vVf>8u+pe5Ao?&RAPYgN5i%hPpjHGyS>R?^;C}EP3q+L#q7OY$@G&GM zAj3oLmMmZ;3)F=`6UfLyHUmppbXe68q6q2^Bx7Na$b^_5>^=*~46s;KSOCL(V3H83 z5FQQ08SW6Iz&Wiu-$aok*fcyotOj6U5-^qxShK-+F(DGAqQ@qqmLUjSTEUsX0XWG9jm9akfxIYb zgv20Nl$?J!55xHb9$FJ1-3T0_9;I>w?(iAW2J#R=9}o>?3u;D2`wi*{^q*(M79otB ze}|56kioy6|7teBkMkdJe#3fXHVFIozQ11+bHSPa0|iIwfA9Zaufc}myno{QKZHL_ zD_A~)frkTc9S#L_nIH^+>hEVH86jVPeFjkAKY7b8AP5xbgk}FLN{`I)C)U4FcI5u= zv&MeEbMn{g-%iojjLU0@v!UHk|VpBMP`G$o86o>;pun%P>EV_AajPUjhIy48@4+oxAhXQyz zT)TsBz!B-VScBjc%XmiYQKV_$NeN?z3j+)mfmCcL9NK{sj(T zSa5v=aWx?p@VF~h0cEM+@DUgk*c{$%OkYt!c6hhZTT;R6^ZKK6paT5iIs^bCqJlsH z06@ZmOojLW4lp%j9fYPZBw!57df**aBMitV@p^%qhh!M=24)Kd;0+Rzia9STOm_G- zcENQAGM@?y4;YB30vOPkxQih&0Rv)WL~pnX#E1&K#D2g@-c5A8R9M0hH!-k*)h#Xw zpupg;fZWJF0zHT+hzryQSgpfY5ZS?D*icg;hJ~;Q;~_Y~r!6210bzh<5XixSw*rC! z&z@t}g$-0^!`LWXs6D6&3>bw4g#Hhs0kb5;5_B7d2@_k`2gpQ(nq(S;ZgAkq3lxA2 zGz^EK4P*@o!Nv3;OqT|1Li-8@$jm_-OueuvfGQ0l4LE?qM=_v5dIW`x4M8BA4xFGN zgJ{4G6hkOr8>ojM4hwV+I4fvCLRORDK3swbU~CR4O5Oq)3J3yXHa4gm6bLziL5X+` z66H{WBn_l95jLz4$j}B$co<;>uDIa}q@O?oyc$6`5IkZn#DEkm4T5pV`T++ZhJyle z7(oGoYq$j{5ZxgYOayLZ!iZpU6fO}2vTejAKmj<4sPJZoHiv{dg{yH$u!41kIY9yY zfQGTrWWkCYK;wNfni0&=!XNAyFM;i8>~32GJ{SjDTOL1;`OvLcWP;`s+iUP1|J0eMn508}^t?J+q7 zhhZ7PWjbVvu`Oygto&i+08&mydkIPc{RzX0OERcMxgaKhLV!yX9yXv85m zYiXF~rXfv;4jB6bt#D{Gl{Ac8=%`?rz~fBjJk=y@fxE$ zo_$CA4a*J~0Rur4X~Oxy8XtHF`ppE^vT)qt-YBDNuqJ5h8Ngojc}(;HxR``CsI15_ ztiyy86OtkfU^$LFBHzRrFvNrs(GF(H1_Q=G>W-WNCRz%@FY|B(9MQ}&Kvfv1tPD1| zT@sK0+Ys=9c?4{zMODF^G|B-QR0jMJ{+)?3iK`%j(2%_2MX4|?!rg&zBcYIR$QNh? zTMlUKm?Opx62QC|8D@$yPeePo6T?In;^Lq1SeOBTt6?Vx$yA;Tz)U0TVelL&6d*m# z!XZ$fh`9m>p#a_z5k__b0pW~IKuB?$gzyhca9D)FX95av8)k|-L9hk$6FFoD1`P-s zEE7OLcg2Lj1#6&yLjuE*WKe+p8JH2`&w>bp3Ce+dWP%+;i2`K<07!NwaFX!C7`wm~ zNEzxn<}cs?b`rP-12T)aF08m8SalxGzbfiS61<3$t0cr|a3Z5&5G#rPDyG6v-6$|8#FhDHGz_HQY z!X^;b!E9KlpkRKn1R@U$A>b+20lJvPAVdzlD=%9~#VVX13v4eBB;X2HkRbw$pa4{a zMLhUA5GOzj(iw1<$Xmb(CV{#{Cx%0gqplI;X93624Px?vhBgSoNSrj}N1*|ZifqO- z2K*i$3XtO`LLL?xOx(C2gaU$J$OiEw1bK`^=P4zoA>fZE(V%oF13V@DDJ7V_!a0yo zmRac1Sm4sI8x&w~3k)^7R6oN zE-(@#Jcw`@3J^m9f#EwikPFA$H=qFIV}aCw(}x{5^gd|&PzEs209q0hBnUvlT}w7v zeO^KuM2(GJ4B`y{3FEUdM+%zEpn^W2?Slj0M^vE`V}mKeTq+bGxk(s#=!r^#fh)WS z3~GQAybj>!pbBr}fMAD*Z-c)9X~YXmjiD1k2oT^5-vgxv`$O#Az&;#oFoLYH(RyQu zz-EwO`wf*2W)3_AjCpXO6$P;au)l-Ddqg%6j4GNV%#Mm zP=Gy10EpW_n3kl&O-%VRF*OTF;w~YvdxLpYq$=iQktiV4;MTAw2p|K!7xZLfavt3( zC?iwOwAIt&`1A1CpK03;wXWMMb}kpYke z21nn4{`~7iVlwk$^f~0z!O*oyZ110KnDsqNf1|JuL|racn4rE*h07sW|9yTur+vv zLP^{P7Xnj2{YA^b+w}nGAkgT4L1$rn5=KHW7{spVN2qMrX~(bw4m_g4$`|w$;NS)- z?rQKhP#Mq+q#X`05nu-tm>df5l?}6Efz?9Z5~c^k4?@6(`HEBlSt3Az4&o*t6XgJM z^N`qv8KB3;C<_X(Mnda_Y6;_@DkHJ+jNv{~29p>F9+iU-6EG6khYiRP;U&xk{WFH= zh&g7Zaesk<;s$V0tx>dL9}|X0y`unaa6aH_-~d_x(t;)2E5xaQuz=VTWmrZ4Ea(UG zfCG#IZVL(!b7Q!IXrkKzTfqj_;yV~n%^}nTIV7G{fCm+z8mG#FK7_AFRAD-R2_eRC z58u{+wgRU>=sJ=BI^og*A5(yrGy%KuVFg0P;fV!!kcy}8bR;kaULfyu0wn-T?3h6$ z2ZoSPP81m2okTGQ2ZUaWP+(MW=)*(?(a4tY0-Zme&jUsO`3?sIPdhHWdDCIZ$kSso z@YV|lCogYL|0Tq`d1c^nF?bIw@kU!I(x1Tm@)bW-{C$u&P>0D>z(>{KmBFxD;l1r% z&Duko>*V0*4cO3ze@f&nB?l{H1$YC#gO?PIcv5W@zKueT4WfZns9b2OnM_Nf7Jd@M z1!2dv5kA6(531=~yK?{f=So;>?Cr_*wslm{$9LJf5FN~TSimY$LC4z~UTv%D=HPP*4-{qYdoACJu`m=7aQCo}&v`(IvK^51{2L?-|GYo+*6Q#Xwo6*VgAuO6u+ zX7-OyO~Rs&HT))WFe;Fkr2jg=B{P4QBZb1j)cTB<&bx$miqEY{+kdSgb~kah46A`*cXC z@95k-k7k3|kmR_zfm@ZF`g~gCUthm`BT>otn$`!2Z*v2xlWW@|n2804+?@jre7g^5 z&+Dt&8{Om5{+ZF>ytN@U>SloP=Y>MmT3-z|uTMBO!_=|E{J{eigKDRd_5dA?e02Kg9Ud*(UG1@2zG zDMo?PyB_;*O$!qcjEcE*EB(fJ9sZ!~YCZbebU|_PQKz0CIwt((g~sKRceL_%PqWIo z8f;;fbG0nv+CACLvnM`W=^MPDWxtWL-;C{MVL!?Z7bw)VMyStP8Byx#5>+7?5?ZQx z-#%*8=nPWPjB`C2m)|vctYKA~9iBbqg?h)pb}Lu!b8Ip33q_q;(y{b;S7cf;81LsK z9!}{DHKIjZ%3O{dJuPZ*dqu^=!4|{d;EgNvr4v>SrAX)J>i9>jGg*FaRViiW(r?Y= zQ%|j0!X=_aA9auW$jMKC`rt|Y>7cyRCWkjYd#-+1KQ!RH%`+X}qSH>kHqX8-r#Kb# zE-DQz6LEP~)NuUf7sj}Q)Kv}Ux1XeY)U#$~I~>`aT3dJDV(+Z7uv->3Zv)$-cYC!x zxS#23_x5}Phb5$Fz@5}wC@1!KztPFv{RMN5wB0G1G+j5M#8`E;_=_C1t$HWjHsmb} zHJSQ-jCR?|15@B-bFq$=nIus|fZd(2qQob64>auL*{rh|d z<0h5I6gMpmK0B188+^8!*`c*=E&00YP)nuIw`@*l*WJ@BpBbfcuDyYrKDFcvx}V0t zw;N2Z9xm~1YHck!UaWa`@jcfSd#=o$UMj#`vqc;&=I@#nRc;EkQfKpUD-K8oy*z zN64y_IZMW`HosCbUdmRmc$#R+>f-ROyNRFr=$oG{c04A*_j&Av9kMOSDT`XZoYOz) zqC9Hjj`&Mco=@I>Dtn*u)?I~1s@l&=U#ghH5frietfeuE-)fh=TA5L$$dR;Qb}Qcv zMF$`G(&us}t}VJ}FN}4*_*BqvPnn@yljTmq^x9jdYxjJolzmFmq(94#WLnBCP&jlV z@$8CIy2>G0j*Bnec$pLRI4ygciHl6L{g=$;?+4oA%!f9Z9a=ux?pP;#M@8=U+iteg zNCCkSMkX!(DM7PUvzaY-OuX}1ZHu%#G+hkkuaoURhnJaIe-d)MkXcN*5vK0OXj>85 zUC631jXztNTbOim!wap&h*y6>kO^R^^Q+M^{$+^y`5}(b58c{gFk3) zvM&qeQ*A!YO=GtSH9X1njhS%W>C9Jhr31Ytu{}wUWfj({^YWrt?4jjxOWt%k7~kt% zR9RF1;FZ5n_Wn7aXAWIdo4jGv6+X$w;-gI&>mIZh=k^NJ=TCc+k(->y;rqBFVCA7* zj4xs@rDGZnejX=bvBpt8H~Z$;z7_YgO9ywxYTIWg6!(fXogRIwH>f1%)zE>f)7Xr( zct^XjETMt9w*~3~awolc&*(V6yscK~O&6nM-|@{4V(Kb}?u$&?lI@VTxHx=+rFM3# zrAN;C*%hmQEZ&M4)$Y-nd9JQw+xtg(-*nqK zIH!~4CZXx}SSw+0>@By@`VfaR`36_jOcw^lMvXHu+!wL)SX}JVar8{SL8lw{rp;d{ z*4#Jxz?o-aYvyg8b>iMc&-y68a}R@Z=%YW2`6{TM>5OVkmd#eO3~H8sU7T4^9p>e3 zt(gw-QW;%(dXrx(YzTE9IcT_N?qs*!0fN0(=;qO7d!DnP{ZFRHY zf0JL}S(cn9krq-X6d>tc7NT6GmJ^&}6+S5Za;n2L&W-FZH_UY>ZsWWD%%d$PYWcvU zd1=bYR_%wC#BGAp2DM0RrfyYp~`{4J^cX(q$T49yru+L9quA~+!Kx7c3d;W z*-To0&lBkw*3j69QSF&u`RaAfxt_`mc)0m~^OES>d-Dzso%H*>Mt#-B)nlt3s%yj7 zM4r#gJpMp2-)Bn~tIHuvlv?%uL1|za$4&6G?$iCbGFMKlU!!bssYzQoG1YX}?29@p zP8ZqQl|@!pYv0J+9xujJHg%ps*5Brp=ffHuJ)iAHZyg%fy>aq#UEk5-D`@F$M<#7% z_z#GEnY-(7?gUavrg+z>g>NlQ4h3}1>F5&MBoR5jgpzr0w2Jo(#dT{E@2wtPeyIKB z^99F3;wvAz&wsK1M$bvN?su2&oh!XZoAhN;u)=GDsyy31=cVJKa~0^$v*PLeLr(%) z%pP?~IK1;+EttG_aE*1?W)HWP=El;O7Zi*xywE>?q5e#zXUcw~4?C&LuHD~mG5yf) zR`a%FzGD6U%y&z=!#JaIxH*Hniav?^37KXNI{N3edy6^GQa-=tY|ic=T6q}|^X6=z02Te?TI?@nCJyS8~fOr5%|`=gS-mXU6* zuM^wYD6KH?c3e;&e_>v&NglW3%@vltQQEE1Z-QR!*e>jntl-gU9X1&K{KUGIQyWxX z%GIympVcW_a!-BX z+PCm&%(*FEtNnEy$J=xUde^Mz)I8!Yo^Uj+>_;10%9r_Zx#M%moT6Ukr!BQ6E5ft0 zlKb^z7tcxY?(JTh?e08#;Dc~4|G@#z$+!5d#_RJ9WCw`)3A~&bG}nAomO$3HpeZf% zo|ghH`nhIPOjow2TsWQbI>bG7jmbo1(Ujov-&%6ND_+{=DD-A-o7DU2cB3oJ+nlHh zlW3E&mSyJ8c%;1e9KUmKsi;x-+x9Wh`&Tt(E1Mos>h^jj@i0HA%xd6rOyQty^6Bqe z#a}!8IP}AF%9RUu-t{UvB!_BE2wgcn>1|X@PMDL3O(*UPrAml3v~qpG?&+%!#m>8A1JipTWBSFM?5xKB!r|HOifob>kWc?;&1 zf2i8t`=q+RweVG-@=*VrA1jKbhIUN;n!PYH&qT!L@rNP(KJ#t6_uMccZ`|Ctw04p7d&q&_*zy|=t>?Yo-zC!4$G-d&@1K2x4tX;!n@(#~~!sW|yAEppzr zF?pvhpLSD!zh$w(d8-TVFJjVf-Q6|7cPFv+8}ro%16StbBI(7{L>J@Zh4F{qN87ar z9zU>QYe)UTUd@K+m+9A<7JNNcVtz5!JA0a$!L6nhPLIl_oKBxOa3sAl^`@rlfoJmI$Q?bBcn}npBLxlGARgFz+q+d7*$_NZa zzgQ>ep5x+YIP0_B+{G2;g)SW$d)D{R8+AQb?&)dL70LUq`RwrAOQ@P2AjEP#Mv%to8lo zF7I%rc*m)8gU9=m+Tka%>6!Bm?I?DTEtwg2rq3a0Es4M8yzuWBu}O%W2osgXRx7%Xe+vbFjU}YeS|VV@OZ>%AGecHLfa; zzAmZ=Ykt^Wz>pC*-d_CbhD_F^FVs$Hv5tk|W_fFad=#?OhiWDq@YJ9BjW080ev3fQ zvcmBA9sXfHqkahIZ`-%)+9tkpNAd&?Dva-%o$h`|EpUH+@6wfv9}b#+S!O<_dyA=t ze*?+=i`6KhrGktd?Yksjb?Q3{bVp>C-{pVU>LV=ieC*`RmD8s7j3!G4jgJ)Kv$0xx zu_snOaidMo6|bfi5t~4!tyZVZ?IkDPa0h*6x{SV?J8iIE>#o(|t=AMsZ<&;rktgf4!xOMj^~=*y}}Z_`@s6}?QK47ujerCFCXPzX;P6G`_dqXTrXpvwdZTm zBXabtJs+2KMCG%;Onmc0GyAOlF6TPMj)HMI&JS+Q5I_0j;Ip;Xnm2lE22Zq~D`>rY z>}%qIcFnft$s*65+S;}L>gMcI?**@R{+RRK_n7yYvIYHxMMYOF=n1vYlmX z;&j4t^wKxbA3w1fupT{dQZ$0O#@;WmQRT+I?u{P|WixVxg>E$K#Hs(d{lxQy&rQ|H zW%qjPR5K5(h}dvh$tSV4!P23Wojves@9vb_->2e->SZNGKzaCLK^fD0*< z+GTiqXmZA_knq06xhfw%*BPF8>2I5+)IY|>GVJmUS2+XP=ndC*in7fEyu#u#tfzjO zdHkG6SMGpmU24l|ru(^DFUR{CXeagXC8Uk2@s&0kT6wOSSr{wQa&BjTa?G;KvA2vn zGxApm9}z(>Z$E)%7N_&F5$CbqrRTGxNO^y<%Y52fpfy zS3~SRYVWL%Gw+R6>|WqrMf2_+Wo!1m=RAib`8Dk3mpcBOdkg0$Ypl&NAY0lwt7)Zd zuhRd%m7sV)_-b{C@_7?)bckLS9@acW#~k$ZE{Cge2CzQ0LO;3 z*B_Ydb5RK?iw8dpJnAzNzGdvvl(eSYOL*v_P5aWCwpQh`mknF>_hm`_P%6F4eYAA{ z%s$18U9LAw>!Oc6itG^}8`?LIuXAJRAAK;N`u51HMG_I@x@^5W7FXCYnL^Jt?pfhp zkbL2b#o)r(Z_4jfeGZ&lu_Z^?zscZPbgkj(Yt|AAD+_E7i9Fx2yVrm{xISdV!}!d` zB>(AGYY+PspY5Lg&e-)HxAF03qv@g7{3qO1wtMn?j5l9(+r;ZX#uo1lsLm+bQZ_w* zY1xnKcCoh_Q>NVvmUq<)47_!0u%h<8z@7DKt}j&uS^2CW#aO)|m&TnrQ&etkh}NCN zs#PuMGfZ7NpKh=6&+{O+@(3)9QoR?059jRY(u2OGVRgZ6;lW$eJ zFlv)xeTQGok?F;2*qv$#+h+H3qtX9a3|$9+zf%!Xbxqy@b*h zl$g2hl5v8~6SV~EF%49U;IJXN6Un)j(?x>U1sIuml`6+l!)XY!) zQG4R{>9KO+3VNDZY65{D{5Q^LCTTJ6_Z*Fy+bw>U?sDwFSI+fdrDmDP?Cr}xzMf!b z)~(M!3D7EU=UY$RI(FOaatRs!!4;9`Us8ltu;u&*ErU448A>*(iz!obD%k8zv^gcc z<`)u^M(kas`7m00^@N@Z$Zh{{Tp zM+3LML``lr-8~f1H(p;mO3aB2ge>P%^u_$s>A!C#ngsG zilpmjSI0h!t)P$36A@`mI(>2I(9m@b{o)oe)!Pf?W*JG1FAQC|>RISiyRCA|K1{tV zG|rm8=vtKOtkL3u4gp(h;^QRl1a75=H;!Ia<{vE#N3|$k1@kTb=yWec*w6m&&osEKQ-b zb1U0G%jAdF*V1`VAZj@aS7R+nu8qzu9t_z-mmNP{!z8$s_IbSk-*5I10Bkb zf|aRy4qbll9-4L=wodNx9cTUez0aYl6OlfG)_Xp$v7B2^7r6gubCCScSG@LoD0O$T&PDZ*8FQUG7!_USe(K3@(^lC(-fQG=Ve5n*P4Bb9)qAT; zUQV2M@Ot))vr`LKH(wBwS#D}7R?WD3?sP-v<}Dr%7KX<+y*l7C#&q3vHHLy_$cu!K z$Ky}>SeK?duYSdUjgl$vZDN0BVo>fYj>X+o7W+Tz_V0C4o?#p_<<8p&C7at-S27+c zAASE?y*#T&^R{FGBdFw466?{Fm)UIzW=Cf{Dd*J8nR}L&T<{@CG_|V2@9W2bF9W9! z<>?)*ic?y9xzF%*#{R@Nu8!H0*EL^=?ta(iInIVr{wlP;L|MZ5i{R&H>5oXu_ckA| z+#K_%#M#(Z{v$<}lbU*)&AgFpUJRz&^KFakI5Gq>*AEFDN~eaHzRJHP~KB{yicrs zr{!Dr`;wZQdxu0?Lu|{kL-sbdcH1u2nDJMmsT-VSBg%u|#as4YX!{3C`dhyz@!Rv8IiB(Zob#Nl z5mO@T{rXxm*FbW)lyzcfQb%d;9Pz~Zth@F1e>|*VoGx6`A<MwqN$bCbaf6~2B(-W&7M%ijFtnU>% z*!O6=*|(IOj#>4SFMjh6elM;fl=Mt!LT{K#esh7@wt(@)1{v$zzsi)KQs_6kDZPC_ zBY2CS#_^YiLz3`y)~p{Dk$<@_@;~`J>(7s#z~g~`_t6uVKYy`9)OqibRo5<>t52=n zsZ27A_SiVCzD{Fo`H!LP6+31~-O(4?-M+VxY@20Mc02Ukx1^_D+FQOI@T`4d$QiRK zFHY{Zu*=dNA1!~pREr-X)og#M?j+A#;IBI5r$1AA|5?kqXP$)29;n`Xq9o+uL@#O6 zZ9~&HjVdo;8UE!we|fX|Uw^cN_P_0;9q>pxQ%wyXnP#Y}!y~UGRXR&UgRQAfg%1ld zHK-aY_|XnKt{-d)!@e?Xp2JQmJn0C#%5cIhO?c4yuRrU-pdyl6p#kGBKkvby41dx3 zm(P2U{`7ed8=FQ~K?j>no7U$)=*=V__^`s=Kqj*I<)j6Em7^z)vzTf&N&DQ<5c4*v ocaqxDQ?<2M@3^fnif{6$^PvJx|4G $@ - @[ -s $@ ] || rm $@ - -############################################################################### -help: - @echo "usage:" - @echo " make apply: create $(DST) directory by applying the patches to $(SRC)" - @echo " make record: record the patches capturing the differences between $(SRC) and $(DST)" - @echo " make clean: remove all generated files (those ignored by git)" - -clean: - git clean -fdX - -FORCE: ; diff --git a/lib/openzeppelin-contracts/certora/README.md b/lib/openzeppelin-contracts/certora/README.md deleted file mode 100644 index cd85ba3..0000000 --- a/lib/openzeppelin-contracts/certora/README.md +++ /dev/null @@ -1,60 +0,0 @@ -# Running the certora verification tool - -These instructions detail the process for running Certora Verification Tool on OpenZeppelin Contracts. - -Documentation for CVT and the specification language are available [here](https://certora.atlassian.net/wiki/spaces/CPD/overview). - -## Prerequisites - -Follow the [Certora installation guide](https://docs.certora.com/en/latest/docs/user-guide/getting-started/install.html) in order to get the Certora Prover Package and the `solc` executable folder in your path. - -> **Note** -> An API Key is required for local testing. Although the prover will run on a Github Actions' CI environment on selected Pull Requests. - -## Running the verification - -The Certora Verification Tool proves specs for contracts, which are defined by the `./specs.json` file along with their pre-configured options. - -The verification script `./run.js` is used to submit verification jobs to the Certora Verification service. - -You can run it from the root of the repository with the following command: - -```bash -node certora/run.js [[CONTRACT_NAME:]SPEC_NAME] [OPTIONS...] -``` - -Where: - -- `CONTRACT_NAME` matches the `contract` key in the `./spec.json` file and may be empty. It will run all matching contracts if not provided. -- `SPEC_NAME` refers to a `spec` key from the `./specs.json` file. It will run every spec if not provided. -- `OPTIONS` extend the [Certora Prover CLI options](https://docs.certora.com/en/latest/docs/prover/cli/options.html#certora-prover-cli-options) and will respect the preconfigured options in the `specs.json` file. - -> **Note** -> A single spec may be configured to run for multiple contracts, whereas a single contract may run multiple specs. - -Example usage: - -```bash -node certora/run.js AccessControl # Run the AccessControl spec against every contract implementing it -``` - -## 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 by running: - -```bash -make -C certora apply -``` - -Before running the `certora/run.js` script, it's required to apply the corresponding patches to the `contracts` directory, placing the output in the `certora/patched` directory. Then, the contracts are verified by running the verification for the `certora/patched` 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 `patched` 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. - -For more information about the `make` scripts available, run: - -```bash -make -C certora help -``` diff --git a/lib/openzeppelin-contracts/certora/diff/access_manager_AccessManager.sol.patch b/lib/openzeppelin-contracts/certora/diff/access_manager_AccessManager.sol.patch deleted file mode 100644 index cfb6cdf..0000000 --- a/lib/openzeppelin-contracts/certora/diff/access_manager_AccessManager.sol.patch +++ /dev/null @@ -1,97 +0,0 @@ ---- access/manager/AccessManager.sol 2023-10-05 12:17:09.694051809 -0300 -+++ access/manager/AccessManager.sol 2023-10-05 12:26:18.498688718 -0300 -@@ -6,7 +6,6 @@ - import {IAccessManaged} from "./IAccessManaged.sol"; - import {Address} from "../../utils/Address.sol"; - import {Context} from "../../utils/Context.sol"; --import {Multicall} from "../../utils/Multicall.sol"; - import {Math} from "../../utils/math/Math.sol"; - import {Time} from "../../utils/types/Time.sol"; - -@@ -57,7 +56,8 @@ - * mindful of the danger associated with functions such as {{Ownable-renounceOwnership}} or - * {{AccessControl-renounceRole}}. - */ --contract AccessManager is Context, Multicall, IAccessManager { -+// NOTE: The FV version of this contract doesn't include Multicall because CVL HAVOCs on any `delegatecall`. -+contract AccessManager is Context, IAccessManager { - using Time for *; - - // Structure that stores the details for a target contract. -@@ -105,7 +105,7 @@ - - // Used to identify operations that are currently being executed via {execute}. - // This should be transient storage when supported by the EVM. -- bytes32 private _executionId; -+ bytes32 internal _executionId; // private → internal for FV - - /** - * @dev Check that the caller is authorized to perform the operation, following the restrictions encoded in -@@ -253,6 +253,11 @@ - _setGrantDelay(roleId, newDelay); - } - -+ // Exposed for FV -+ function _getTargetAdminDelayFull(address target) internal view virtual returns (uint32, uint32, uint48) { -+ return _targets[target].adminDelay.getFull(); -+ } -+ - /** - * @dev Internal version of {grantRole} without access control. Returns true if the role was newly granted. - * -@@ -287,6 +292,11 @@ - return newMember; - } - -+ // Exposed for FV -+ function _getRoleGrantDelayFull(uint64 roleId) internal view virtual returns (uint32, uint32, uint48) { -+ return _roles[roleId].grantDelay.getFull(); -+ } -+ - /** - * @dev Internal version of {revokeRole} without access control. This logic is also used by {renounceRole}. - * Returns true if the role was previously granted. -@@ -586,7 +596,7 @@ - /** - * @dev Check if the current call is authorized according to admin logic. - */ -- function _checkAuthorized() private { -+ function _checkAuthorized() internal virtual { // private → internal virtual for FV - address caller = _msgSender(); - (bool immediate, uint32 delay) = _canCallSelf(caller, _msgData()); - if (!immediate) { -@@ -609,7 +619,7 @@ - */ - function _getAdminRestrictions( - bytes calldata data -- ) private view returns (bool adminRestricted, uint64 roleAdminId, uint32 executionDelay) { -+ ) internal view returns (bool adminRestricted, uint64 roleAdminId, uint32 executionDelay) { // private → internal for FV - if (data.length < 4) { - return (false, 0, 0); - } -@@ -662,7 +672,7 @@ - address caller, - address target, - bytes calldata data -- ) private view returns (bool immediate, uint32 delay) { -+ ) internal view returns (bool immediate, uint32 delay) { // private → internal for FV - if (target == address(this)) { - return _canCallSelf(caller, data); - } else { -@@ -716,14 +726,14 @@ - /** - * @dev Extracts the selector from calldata. Panics if data is not at least 4 bytes - */ -- function _checkSelector(bytes calldata data) private pure returns (bytes4) { -+ function _checkSelector(bytes calldata data) internal pure returns (bytes4) { // private → internal for FV - return bytes4(data[0:4]); - } - - /** - * @dev Hashing function for execute protection - */ -- function _hashExecutionId(address target, bytes4 selector) private pure returns (bytes32) { -+ function _hashExecutionId(address target, bytes4 selector) internal pure returns (bytes32) { // private → internal for FV - return keccak256(abi.encode(target, selector)); - } - } diff --git a/lib/openzeppelin-contracts/certora/harnesses/AccessControlDefaultAdminRulesHarness.sol b/lib/openzeppelin-contracts/certora/harnesses/AccessControlDefaultAdminRulesHarness.sol deleted file mode 100644 index e96883f..0000000 --- a/lib/openzeppelin-contracts/certora/harnesses/AccessControlDefaultAdminRulesHarness.sol +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import {AccessControlDefaultAdminRules} from "../patched/access/extensions/AccessControlDefaultAdminRules.sol"; - -contract AccessControlDefaultAdminRulesHarness is AccessControlDefaultAdminRules { - uint48 private _delayIncreaseWait; - - constructor( - uint48 initialDelay, - address initialDefaultAdmin, - uint48 delayIncreaseWait - ) AccessControlDefaultAdminRules(initialDelay, initialDefaultAdmin) { - _delayIncreaseWait = delayIncreaseWait; - } - - // FV - function pendingDefaultAdmin_() external view returns (address) { - (address newAdmin, ) = pendingDefaultAdmin(); - return newAdmin; - } - - function pendingDefaultAdminSchedule_() external view returns (uint48) { - (, uint48 schedule) = pendingDefaultAdmin(); - return schedule; - } - - function pendingDelay_() external view returns (uint48) { - (uint48 newDelay, ) = pendingDefaultAdminDelay(); - return newDelay; - } - - function pendingDelaySchedule_() external view returns (uint48) { - (, uint48 schedule) = pendingDefaultAdminDelay(); - return schedule; - } - - function delayChangeWait_(uint48 newDelay) external view returns (uint48) { - return _delayChangeWait(newDelay); - } - - // Overrides - function defaultAdminDelayIncreaseWait() public view override returns (uint48) { - return _delayIncreaseWait; - } -} diff --git a/lib/openzeppelin-contracts/certora/harnesses/AccessControlHarness.sol b/lib/openzeppelin-contracts/certora/harnesses/AccessControlHarness.sol deleted file mode 100644 index e862d3e..0000000 --- a/lib/openzeppelin-contracts/certora/harnesses/AccessControlHarness.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import {AccessControl} from "../patched/access/AccessControl.sol"; - -contract AccessControlHarness is AccessControl {} diff --git a/lib/openzeppelin-contracts/certora/harnesses/AccessManagedHarness.sol b/lib/openzeppelin-contracts/certora/harnesses/AccessManagedHarness.sol deleted file mode 100644 index 50be23a..0000000 --- a/lib/openzeppelin-contracts/certora/harnesses/AccessManagedHarness.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import "../patched/access/manager/IAccessManager.sol"; -import "../patched/access/manager/AccessManaged.sol"; - -contract AccessManagedHarness is AccessManaged { - bytes internal SOME_FUNCTION_CALLDATA = abi.encodeCall(this.someFunction, ()); - - constructor(address initialAuthority) AccessManaged(initialAuthority) {} - - function someFunction() public restricted() { - // Sanity for FV: the msg.data when calling this function should be the same as the data used when checking - // the schedule. This is a reformulation of `msg.data == SOME_FUNCTION_CALLDATA` that focuses on the operation - // hash for this call. - require( - IAccessManager(authority()).hashOperation(_msgSender(), address(this), msg.data) - == - IAccessManager(authority()).hashOperation(_msgSender(), address(this), SOME_FUNCTION_CALLDATA) - ); - } - - function authority_canCall_immediate(address caller) public view returns (bool result) { - (result,) = AuthorityUtils.canCallWithDelay(authority(), caller, address(this), this.someFunction.selector); - } - - function authority_canCall_delay(address caller) public view returns (uint32 result) { - (,result) = AuthorityUtils.canCallWithDelay(authority(), caller, address(this), this.someFunction.selector); - } - - function authority_getSchedule(address caller) public view returns (uint48) { - IAccessManager manager = IAccessManager(authority()); - return manager.getSchedule(manager.hashOperation(caller, address(this), SOME_FUNCTION_CALLDATA)); - } -} diff --git a/lib/openzeppelin-contracts/certora/harnesses/AccessManagerHarness.sol b/lib/openzeppelin-contracts/certora/harnesses/AccessManagerHarness.sol deleted file mode 100644 index 69295d4..0000000 --- a/lib/openzeppelin-contracts/certora/harnesses/AccessManagerHarness.sol +++ /dev/null @@ -1,116 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import "../patched/access/manager/AccessManager.sol"; - -contract AccessManagerHarness is AccessManager { - // override with a storage slot that can basically take any value. - uint32 private _minSetback; - - constructor(address initialAdmin) AccessManager(initialAdmin) {} - - // FV - function minSetback() public view override returns (uint32) { - return _minSetback; - } - - function canCall_immediate(address caller, address target, bytes4 selector) external view returns (bool result) { - (result,) = canCall(caller, target, selector); - } - - function canCall_delay(address caller, address target, bytes4 selector) external view returns (uint32 result) { - (,result) = canCall(caller, target, selector); - } - - function canCallExtended(address caller, address target, bytes calldata data) external view returns (bool, uint32) { - return _canCallExtended(caller, target, data); - } - - function canCallExtended_immediate(address caller, address target, bytes calldata data) external view returns (bool result) { - (result,) = _canCallExtended(caller, target, data); - } - - function canCallExtended_delay(address caller, address target, bytes calldata data) external view returns (uint32 result) { - (,result) = _canCallExtended(caller, target, data); - } - - function getAdminRestrictions_restricted(bytes calldata data) external view returns (bool result) { - (result,,) = _getAdminRestrictions(data); - } - - function getAdminRestrictions_roleAdminId(bytes calldata data) external view returns (uint64 result) { - (,result,) = _getAdminRestrictions(data); - } - - function getAdminRestrictions_executionDelay(bytes calldata data) external view returns (uint32 result) { - (,,result) = _getAdminRestrictions(data); - } - - function hasRole_isMember(uint64 roleId, address account) external view returns (bool result) { - (result,) = hasRole(roleId, account); - } - - function hasRole_executionDelay(uint64 roleId, address account) external view returns (uint32 result) { - (,result) = hasRole(roleId, account); - } - - function getAccess_since(uint64 roleId, address account) external view returns (uint48 result) { - (result,,,) = getAccess(roleId, account); - } - - function getAccess_currentDelay(uint64 roleId, address account) external view returns (uint32 result) { - (,result,,) = getAccess(roleId, account); - } - - function getAccess_pendingDelay(uint64 roleId, address account) external view returns (uint32 result) { - (,,result,) = getAccess(roleId, account); - } - - function getAccess_effect(uint64 roleId, address account) external view returns (uint48 result) { - (,,,result) = getAccess(roleId, account); - } - - function getTargetAdminDelay_after(address target) public view virtual returns (uint32 result) { - (,result,) = _getTargetAdminDelayFull(target); - } - - function getTargetAdminDelay_effect(address target) public view virtual returns (uint48 result) { - (,,result) = _getTargetAdminDelayFull(target); - } - - function getRoleGrantDelay_after(uint64 roleId) public view virtual returns (uint32 result) { - (,result,) = _getRoleGrantDelayFull(roleId); - } - - function getRoleGrantDelay_effect(uint64 roleId) public view virtual returns (uint48 result) { - (,,result) = _getRoleGrantDelayFull(roleId); - } - - function hashExecutionId(address target, bytes4 selector) external pure returns (bytes32) { - return _hashExecutionId(target, selector); - } - - function executionId() external view returns (bytes32) { - return _executionId; - } - - // Pad with zeros (and don't revert) if data is too short. - function getSelector(bytes calldata data) external pure returns (bytes4) { - return bytes4(data); - } - - function getFirstArgumentAsAddress(bytes calldata data) external pure returns (address) { - return abi.decode(data[0x04:0x24], (address)); - } - - function getFirstArgumentAsUint64(bytes calldata data) external pure returns (uint64) { - return abi.decode(data[0x04:0x24], (uint64)); - } - - function _checkAuthorized() internal override { - // We need this hack otherwise certora will assume _checkSelector(_msgData()) can return anything :/ - require(msg.sig == _checkSelector(_msgData())); - super._checkAuthorized(); - } -} diff --git a/lib/openzeppelin-contracts/certora/harnesses/DoubleEndedQueueHarness.sol b/lib/openzeppelin-contracts/certora/harnesses/DoubleEndedQueueHarness.sol deleted file mode 100644 index d684c73..0000000 --- a/lib/openzeppelin-contracts/certora/harnesses/DoubleEndedQueueHarness.sol +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import {DoubleEndedQueue} from "../patched/utils/structs/DoubleEndedQueue.sol"; - -contract DoubleEndedQueueHarness { - using DoubleEndedQueue for DoubleEndedQueue.Bytes32Deque; - - DoubleEndedQueue.Bytes32Deque private _deque; - - function pushFront(bytes32 value) external { - _deque.pushFront(value); - } - - function pushBack(bytes32 value) external { - _deque.pushBack(value); - } - - function popFront() external returns (bytes32 value) { - return _deque.popFront(); - } - - function popBack() external returns (bytes32 value) { - return _deque.popBack(); - } - - function clear() external { - _deque.clear(); - } - - function begin() external view returns (uint128) { - return _deque._begin; - } - - function end() external view returns (uint128) { - return _deque._end; - } - - function length() external view returns (uint256) { - return _deque.length(); - } - - function empty() external view returns (bool) { - return _deque.empty(); - } - - function front() external view returns (bytes32 value) { - return _deque.front(); - } - - function back() external view returns (bytes32 value) { - return _deque.back(); - } - - function at_(uint256 index) external view returns (bytes32 value) { - return _deque.at(index); - } -} diff --git a/lib/openzeppelin-contracts/certora/harnesses/ERC20FlashMintHarness.sol b/lib/openzeppelin-contracts/certora/harnesses/ERC20FlashMintHarness.sol deleted file mode 100644 index 2f989b2..0000000 --- a/lib/openzeppelin-contracts/certora/harnesses/ERC20FlashMintHarness.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import "../patched/token/ERC20/ERC20.sol"; -import "../patched/token/ERC20/extensions/ERC20Permit.sol"; -import "../patched/token/ERC20/extensions/ERC20FlashMint.sol"; - -contract ERC20FlashMintHarness is ERC20, ERC20Permit, ERC20FlashMint { - uint256 someFee; - address someFeeReceiver; - - constructor(string memory name, string memory symbol) ERC20(name, symbol) ERC20Permit(name) {} - - function mint(address account, uint256 amount) external { - _mint(account, amount); - } - - function burn(address account, uint256 amount) external { - _burn(account, amount); - } - - // public accessor - function flashFeeReceiver() public view returns (address) { - return someFeeReceiver; - } - - // internal hook - function _flashFee(address, uint256) internal view override returns (uint256) { - return someFee; - } - - function _flashFeeReceiver() internal view override returns (address) { - return someFeeReceiver; - } -} diff --git a/lib/openzeppelin-contracts/certora/harnesses/ERC20PermitHarness.sol b/lib/openzeppelin-contracts/certora/harnesses/ERC20PermitHarness.sol deleted file mode 100644 index 08113f4..0000000 --- a/lib/openzeppelin-contracts/certora/harnesses/ERC20PermitHarness.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import {ERC20Permit, ERC20} from "../patched/token/ERC20/extensions/ERC20Permit.sol"; - -contract ERC20PermitHarness is ERC20Permit { - constructor(string memory name, string memory symbol) ERC20(name, symbol) ERC20Permit(name) {} - - function mint(address account, uint256 amount) external { - _mint(account, amount); - } - - function burn(address account, uint256 amount) external { - _burn(account, amount); - } -} diff --git a/lib/openzeppelin-contracts/certora/harnesses/ERC20WrapperHarness.sol b/lib/openzeppelin-contracts/certora/harnesses/ERC20WrapperHarness.sol deleted file mode 100644 index ca183ad..0000000 --- a/lib/openzeppelin-contracts/certora/harnesses/ERC20WrapperHarness.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {ERC20Permit} from "../patched/token/ERC20/extensions/ERC20Permit.sol"; -import {ERC20Wrapper, IERC20, ERC20} from "../patched/token/ERC20/extensions/ERC20Wrapper.sol"; - -contract ERC20WrapperHarness is ERC20Permit, ERC20Wrapper { - constructor( - IERC20 _underlying, - string memory _name, - string memory _symbol - ) ERC20(_name, _symbol) ERC20Permit(_name) ERC20Wrapper(_underlying) {} - - function underlyingTotalSupply() public view returns (uint256) { - return underlying().totalSupply(); - } - - function underlyingBalanceOf(address account) public view returns (uint256) { - return underlying().balanceOf(account); - } - - function underlyingAllowanceToThis(address account) public view returns (uint256) { - return underlying().allowance(account, address(this)); - } - - function recover(address account) public returns (uint256) { - return _recover(account); - } - - function decimals() public view override(ERC20Wrapper, ERC20) returns (uint8) { - return super.decimals(); - } -} diff --git a/lib/openzeppelin-contracts/certora/harnesses/ERC3156FlashBorrowerHarness.sol b/lib/openzeppelin-contracts/certora/harnesses/ERC3156FlashBorrowerHarness.sol deleted file mode 100644 index 1c76da2..0000000 --- a/lib/openzeppelin-contracts/certora/harnesses/ERC3156FlashBorrowerHarness.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: MIT - -import {IERC3156FlashBorrower} from "../patched/interfaces/IERC3156FlashBorrower.sol"; - -pragma solidity ^0.8.20; - -contract ERC3156FlashBorrowerHarness is IERC3156FlashBorrower { - bytes32 somethingToReturn; - - function onFlashLoan(address, address, uint256, uint256, bytes calldata) external view override returns (bytes32) { - return somethingToReturn; - } -} diff --git a/lib/openzeppelin-contracts/certora/harnesses/ERC721Harness.sol b/lib/openzeppelin-contracts/certora/harnesses/ERC721Harness.sol deleted file mode 100644 index 69c4c20..0000000 --- a/lib/openzeppelin-contracts/certora/harnesses/ERC721Harness.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {ERC721} from "../patched/token/ERC721/ERC721.sol"; - -contract ERC721Harness is ERC721 { - constructor(string memory name, string memory symbol) ERC721(name, symbol) {} - - function mint(address account, uint256 tokenId) external { - _mint(account, tokenId); - } - - function safeMint(address to, uint256 tokenId) external { - _safeMint(to, tokenId); - } - - function safeMint(address to, uint256 tokenId, bytes memory data) external { - _safeMint(to, tokenId, data); - } - - function burn(uint256 tokenId) external { - _burn(tokenId); - } - - function unsafeOwnerOf(uint256 tokenId) external view returns (address) { - return _ownerOf(tokenId); - } - - function unsafeGetApproved(uint256 tokenId) external view returns (address) { - return _getApproved(tokenId); - } -} diff --git a/lib/openzeppelin-contracts/certora/harnesses/ERC721ReceiverHarness.sol b/lib/openzeppelin-contracts/certora/harnesses/ERC721ReceiverHarness.sol deleted file mode 100644 index 3843ef4..0000000 --- a/lib/openzeppelin-contracts/certora/harnesses/ERC721ReceiverHarness.sol +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import "../patched/interfaces/IERC721Receiver.sol"; - -contract ERC721ReceiverHarness is IERC721Receiver { - function onERC721Received(address, address, uint256, bytes calldata) external pure returns (bytes4) { - return this.onERC721Received.selector; - } -} diff --git a/lib/openzeppelin-contracts/certora/harnesses/EnumerableMapHarness.sol b/lib/openzeppelin-contracts/certora/harnesses/EnumerableMapHarness.sol deleted file mode 100644 index 6155193..0000000 --- a/lib/openzeppelin-contracts/certora/harnesses/EnumerableMapHarness.sol +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {EnumerableMap} from "../patched/utils/structs/EnumerableMap.sol"; - -contract EnumerableMapHarness { - using EnumerableMap for EnumerableMap.Bytes32ToBytes32Map; - - EnumerableMap.Bytes32ToBytes32Map private _map; - - function set(bytes32 key, bytes32 value) public returns (bool) { - return _map.set(key, value); - } - - function remove(bytes32 key) public returns (bool) { - return _map.remove(key); - } - - function contains(bytes32 key) public view returns (bool) { - return _map.contains(key); - } - - function length() public view returns (uint256) { - return _map.length(); - } - - function key_at(uint256 index) public view returns (bytes32) { - (bytes32 key,) = _map.at(index); - return key; - } - - function value_at(uint256 index) public view returns (bytes32) { - (,bytes32 value) = _map.at(index); - return value; - } - - function tryGet_contains(bytes32 key) public view returns (bool) { - (bool contained,) = _map.tryGet(key); - return contained; - } - - function tryGet_value(bytes32 key) public view returns (bytes32) { - (,bytes32 value) = _map.tryGet(key); - return value; - } - - function get(bytes32 key) public view returns (bytes32) { - return _map.get(key); - } - - function _positionOf(bytes32 key) public view returns (uint256) { - return _map._keys._inner._positions[key]; - } -} diff --git a/lib/openzeppelin-contracts/certora/harnesses/EnumerableSetHarness.sol b/lib/openzeppelin-contracts/certora/harnesses/EnumerableSetHarness.sol deleted file mode 100644 index 09246de..0000000 --- a/lib/openzeppelin-contracts/certora/harnesses/EnumerableSetHarness.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {EnumerableSet} from "../patched/utils/structs/EnumerableSet.sol"; - -contract EnumerableSetHarness { - using EnumerableSet for EnumerableSet.Bytes32Set; - - EnumerableSet.Bytes32Set private _set; - - function add(bytes32 value) public returns (bool) { - return _set.add(value); - } - - function remove(bytes32 value) public returns (bool) { - return _set.remove(value); - } - - function contains(bytes32 value) public view returns (bool) { - return _set.contains(value); - } - - function length() public view returns (uint256) { - return _set.length(); - } - - function at_(uint256 index) public view returns (bytes32) { - return _set.at(index); - } - - function _positionOf(bytes32 value) public view returns (uint256) { - return _set._inner._positions[value]; - } -} diff --git a/lib/openzeppelin-contracts/certora/harnesses/InitializableHarness.sol b/lib/openzeppelin-contracts/certora/harnesses/InitializableHarness.sol deleted file mode 100644 index 743d677..0000000 --- a/lib/openzeppelin-contracts/certora/harnesses/InitializableHarness.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import {Initializable} from "../patched/proxy/utils/Initializable.sol"; - -contract InitializableHarness is Initializable { - function initialize() public initializer {} - function reinitialize(uint64 n) public reinitializer(n) {} - function disable() public { _disableInitializers(); } - - function nested_init_init() public initializer { initialize(); } - function nested_init_reinit(uint64 m) public initializer { reinitialize(m); } - function nested_reinit_init(uint64 n) public reinitializer(n) { initialize(); } - function nested_reinit_reinit(uint64 n, uint64 m) public reinitializer(n) { reinitialize(m); } - - function version() public view returns (uint64) { - return _getInitializedVersion(); - } - - function initializing() public view returns (bool) { - return _isInitializing(); - } -} diff --git a/lib/openzeppelin-contracts/certora/harnesses/NoncesHarness.sol b/lib/openzeppelin-contracts/certora/harnesses/NoncesHarness.sol deleted file mode 100644 index beea5fd..0000000 --- a/lib/openzeppelin-contracts/certora/harnesses/NoncesHarness.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import {Nonces} from "../patched/utils/Nonces.sol"; - -contract NoncesHarness is Nonces { - function useNonce(address account) external returns (uint256) { - return _useNonce(account); - } - - function useCheckedNonce(address account, uint256 nonce) external { - _useCheckedNonce(account, nonce); - } -} diff --git a/lib/openzeppelin-contracts/certora/harnesses/Ownable2StepHarness.sol b/lib/openzeppelin-contracts/certora/harnesses/Ownable2StepHarness.sol deleted file mode 100644 index 09a5faa..0000000 --- a/lib/openzeppelin-contracts/certora/harnesses/Ownable2StepHarness.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import {Ownable2Step, Ownable} from "../patched/access/Ownable2Step.sol"; - -contract Ownable2StepHarness is Ownable2Step { - constructor(address initialOwner) Ownable(initialOwner) {} - - function restricted() external onlyOwner {} -} diff --git a/lib/openzeppelin-contracts/certora/harnesses/OwnableHarness.sol b/lib/openzeppelin-contracts/certora/harnesses/OwnableHarness.sol deleted file mode 100644 index 79b4b1b..0000000 --- a/lib/openzeppelin-contracts/certora/harnesses/OwnableHarness.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import {Ownable} from "../patched/access/Ownable.sol"; - -contract OwnableHarness is Ownable { - constructor(address initialOwner) Ownable(initialOwner) {} - - function restricted() external onlyOwner {} -} diff --git a/lib/openzeppelin-contracts/certora/harnesses/PausableHarness.sol b/lib/openzeppelin-contracts/certora/harnesses/PausableHarness.sol deleted file mode 100644 index 5977b92..0000000 --- a/lib/openzeppelin-contracts/certora/harnesses/PausableHarness.sol +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import {Pausable} from "../patched/utils/Pausable.sol"; - -contract PausableHarness is Pausable { - function pause() external { - _pause(); - } - - function unpause() external { - _unpause(); - } - - function onlyWhenPaused() external whenPaused {} - - function onlyWhenNotPaused() external whenNotPaused {} -} diff --git a/lib/openzeppelin-contracts/certora/harnesses/TimelockControllerHarness.sol b/lib/openzeppelin-contracts/certora/harnesses/TimelockControllerHarness.sol deleted file mode 100644 index 95ae406..0000000 --- a/lib/openzeppelin-contracts/certora/harnesses/TimelockControllerHarness.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import {TimelockController} from "../patched/governance/TimelockController.sol"; - -contract TimelockControllerHarness is TimelockController { - constructor( - uint256 minDelay, - address[] memory proposers, - address[] memory executors, - address admin - ) TimelockController(minDelay, proposers, executors, admin) {} -} diff --git a/lib/openzeppelin-contracts/certora/reports/2021-10.pdf b/lib/openzeppelin-contracts/certora/reports/2021-10.pdf deleted file mode 100644 index 22df9c61e6a9f74b29f90b6e36bd3d04f99756f5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 92882 zcmbTe1yo$kwl#`tfW|#EP9V6uI|O%kcXyZI?he5e#%7W})3tcirxZ{!N&b1b_Rs6_QNzEj&Q;b@;j6ygSO<%Cel zc$D84g8d${LIf#piO%?yi}20WWwyV@N#5{KxUj@YQnv{vgqtyz{V+(wu;wD9`$;8% zo&$&EMDd8@(bvH+7b0;>Kgt-2%Ku8o_2S)Atu9edgQ|O`S&+l|Yw!<63%?B?h z^k-o`O{aOiNiNu&7Oom@67CNE8|EjitQ`Kvofg)>@6Av{o(N-pxL{{66u3`Lfm!Ch z@(iORv=y9ROFF>^jimeOJNeUN6sr{MN?F`tS;Rp5%u!!EIp-AHrpL`Vn-MpgAcHaE z&ibyw_UwfZ#^*dB$)5a8=d}|R3o>iEZO>{XTyGVJe=4`1w%sbo#%O6lqdO|fFc1ea zqRMH;hAJl|Mj$9!poPo79`2$7%i#_h(uKA%#J608s_;zK^x_Kc=uh2B;gkfwsN7X# z>dymJBFCF*-NQIY7JAbkxA((@>>&{=0*|xMENN_98zeyl-$@yaDYL3UR%8u*Gb=MR zOc!kWGz58Iw)`vL8_K3K%i&@K#@?zkq`6y;5@-J;!txXgv4vX%!=md^aex9#>0DCw3Y z;#f>w1-F^dyRCv!J19SSBQEvsx?}qCHiXBx?{RupUUcTw0p+TrBk+84Dk&aWSFtY< zX$u(NNIpfpD)FZiDvPCe28j(Imya(!s~S}-FVO6Nre^ewF#N&BOsBly-C-KxpJah1 zhP0~FY>0_UsCk^N+8k^_lW*p|wt>zn8FbHGos6L3oAOLEXU^>63zEqYsyw+d{v@y> znpHqnS#P7^Rpwk)`_0fLa5$k_`G;p*T0Io`M%$@0{gO*NHSc(WE|*ipW!(s@uN0#e ztF5hVG%&w>G?8RY=?t#sS3K*dyj6pt6z=DWY@t?o^Ha)}*3=YOhA?~@+IVX~5Lryc(i=OzZs-yc912-m|i9qq8rUu zuBbbD2{_D}pW$k#!76!!1#^;(_N&C-zx#RpE@c+a(cP{+-cLpx#YGI{4kR6=q4CV= z(_%&gX!kwL^PZ4t#Ff|k6n~SqoN-y0`4Z_g_ya90{Fo$Yo^<;qdlRN8C&;-ONE(xi zHt$(7uGCSlcFAn0FV@5mwp^c;iJJjjNZ=YrJ1ofS2w= zH1#n?Fbvdr2Uys2lQ)Y?K~qxcNT~*zv;98rXzAZBk0@(rVD@UF6=D&ZL=F-j+!KN8 z@2hxfr_^ey<`#U0hF7$4$HEe}QXbOZ_r9H+vet1@lO2f{Lr_L!X4;779ABsp#c(Xq z29z#A>o2yt>g`M@voHhMp-q+XR#*w|gno6U)gla(%lrI%b(4@D<4Q;2K`Z`gQGRKi zT!n{DbA~BkE&3!2Yp!xY+NHHj{N3kOwtFhzHM@>D+HnGer6lK*8UPwB*6CtPeNtcN z2Yc4KA;rVdBGK!?jOLAf1>d5>JEYAR)@7lRCi;4-JU2ZP1nwB1irda{_Z19Rwu?HN z_P9gUIrEo5Pcib-(z0{=(2kEgcjXJs6}rEd`mghdMk|166|DB%#85=u^jB(@wN&)W zaVG)o`oYYAgNqhZReiM*Hj4pBsW3BMhNNumSMGppY|iH7LV2c!v@3D>D1N^E}&-aucj6(u7HnzP)lqDIT8K3lmNCHMAv=3se=s9Tbs zzwH@!n;15_<%RYin)y^E)vZTwea;*5&wtyvr+V-@lyzf{+?23GbcuS1DQQzge4|8i zQR2b8QEu!P#Y5+I@qd&&VG-<;A>_9)b$N9=D3n&AaGv9sLp$YHrR}L&{(MXScxF)S zb~;?y$ofUcnmzB;OX{4WTit2u$OapqjQV~-n82R^osv?L1+0D-QqymGI3s82LUOE>fRWi~kqZ`WZ@_;u za5H8QX%!(S>~`piB_^oUT6lJ!zGm6AF<}?Ho zTjPJ>jE~Y^i1H6E`CIrvCQOVhjDN5A$Ikqp80H_)BI@oeuH^gySb#h{e+?fmdIN@! z3Xon{5XcCmH!}D*f54cJhW|LztIHW$nix6%bB#MA8}Q@!fI$Cl6|=Mb+w||gOlcWt z8GwxJ|3*oF`!}U!{A=U*?>45tHqQTUWB#x)G5p*1G5*K#Z%6))`q!iX0>+sCI`_W@ zV}Hk1_OLer{@aCrWX`@$v-AF3*!%H$HdD1Pffza!pz(m$j13kP1w%b z&QZzU!04kJ5ffJnBNIh&p?_K=Z9m|jz1?5*2XuCH`H!xIES#O>O&o>oZ0zl9O+KcE zHz?%(I7DNSNvD zl3=$EixQ>hbbI=oZ|#K1qevVhah##d&&m1BVVY7|kbK!d z5~F&^*8rE~01>iCODBkvzY{We(YO7OU(_FNw6jGHHY3-?&dBn*?PjsuAf@5>xY%XUczqqv>0~ng$d(TK6b8SM!1tz{9mhqG=8p5>#Hw)y1DzU)eL|$9mzips^0zBxOHL?4v z>6`M1()bbE0F>fy9m}+IZ+h0g+6krAb%txxK1(hW7zttaY$FG9|-!_BkO2H4N=ORy1xMvX~I1r37`;I#N-6_2_ulmmE5 zqMQ!NhkjYvhA-(l)mY{$rZ{#ALygo2*)bLrG-h4$*_v?k$o+AxZovBn6 zu&VXY6<~zcbYSW|iO5c-r`XqdyV}vFsVut2|NRzFS^%IBz#-(=>wAgDef338&rLpG zO6s|nar#P8QwPyK;nq7xn#)2G9Eyg4uJ)hGC{Lp!)y4?j`4$#HY+M{*| zdt)=dRCiERw~*+r9q7){X?y50oO0U(x-JwQg9;&4_vE_k!TrHdM344D9%ufU%zR(C zhm1yn$vN5K6Ti;J+Ge&lL(btNdY{6stCVX@&$z9R+poRormk*55N{qm_SOMklBUjR zBzd4fUtXt#p=FraKmuOWPF>Fv=Ew|PtIdY+gLLd`%qL73A~u_Acd0N_`;e4_f&{|w zF|;C4x7*zE>;Y`ipz|~l5~07hpoE5x@j6RS;V3t9lB2l^5>m3c>qHW)KxpZy8xBhr zgP&FN??GWA7`v_zDTkz-bGpBPQ07TrJih77i|NX972~Oa5Y(UXJS2oUA-Rv}B&Y%S zie#9(@OD+8I)k@0mt%6mg>Va2*}r1wxr@4!Q4A64#q`Ra%Wq-`f>j}U@8%s)IVth0 z{ye6#Ba$@}+t?IO-`#57dq5>^|D93U2qushzQVgRbAL54&`Sl$z|Sr(I`C(fT-<-{ zcSSY25zL97b7cpN_C)OXrh7ZRQo{858|zCrZOXY}dWosFA}SyKm}-qP^} z37g=4?pq8KTpL}T+8^bR%TzhU1s$;We zi=K5oaNYYbrf2czd(x1I{Xss1@2g(^p+ilH+C{Mrk=HN^tot>Rix?P@cN32|3-n^x?lvQ@P^KfNG z*RGk+mV929<@l6_bx?#jrlbdVsWolwUZHpUK5Fa@JTE!w_xlTL&20Na4nyPndMnwv zu^e1OH9srb!=ead`Z~tI(}`&!jwrR8wtu%yjY{Jq6eP_`c{UdLk}-l@%@ z+D<;n*>1Xz@v;$;QUhxnYltB9;eHEKLTbtcoOU{UGA?lkOKI=w{x%H-`%<(LL9?mU zqSic%h^)ApzRCS^j{l>5@c_%DsQ0EY3~Yqn^YJN~qS-x=!bC`U);*J)36)NEx`<+e zhFpgGpcAC^Ou>d!9zWWIkE>2$p-3TCLiB!3KbR1+FgJ%E$6@5Hd}VJN#-xylm!UB2 zvCn7Q(|=cPIu!svV}Z`vv>MPAZ&=u9+(KhCGa7Imgr{ALTjJ*Lq!;BD@j|_KNzQw(R!bH(|H27fNh5MeVP@0$&07@?q zL!dRafVTM2YeI=yqsoQ^c$2Wr38Fj53hVVZ?9QPo%FG1vp^u$T?^x&XhPyjnED$(uF@F$ z0ub8T(uk?R;G!aBpf>E)3lUjkC)o`Kv!7AInoO@%nl`$Qt7BllM4vCflJA51V+NB9 z8^Oju(MJ9$Q-T^hBEz>^-Skt1R&GYX{=6;8`pf@95*9DWj#L#E)4u^E00&qAQ~Tle zByzpz$n&G)APYQeiY?MFd{H}ekR0C@!F2w@-(y!30mxuU>%aRx{>ZQ}4a{&&k4dnw z!3xkuk)cVlf*yS+Do|u#t6T$zYblFjxW?F%@rqW*E~QYWeDge#8$^J}lY(N(_AkQV zq6=4Pm?n~{zHZF(Z>TqYjs*h`Hm51xHuxNR79WWJ9bcUoMz_J%6&@FLE31+J<?h&GuDv++P|Vp`ka(0ZhCfTx zrJ>7TA{nMSS17I-R}-tM)o={U5kj>HE414o&G;+IFuv7ox{lw}!q~t~a7sCbUAUf@AobAUcg%g4fN0@d(g-`f{Br z{5sf#d@L54a!lBq!EFl;^Grz~>>oysLsh(}<(9#1*W(~>(dvOO^?J)@VoGceC-mdj zW^No(DOtA1%ZUfNZ7wYX6vyJpI!Ye~^$lnt@7Kz;bwK;sFLq}9PgPf8x%repg5kI^ zwuJ&Nb{Lf4@u?=g7=3Uw#6WBbLexFNf&19hJf#9Z0jBNY-ucL=*BrjxON}R=3=d|T@4l9%N zD?lC(v8w{F$C?=n?&3$?#TnWjt&8USWj%KOVLf0cWWYm&ti$7e-Ql&+j84D=hrXd( z|CGXO0j`gQrJ48-TvV_t<)NDO`e6eb`?pkfIN0W2N!C|_6jnE|DSL%WSmr>C!8#v0h_!jhx| zA&s9i&t|WE_ry&cUXywJp!E`EvCkVTq4mT9rdg3*N-gprevP{7(=U(jx)OsO2!Mg7 zrM+aXBW(X{;d2x;h1UJj{%M$L?VY(C+&TO)sJARQ#QE?G!(eb7XI`2Z0R}n#gyGd5 zqKX(#-{pP{3u79*tZTS?&scX2X4y{9o&%y>hda`jm33l3nuaR)ZF^h$DXWPrBt@10 z*qG!_7Wr=eoh{jOG5CNyt}XbPA+dn*L*8WHWh#0JI0Q*0^j_7ve!Wji>NsUMw)u*z zg};%*z#o4${#I3%u*@5VG+EGJ4g#odghP>?Bfq2 zMdU>d^!}jqS0g{>hSsoZ42(?_M#_)@ zYVTw8*^2R)zSIJe279mYIM7q#SQ2RiS zz6+*EeoEFL*7i=KTyp9Z8nSsLd|1io%eDyM+op$dNjr!#JWB#n8-VM0CfKEoA%23* zyG;5Xn4UTAik&8A{`kN(3t>R2hez6cfPfVcK?wkRUbz&Bmu^1i=eZhsY(qrq&ThRp z`9m{EO>%=G?BDSI1vt$OfB-3jc@L%o$w8b~L!2i?kWe@EY6}dcAz-a61aNWtIW5y* zzhVe%($9V+o0h67Jfl|-jb!41BL(^!`?RmTi$Cpmw=pjRsyM1|SXID#6!d zqrVMN=S{T|2Qvgl_&Ld4&<N^M)pPa^06&KOUPsBLB}p*c;j0@ zjil^&6HEjxKD0p)Pj(5UO!-3}RNz3g=0ZdCD^rB<_IdLOQ`rdOj*;1I_~F5oZo@-m z;R!`SLliDS^aG^ms0pFKGjBdniR8=|Dzb_wdfj%^NoSXP&}lq#1c*0`m~v8UFiN5e zDa4-~wRGkaR2C|ND=NP&7L%rsQHxShhd~s>EsD=Y(RluOP8axq@M42hFz+B*N4alJ6x@ROo4wR2jC=Q$>YI8$+(7^ z`W}p_F=45XAMWgG1h$VKXG%HjA`&b zeuJzVl^APa2)_05HTar4h{wkn1X7U}Gv``TI#O+;y&*>TPE2>t%Ncg6R!ak=UEiMZ z_YA{g0+wyj4B)~A5r44?%641X{Zc#MszB%1kn#{z_@JG-X6IWs`E=BtcuSNrAk#Qx z?a;?Vu1;fGtMRDZa7<*L2X3 z9I5Ge&|4u#_bd)?eM?3Ank~rqMBsxU9ej8eb@o3(*~3^6OaeRks2t3rg#FLI!iE;%D@g5>b<=6xZxlewLj<*t;v^*< zr^cP;au~@6B-&dzI#X-lg{l!{vlHQrAG!}gLD?sSiVzZIS-UygTO?3~Bpi<%Y+qp` z$u{eMt?W8YB~22NLn{c!6cIsaZS&ZuS;mS$9d=%_b!H-Zh&X+M;P^o_aGLtwlX&Q_ z#@n=z4w*mPA$|zBplpG(m1e&*)->LdF#4@#4f)lZm0UfkT}HbF?F_I+H z+)43$E79!i$Q@7E;`WaBn>b@QfdzOH>XI0FvVEt}$HUinzais-tA=yl?#}6)QR#>) zM1x%0j&n&4dJ#DxKv3a=(!bYcL~J9pWY~%VRM&=WU1H~VzA07MDu`+>T3KARflky1 z0CEb!JEiJccle%3p%a`YcUL!RcPw7@Cg|Jc*cU+eHl#^z3w+|Df=Ea#X0iS4mL|vu z5GPvstONim_8uNcBuq^TAI$s~wsv<-7b{``(3CpwARlZ!+cMO6N**2^2JoZr(-wk} zGF5F{phZ`XRAYg*J zEhzEGX+wX)8IWE%D7}s52uec5R&neQvWF=nH!1bg(XSNJpXU_n$Cfw6%IR2^cgug9 z9~fJNo&-G}>FfowlWkx;^>OU1=D3YSeSzDY5gkuE)^}EEzY`=R{`P<|>>_R*9ka{{ zT;37{!P`xwlWkU6fASA&t`dpTeCxDY%NqVdXVp7o)T15!` z`mr@sVPgf321i@^=ZWSKA?QBW57tH9Bv>;o7mBBIavgm_W8hZFi2~-LFY${G8$Cmy zA|)8qG_Fd=^AWFaG>84Fp+(U|AVeh`PdQ3J_qZ_lEaKj$*@(Iy&~QExKNt^;u_xE? zH8)x2_0$_z#wnSqn)$BT)-|{FJB%P8+?_`TetZ*eF118lE%$$gz{$QH#3dQ5Y4|1Z zj8Xe6P)LavCnm4ns*}PW!h!y2H2~WtJNxV<`qKm|32y$M)Q7Dy{eqU7RcLQM;1<$z zJ*drBZKJJb9a<*Fdn=D>ChNRdw}nzyJ%~hz9KU3q6;aVNNE~#Tq_}#xV<|`C!ziDr zFOmjP-CcOYseLXl_=MmZ$?LvNL%`}blP^%r9ej@!Ujl&ERP0O^lSDPYM%}~^2Dt`U z9<-JczHaen;Y2U803ft#iRZz*C1h(hpGGehAF!>(s3x5bpzC4NR*Z%uskwrVaeHr( z3z;J*h`L}-kXiuoau&3e@IHY>uPwAg`FLg#NymkG_0nCuzCLj}yBkp$JuR!u1bXCD z$Xf|J#?4(?D%Vs_!NXpH0ML~|0tGaW($LFB5=^yx( zTi*?nW-H$hmnB(PvXEZutd23syVN^0fGkAisSWF?7x6 zIJcel_c&r-z}z%WGdaG`kwa8z^lyjIl;n_=$QdjzBh-;au~7M&(gv_$92jAL)q-gK zv!jQUNv$Z+j%6~mq~*4EhAJtL;-r0kUHYRp02tL~{u^r>6^uEJSYNN!uN2F_4nSLL zs8ltF8vnTBc7m~f^dsy$IiR*#PoJZZ^pFS+!ax%Od|Rw1wjL)R?z#LyMazx*0Ebw3 z%g|6&aN~^Md;HVXL1Ul*8C&qQFE};418Fv6ZVOnjf3{DsnD&Q%x2Kg?Y;*xY5!m0t3JW9ydn>*fCSMM19N|a{^-dGVJz7|v z-^|MeJra9SUaM9biIqSL7@`D%t;h@0#mi3Ex<9Yy*_XO_EGx5AdnNZ2yq3l$1sGTQenXb=oL41|3=>dSWM#tY_ zcSAf|MvxG}ZEfw>qtqj|&fC&&-Y-c(lk80{GV?`&m{18=#mwDiz%&}!M>A+qPdY@yi{>bsUJT_TeGw{yG(E1949iA0%^koh!0TwdWJ%m(Lr zfkhCTT2xe|=2N&}&=;qh93`)veZzZ#t5BRXZxiQaD$fsF-?Qw3TEVvpIuxgrvf*U2 zqwXKYIRvQDcWvXWJ0!);c65wL-!lk2ST8atL`#S<^mDBgouwo+b68v`2v!2$WG0-H za91pqoaa{UF*1C*RV(@&^fQocjLqXscE^|y<@9>-H!8b;jAB3mI5N)VDd570IHfgm zaFjCI=h$7yEk9YQooHm!yt+#T;B+)|h%c|pH-8==LvvK$qdMRah6h7D?8Y!Tf9K4{ z6sIXJ87mxseVQM6AAtSIwf%ktmKY`N3#DCzY1JmQ2v~a{Lfrhxy`3+!ez%NPE-M1T zDV|k5&btkV+s(GoBX6i88<*H(ZaAjZByraUjrKc%n`6`ox|P-@>JOxA-UP zl#l=y^QJ&A6->FNDQ@@r-PweUQ~4Dg6AWr35vjF~kSreet4etT|51Cy737m7Cx6qF zDolMH|H7M?(4aV~xo^`&+E&NG0V6YI#?BUqW1-A#S+fYGC&et&j;}M!*vsFg zv}yxSHd92%bZuM974&TEjXv80Aq5?f2ZBk#(~W%B5mS?VroQ2i=&)DRWN{g622o4gMyMwWwZ&P8}4uHeF&p#%lqr#vbL{B?nA!@Ac=Y0-J}| zsZ`!2EQ$!b{9JI;bs=}{44*Od>cecco z_n*1Rl_^QwSV=tgt`JI;hE^Y2$7sx53P5kWd4c<|yZj?!_;~7IZ~$S{9OU9*d$CmQ zj;tu;4m5d#T{Jj*JhM=^1xZ0kPUI*4@SJXMS+p60>W@ePtk2E>#jT$d;<~gulRY=W zmG?XTk1?3X@k%&FFlB?IO_ps;YHc)nB`N+#m-Pz~dPPo{5nUjO{< z`76S=o2j7RTLSfjZfA_H5LVN}htg`p2jK^eC|+`Gu9|xDe7En z)8Xqok53y@udG?DKf!Znd$l}!q+pSEz0qX`ObTu*kzIMmj58nk;UFMSNJ72+5jo*x zYkrS41x8P#6NEnjmoAHDSRRv9UrYIZ49vpPBE-5wKfc4irtXz26+lnp5wJP5t{V(< z=(YZ?xnyOagumr5d_xrg;lWkCBKIb>xhnKXRp(|L*N_;%2K)(%=$rC%6rj+exfPDw z3Eo9b5=8pBAI4eASJ65C&10(VD(u@TL)cC~#XG1Z(^_`ERBUE#W7GZ!otD97#*M@U zBF6c!e;`@6g!{4>CoE;^fLNbq2YGb2Z|Pv3^F=>e;`_<$T;X$GL8SI>S~%7)Z52R_ z?E1$H$>|OJGadN7rpBAkK=Uc|2b`EGT%E>Tm5;leM(j|iu(LbK6hFakcfLLR zgA}QRkbQilnAm3M6qU|cqD2`<0u*Tc$8{srY?#m-A8(7Ok=xqj9cn}5^Zi3EUBtFi zD<49D4CMsXvctu)-^jk>%rfQT^4m@gO-2VaL`cqlMG|4Oafr|#Kh(mvZgDIlhTgAl$iWs(3c1GDC}!!h zJT6frj2kTpeny7+s;6q)y!N2$OYvn5!Z4QzXC(FTr!>u(dQ))AiypQQogv{=3B4{| z`8xG?nS!DjW%(klH>sMrd+U=x0%WMlabGHT(Mq#l#eL4o)KhBErhe9f@RHJ|4A22D^hbThUYSd zD!bY7?C#I(eprJ8FLZd)^Jb6Yp9Ea6kNS!yU>uNK;~8w*hMG1Y)@FvbYn9y|G;~}q zBduBZe5R`O$uS9_GeptSwcE;4Uc1w)YfB;rDe9iFJ-xh|i8!93*@6(Fcl?7Gstz(Y zsuOGa(s@m^au){nQLmrbJ8w%LzN_Lqylo{3c!I5UYytyI)!B z4v58b1t2U6IOxg$@p&U20gAr+bQMln?ilC#DY37b|1!X9zAcqcg$AJxBaPyUQqr@j zXApLjjf&FYjrFgJM%xgsjM02)joB|L?n5WX(!)b;<+9^$0MJ%%V1&kWWbB-m~Dl&ZOC&S$Umk zbjM&#h@)ZbJkK(a$js6npihPsqZ>w`7;>oD@gp@1(11qN3qtKuY+p7nh3pK@h z^XfhD;ZjIgLOylGEvnERS4iLv`*UH+rhp>vFn)MkM>d_b!_W#gGeFHKw{nI37;ppTH z^k!|F&SaT{F)Z2b{W#Y{o@mCRjR0IHZqBB}v`wj*vnOtlN10nBhn z#59-`DQOQFa}P<6-~~%Glp>bcs}B>pEJd6)4+~a8UwOF>6xfJ|+o|WVu!av2!IEnT z_n4LzXU6wtKDWn{N;;Zmf9W``;zueB2h#(}*LlN`2*zJ~j#!aBNZF}_D*T{%tZKQ_ z%u<>!F*acg=?|bGgS!x#W6PUK;zuT4!d$B0rRGW2NH)SE5=uVo7W>KA1Hu_&A`D$m&t>aE;n5?Yp;mgKHQFLulH9`(fIwg z5yL$VX!>ZEu298kA~)EY<(=15_di_g{?+^_pFJEy`(|oqw3u`bJD?l3dCe#LZR1ss zi`a!vW7ne>6AmbD_A@`RMS&(w2BSI8d!W(@CdEWuWYLK z>JZMPLVrACaQL_@;*$?k={*&I_)!n+z;D=&WZm3S0T!>lJoUU&*nceUc$%*}$ke9$ zl9XXo1n2U&%(3R7en>0BJ>cjQX;)d#Y4{p#skC@UvBzIjJ529HrHQH03E znC&yt4m=_4T-EhSYPn6|^{(p>yU*+`6kG;jq7?cdC}X&Ka}_tQuMwFTlu(M(co(}W zxY-z3$X{|CSaK@#+3TDhPhq3qMZ#bN4GYc#4}qR>)^VSKaBLECK`AoK4@khdTH+w!f6$KXG|ezFN!v``Hhz**o|!|FC*rcUt}j0dFlai~MUZ#N3fhLw%2Xew!3 z$?ogAR5fw^-ek#Qft2kTrx&{eyLf4gfvM{n8WGm@ocA_Og8W`TMn(FteX1^< zrbG4XXXAH8iM%X3Yyol$g0s&0xcXEF)opka*&mq5RAyQ&>AWb7UDe$n_1zQ4(uYrv z`I)-qDEzg-%7GH}3WuO=$`_A;q$cOu`1Yee&Dm6$P35~U3y{x8o*J|?UxpS~pZ{!! z4g9R8&oS^`*intuqkrps!cQbnE<9Lh>ol-)AusU_MA6glnA_2fWp~`ghVJML(FmcK zs+hg3@LlMjSkqp_bmW zyU4yCrbN6D@HIGet@2vhS54MMrsPa1XzD_*jH9f~e0?X_>NkQ@DQKJDAjaUyuGF}% z;K?_78q7LxOjoO?zdB4^4uGzH+->ehc;lLhxaB zbUK?%a7bNTl~cF=Y+Eh(@s>;Ceju&TJQ|Na=>BO(dU+4#<`QuDa}uOG>WqAEyUHrV zEi(mO9xusjnYXCe=A*_+0&_$&b41*i-i#5}CH@{9@WWpEK<=r~a20ZC_gA9ZYyXK& ziQl>XF_o}f@5lxGgV4TJN-ImSD=x;itNjkWNGR5(*TaDiF?KKNdYilZ2zy#UxE6O*>NY?|6)u9Jjr7(DivSl(KU{BE_c7RVv$%|P9_KSD>U`c=nB|_StP&WsYW@P4tvoU16 z>UjL&@YU1rMIM~W6ZqsyG2iKqxD_{B*z-NO$0Un)%-!oVSfDXFS$dp(k2S=ObC&Ep zJUh6&nc$>5B)(vH%juNYejDDX!k-WJkFY_XMEhPeWOu7hpQKcJbM8miVa3q3#<{-S zGrC%Or0hqb8_A)bw9R`mc5bz;umP#J5Md z8(A7vrR&p|b=IqXOo#!C=%CNG!2=OX9}4LG!v(3cMWc^q=a z(ZXFwf(Q_VgSN9;J-B+7cFxRAk96Hdm*}1xuTMSh8v**B{WM=4p1m*T3q3DSTu= z)G+@<7u$3J!mLeuS*X2${eHXko{aTR`5X`7o1~g%g}LDQ%-tBWSG9}%4Y8{CDS!x= zwQm?SIO96VXo$Rpot0O$`C#hC;?!_5A`DTF?mXbQAs0~H_aY)VyEBa|Xn&Fl;IWs% z&X;oZQpb1_T{;ja)cD!oyiD~m^AIo_Vd>0iJ*48p$g4ecANZXjDe59804ENCK)k-#VfW0wA{9RCML)N`gnRnyy}%Rxy0O}<}r zM#=e_bq(SbKY+J`Mx?DYP0XD<7yBeelfQV(fC%yGkM5C%qdzAshnGIL-g3s57lL5}Z<2g@dAvLfCUDms55!WI)JPRMx~r(vgiW@W%ypB{ozhPWXki z3C~dQjk#HFXHAO(VwdQ^p?jDkYhM}dZ`B5S{ofF0)zp^<<-@tmptI2%$rDzYI);u4 zCXuh@66I!eA+T21=tXsmW^WMC#Od+5iMMWI=I(0o&Vu#|)EKOS2yh$olBCs{b*P|< z_t8`vrXJ^rE2qIrzJgKPoK$~ze5q3om;b86I7n|zKmwAZ@c1EFrIwQD1Tu5FJlE5Chm?05b}|-)m?}G?y)obK>$E#7i1=p zb5)*qw}YDzx{2P5bXAsM12NIG!%XZn$gCT!CJ`@DQ5VpLTXS_~XJ;Z;fHhI(#1H(4qyOGOH#65A~sR7xX0oLlw9PhN(2;LHiAfaZUJA zGf_qxGl_9GjHTQq>wQ|+{n|dQb2~xrIV<%l*JYg4oq7*Dm^>jq8vU?a+>W(OF&cYY z<{@m!LZlaVsEK5u%vwBqQtFk`7ILh|`MIVBQE&sspgXrdsLgQSiGf*qzNht|oL6x7 zw}W4DjcbbSnzE2aSe2x`X5l__o?d zcwuXLbT^T5h)YOlP0S)eUfbc)<%C&*OS^-}-9uLk zEl6YRwV#G!QgTMHq@>J}me##MVD`dO%8`HFe_}AkYVbJ`;@szF>XAB0VUG;vZ*m)X ze}(;XxWc_mRRX8fJgW{U!a)@tec4RcfL*+5d%Ai~$C?ghMsDqc-X5n8) z(D8o%N#xheEr+hfUqPyTJ>uLKvYtJ}(&L`%6}P(Hkj$WMs9tPV_yKzRNP2Yf@=Pzm zU;=L6kOH<-&_;Dq2X;hOPcietBm@hT>&U|pzPu&6XH0xR-0a&PE zov{03vy=!o88{IKp%=QKYm{G15v<73D*Mk-FisP7EvNK(P?#}=tyrMLKlaXA{Vkp6 zYA51%diUU##{Uz_@|TDF)-V1e-(vb`5UVE&nU#d;tqd<5Ul?y|LZ`H%acL51niG1kDF-!$$Y)?hfm1NL`U74|06v?^rA*2v#Q~ScVc78!^7F&fZLG4qvl+lFLU-UU)Vxm21On&`}c(X8E3C-ks zRg;`%z``;Xljb9#gLc?{jWCXv*w2O8o4>bjau_`2sT|MI_o=G?%8~o3xKTKTT^6Nz z@+&JOM4!CX6xxUKo0PZiyv;sJ**|cHb4?JX^Q~bBp~RIb>K>4Y7G<=?$nX`GPj994 zmfTJ%DnuJglhBsbPVQG~u0sIz*{xlrH0ORq3o4Vg+OtU#|tu(9IOZVb< zLtXZS5~FS8ZmG#lt<>vcQ?%6&(qOB+@a;p6xom%W{>tG8Su$h89?DX^?#a1qZS{6Z zX}tz96SP%|rVZeLMT`(5~#|fXN$p)hg`r>u!$5ur9`Q$M-0GrIg>W~6p2X*$`k)C3M39Tg|QmZ+2BDj;|-p04J(dS)Nb^Ql@V}pyes4x z)@h-#X}t6|?XO-Jvug3N&mu`}UyiG*j22tWCJ9jyqh2t+}cS#ElhxY(?x7z#arT)s%yswkiH@6=C|FHKKuytllwy2qznVA`4 z#+Wf?j+vR6nPX;#m^o&OnVIdF8Di$=PIsrfZ}*+KbKgJGyr*9}mi%p5K00St)n2u# zYHcr!kKYJwcy46)aFk(l#y7BTwp+mu%^~x>55E`{&oj#94M3bgZ&Q#Dpkh2=s1im| zDQd=2MG9MD3%U}#obZ1t;*p$jTs*KVFqNp#SCG~^>LPf>Y~5IFN_@7oSv46D&LmW( z+Nz&3)j#az(gwWCbcBoL0YL;r8OG`s5(SCL(LI19?4u_aasrPzP{bm=Fbimgq%lZO z39qsG5=QLLJdcL+o*?RC6M`mTqtM*Go7LxRk}3Z3qx&mz?9j^#J;jJ>!1cRcJCpa@ z!dYEhH@D7-#FG0eRm>kBAR8u^I*E3M!pZ!7-j7}yo&pC*OZ2v>(gUeaW!j5}@Ls>~ zYvFsLPF!9fa70gI%*&|;=)HnmPaZ{&#bLr0ylD5Q zzZ}Ny{#vgh=wmC~R(~5#)=T(0Kwx_sKdT`IAxRlvJtoOE$ENIGd5&;s#eKN)NWRF0 zyvhH`5GgnOiKOq^4}Vi11ESmBis=!-JOJz+8&Zvatz6dy1B{dk0cqdYmw^LU6jFi) zBj0#E?t(}KoN?D=@l)O9tX?PETqk*kWkcys6oef>yvMmu$sWQw{y7f2POC$~A%*tr zF!mY*{F|zyTL^OTd=VZX{7#T6D4J@KAV1L4OEEKhXuG zYHQzgGC_$riIpBLSJRe{#BE&oP^agj)X4o=XCya>wv@gnne>)0Qu?_t zqajMSpO`hiNNpzo%_PbFT74Fw-kM!lKapNHLkQ@eoQ~l6G9)A2gl1lRV2xKrHBE%X0hF;;oq*>*s8L zBcigC6O3Lgz#@j_WJMk=)UpF59bX2*mZ3ztT9wtDhYOf3_g@thn4Ls3sOX!ioRe>m z&eIE7IDB!3AEs>UB@;Bnhm?Wq-Dtmo4ue5U@a!58g(Kc)QDLY|yPn>00T~U}Wmuie z*2$qaS({R<3DtI%QtnkKb zxDbf8ReF4+8LS#kmEAD=vd}DIxz=@!2_y1Ye+*Izu&l=}37pNIeeBQDL=24+I96Fg zp#7ZQ0G^)z#E=mg-FzlrXImyv3dJw^{>kF$vDjL= z53W{x3PrN$4B=8}Vxh+b$-=V_2$|S?;k!Kj5xNF^62$oKcF4gy6?1kZ=Z(%J9H-s(|lao*HML(@|_@_Dp0_z(+`^Q}D!byKdSx@(iwX z^H>gCw!}sHv^KixtW}On##%}j!gqYAY?#-<8tFRV(Sk&d^;|gMRWy4ruJ>6TCd&zg zzw_4nmLHxrxH9F&2DTIjKDbKmVt-T3VU+*@LB1|`9l$i=)K_SIWNYOSqPv^MS|Xtb zxk$Ri?!}v4yNa${`%})5-s*uM~?l=a%##n4)VA@#( zJFnT-R(Lrd0tPz7YCbntUoXk%N2D0e8iVjnOTb!Z?DJq8F1;Hnm3ZY!T{(uet&@_! z(Ls@CPWgv@`@IhImTUbf)nfhg_w!rPl=Y9V<3CgR`l?}Ry~2j{GNzLgtzD-qtU&)c z7d>0rtqrFlDW9=|f7+|6t>Gx#`Q-SWlYPg_9To3(%=dSu^5ofuq3M`ok1(X#tcUA_ zDm^u*vj?ed#;sGY4d}D+TZPRFjEgFV-sDSW7^!CN${Druv+i?n_4`-xg?Ka8dU($t zEL9ch-LIKHToC~T&K{!UA9>*bAGh(_P#)!=ix6nFJQ;kSS>k*kJ4|W|8pCh7?xMG9 zV!$99&}?{+A71VURyH@+!<@2Hiyk(FSyosbE;V;~hWwEB)htIV6Oh*R60>UdFqN7v zsmmFUogJAEP-Grc08PFwve=b)6B2EZ;#yXOUV%gnBNjwmjUM|&O{|82h(tdqEm|bb z{~OH=M^x3uGI62OA_sE)wZLcb&w4oJi}9B|yH)b&a(nPfzKbJ@ino+(~UMUZhiGT08hBz0#mluJFLf431?7TPl79I>tQ8$?GH_H zGbB?RDcXJEQndjcuz^khbudSJHA2Ie1<`n#qJ8wtO>N;q8!ZPOrCIF2dsbwQa_=+k z``(PIm6z{Trx4+hIk9=Lie-?rI|l0`+F*fG%Zf&NX!L1lIf8ZGY(o9~Jy@r;Pw(j_ zjzI(Al}4RUK#3t%IFnT+{(}UBVSe6&>1WdUim}5`2)EqE8SLV=Zv}05FtpEI^x!x1 z-9YfAVVx>@pWr5kC{4ChSqAS~-UekhC6kk zAPW^L3lFI29^EVwsBwxDEd@B&(k}cF4@g5EXi%Z>-On^2EjGbzhxcL24Z)`O=$dl$ zWZ=AHqTu_X`#V)>r~&He#9VK)Nu&K`s<}o#VbW#!$g2u*uxfgN8`Y#Vtz)~nH6B{T z_3Cm?;&azKQK_3}oMc%P85Ri$=9Q)8Oy|UY7FKlL#%nYo^A6{Ldl!nJuq%<3Z@h3zV+^^VKo%3rrb)Id8P;Ss>Wq*JwYPmfo27>oVq zg|K5kz0SK@Zgxt%^W9g`O_;H-M0m^M3=;O!Rb@eqzzUGl$}?OhsR^kgZkPm116sR{ zSxoZHYowDHDQG$S=i@D6I5?X}2E=G|uUl^g2oC`*b zE;PVM`NB#G5&%uHzX%h~6Z0{ln839py6O6ZQM7*aeJ1mXcM&wPu&KYGk*2SZanZ-+ zoiM3_X5{p;E6Vr#7cS{pGpQfPI$nqZRB;+&A#TPutz(kzgDggKJr}KXhe{T!B6d*a&^JBt-AA(xeCyhM`bt4=|*jIWM_z zFaGYAcm#~xlZUV8TTi>P3&wV&VJeTkh|`40?;V`+DpSnA+$RX`=o~rH_pCCF3pofs zem>^5coww~@2zFErljMo#dH5{F??_6fX7qa^YIDu@if@@fSLDFYJ=Gw=KI#I+1IuQ zp`#`5#bq5-_*An3P4{b|>-J5fI9%CzDVUl#g{;Cd$Ip{mI!e~1^WRiSd1Vp(i-RZc z^eGb^ms4KYY)6X-3Rxre^%;ksb}tjsQW+4shz!4gEao|9zq_D9B^}<)YDeY~BNT-b z&72c5G-fqt<`pi0H5b5|tJx>jdbl$}l&Oi*OGyfa{3=O)X1F6m{r)tXX@GL+@+;xl zRYTLo^x?xygv#z1Bez!C5wm?8sbMHjHHuIhjf1~LKmRztD8g*#hdhejbh+w#ni>S zXS)8ywTur4v2r2=X4Mpc8Pq~*&b=W&M*+So^X-GAnhlei`f5db+0aEh z>8pUxVjp%MRmIG+5H&vBttRqGwTj~QJykki$t}HpU)mhwoC(OEzrL7y)G+BPK7YdPM)>ocM-@RZ1&jqrYC%oC5_~ zzlDXtIOw^inGITB2g7P!1qc_+_AJSio#Yx`rywdkY*j?BGB-q|p@#w?e7GDEy*%%P zh&jxIYJMsY6MNjGr!K^BugGEignl;vh87IkeVRD{)KWfLk%W-D)_(OdoCK~W1UXIo zY61~&!-or-TgeZ1s8Zci2SiKKLo5V-BI3a6pbB9XDD2p7{@hLrBzhg-mR-v3aKzBr zl1e0Nl&uMQM%`RBA2jgv&%hAcQ$^}s*yK2AiL8S}usguz^WX(q`-??5>SxH`frE6R zldA`O3pm|MU+Kzx@1U)=NyFAYya^N*gFaBXv1`~D=pTGdY912%GBZ;+k(l8gsFO;f zxcCh)!o)I3;@QbMFT7g2RMT+ZlLS$vfpSW^&$@w)ojh=p$RdxxnjiA zb2JiD7J6>C8q}7Rc6TYq9@(uZCCO;_-eFYQ-n82rI-bT)x_xUNKJVHINQSw+C*COo_`Z=DsFS+v%uLp|F=?hE*0dXwtEVVjZpOxT zaBgRL?@9mDk-1f-`7~~!u;X&`>>a12Y#oceg~t|;BfAYP9<-%z^a73-xHwDB>E-oR zuR@ZjSxzNinH0bG_H}ndUoBX|6~K}kZFY$8M|^Dd z;{)PI`J|i0>rk<4JzxB%7jhy zf`NOXQ%^;YlL)8t8$P?7ckYpO!2vH9Zdj}g#tFLkxVn!N0);0M5z!)gCTn)%x@2>h z@&Y&#+L;ITdcgqDJ7V$-WCaCP4901;-;(lJydmg~;g*(DjB$DG@p(!ObUBst?zve! zPWIvVpV@03v!*p-^cBlLTQQ*DM67veaAO%Lya+Tk+jg^tfy|q*&%Fo~_d!l36HMWk zn@P3ezYu7GyC4O&lLAF?tUPDH=|2Z za9Iv^==+`LY1sFk91USf<-VLy&B8aCq<(N#S~1%&HPFU)B{{oah|A z)pfstNcwdO#1Kpo6r-~fui012pQ8ogTk*en%6_f7(nqsX+<+GsWt#!YMMe($tTMOr zh%@#Ptm#?V1sCUl-5SK^@<*fZgbRBcQ%ZUcyULyl&IupF7aan0bJV9<6}}W&tUEl> zsdp~M$i2oqyzk;B+!&NQmm83q%5kAPRj(MP-;Ild{k!A*FtXnqhxHGliTw}1`Ke3J z{)avOXQnr*u3^2*hT^qXxseA;Qz|x;$O;3xREN!0X3~O*TV(|wgbZ#_0MptT)T>{itsVW94h4LDw+T z-lKWDLFN5>~`uq0h%TzG|A-%D|gpQ&Af4N#Db${7p zdLnac7k`?Ip@r&t@23LGC)_VDeQV99rVZhx)A3mF@|xN9+_I}NhAy@J1o}DI%b5E4;7R?Ji!Rq`_3rfX!WU>CG)%EUNY{!N-isP z8|)9*!U<*zI1XLKu#?cr-X+P!9lRoL#wCHHzk`sys&@!y~B&pF5;WSXHQd05bE~X?HCE-043vhT*%0`}sFiqCw%=VJ1c5@R}7lIW|hp$M}?+hO76sJwm6wA;hi>bs!02L_In-eR3=*8Oo(GhXs8Ks)M8X<+#a4} zaVCHlD=0+nRTJ`|jq1W`Rr+(_<6j$eE;u17{5 z0&GUK-x2m1+0tDpUlwG-tNLWggd0p(dk-(AADSG@L#=_H7UDs0$up%~b?0&F!V35m z;&~0Hp^JoqWwb&fXICWt(Ph1d-51uv#}$2nF#H2pNpcHNK+GH(f@QEgb(s5`BBNHU z__KJR8qQ$7jcvDFtJHaX-%=pFVM}aNGTE0gfx!j~E+ARyClkiat`9BbtYjq9=Me9L zyhh2%ERQqm-lI}ke+NOXw@0tff;p<1)}@2uiNea9-4gBiGCTgBr{XFt!)wjyvnZ@z z?!@svFU?A@(^MFM){*h0*8$rEmEtSYkyAr_cLsEuFX%h}$VylOxJnrLM>x$%AiwVS z4Wd_rT@%nWJCXzjaPECgd87zp}D1pIB(>L0MKR{B^JaiU8R2D3BpvE_4I?w zQNQGVdCCeP-7`2+U1y7Z1<7hPSIbGKSaI0h5QO%+x!TN#a^fP5s^*R8pKT6k71svwAG40YM_-Pl!%xMGjCx} zO7-3xaG{-}6Ub~u%eWU$P(64YC{S!>e25D-_k1}~17ni-WjjB!ra0Gaa9_zsi<`e@ z!I-at7#Q6L9sJk{Wn#px7NTjfL!TSG-(E!hA}~ckRn#xnyBwHbyTM0+?%E;lEJIxX zR@@bnB$FkzQny#0)J;8E76bRftSow)b4rXwK?W!K{@Lxo)$S4`~#LL($QxMwk;~&&wjf|GbZqg z7X)Ck^4ec+Y1CIJQ90vU$m<>`{Hlw>@Qxp+54&ojzE-kt6u^G)Wv#kc>q!mF6>|_J zhMSZiMU1Mdk0>H_`37={yt0N&tSuRapV5CvS!B?i$|ZuQ1b$|%%j55vQ2_XfsvMa_ zm|_D00yM&dk#z=Zp(Dh4gy>jmHf0+M0V;sB0w6=_^5YxN44Cdcbi_Ag0zo@7sW|TI zgG_2CxCuEO)62548%0=_P4^R_qj7Q>wAh>y2|~S00iRkCtQid{LErre zrokCv;m2~jIa|VpvX<7RN)MA7y)AC&3oU=~yP@3S7w+0X@5>KSOa(*oboa$^Da9vB zOW$?gF>+S|Mu2x5Tqs1>;0+5@WUcSp7WL=hRbIPH=oj{jI!n%ZF~n;h*n%mJKAM78 zSga>=n)AG@MM&AZm1)J`&bxIbRW%a!i?HDh%kvhZ_~jO0TOk$>nx!YON?pL(p1^)f z1x06b4`T}D)*HC@1*2bD=q#3v{50@EEv;qhf`8pE2-zc*i8#B82b*(S*EmHlcST@D z&BtSj^v?8*{cwFB6)&RPMRDNhDj1Q;hZ@1$#?gH~B5Ho~j82yf`$-OhJY=()Ec zOaZ!Gd_*hiA@2Ds%;3%F!`s9B1rhy#|IDN?o+vUi;-Nov#FOn{0ScnaDo-c8h1N22 z5Q$Vl!g_C8`b=D$Gu6OQNhuzZht8Fm#^K!=E}08B#`Y7Do!!SVvf~fj3#y%d#5f$s z8zY;#^i8csuRy{{o!Nf}qdySlZ(x*(mGft-BKsfhZU3^e=Raj^|D-GbSH1YRy55`C z{9kqD|I(_+{(A-RKg#Sl{%FmUc~fuy<)8jKFUk7*!++eXc#ePa2%^5=hHMAH*`ywunjcra!!lTTCf4AuH{FvsC3(wIsqJc%|Gqm8%7jRA zz$AqN3RE%lqnup|1zdzNkvwLVW|c6cu0(NuOs9l8$!FA<;k`Kk&ic7~5P$)vyWPC& zFV(ksTP*^Q(yN$9jC^i7!ETMVk=Hyc0LUy#OyDB5D8S<`>I|9F$FT1cS$6Kthge!8 zMX2+hRq5`MQK3RizoRIBCh*IgEA!ksKDPALR6@UmAZ>j;^<4HQG1zm+YMxs_pKjRA zsV;Hi3vrrruD{_yJU}j44qEy0etL1q?2>SXlQT4OUIQY%!Z+7{EsLKzdIBz}?*MV> z+r$Dd%a~y)6Qu;82p%P*dVc!FItP)Tx>2a70|%~$RB!Stu>)UPQuFe&rNL9kv7Eu; zYveK5Dv*v=u^$CF;Q`GXmZPbmutKk5zs~S=j_C)x>*;$9nlD==flOhizGUc?~3B=*I4_ zq^o$b)x9n_U3#Q6QSb>Q3E787o^+C@^bX$$=G+rqq z4|5(o_dcght*eeCBFck2xDxpq6JJLl^~Bzu9{c+-5fl;A*9=H5mIN9$uA5Hb$rmn7 z)XF(STSo&4^c!#5&)vy29GWOeWe(HF)H+$r^59sG@|bi-xpZF|I>wxjXLrdsFv??^TE*H+r1ksrT~F#Tq;SJ-WVITma$`(_?R#fN#Ol zbS4=Oy*%Ir);ag`tUL1)8`acTGEZXp;FgzLl`l0KV5e0Bpr3_`&J)z4(;K{Q?31kk z9No5!y|XKZ`=~-AC0d?snJtgPa1XH+Pabf@=ZDdsFS79rDW=)88;$dF{0Ka(dHAYg{!Ras}&|UsfDzYhC48|VvZuoQa2EGGwY{V@+(k| zLFQy|Mz9VHNdW4ESn@`~+eR^yp>F*WLN-(zTtvYuA#1K~#g2$u=xqm{1(Q9E#?B{H zo3Q1Mll3G(Vw|#Sg4Wdm^j=*TDnJ;s3*a(L)x!o}w)^+V9>B_6cj*8EV0}RG@m=&F zwZb&iILNu%S~gad!n9u+T!l@0+A9QO5`|)3MrCHB*xT-+v6n?gHq&0zgPrlZxvXLd zUnJ#iODt-#bpZ!}IBZ@}HH-8=gJ?umaa%{Rj3H`>^67>Sn(z&vw{OJ))&S2j6}nBQ zn1_ZPMk7id7ZMr~NZzZK-AT;612LF=adFp-ht->K31VfG*(%eG_JZG^f?x$*S?_Ub z$k2CG&_#40G?@sw1?ms>S(@0gdlkNJ)@|@FVq<-79}*wkRZ;XHr^~fe zIdfXn6I<(iPCI#uxIX7zdgqXN1X3yurcJ$2lm?iNWVgElbO5ED#Q1N67iDmJ1&c&S zZ?Gi!59NJj`oj9)PUAVVg#ic>Ds6|8hBPG4wo+lyR1k;v!JbbcGLE$}U>LCQ%HJr2 zKhVV%`2t37Dy#?zlmyS`jbtSM(EYe+{vL zCvG6Dfi2@%>4vIhHnQ$ZO-h(px-!yqWzNJ^dXrZqj1ZYTwHHk84w4w++zVpB5hfwvQo*dXhzjyGVh}~#c?KuB!k80JN=89k z1JY^iWTg#x$R`7}5VW6GH86)-oY8C)5K@%Fcxtv^R9++_;J1_X%h$$z;YF5-6utahg3`+0H@T(6*65QmKr1des@^!mfh{)GGO+*J@a9vr=Dx zbKr@QZ11P~-_Ncub-OSoyRMLQI_ScGlCRU38Dt;zBskSJ(T|@rv zbnN+zDVA*;70ED(FN>+SI}P$26TGO=$QlsR(Vfbi(O2*7;f^~kaO~HXWdM^-J4?*9 z+96%{x~VK}F{Aiwv>zn`#=9@#>n*~mFhAi1pZ1-?nLz4J;zU+|w$M#iJN2?--im_I z`)Hj3vynNjC}0H06!eu({>aX&cTxruB+;0Xr47+|X1S1U8%F{c@CUfuvdgpiJ)mK{^H?=`9b!bfR!DOvV`B3n~O* z$2V%WatC0^4kWNA$+k&{Si0RaNQyvu2}~otlzH(?x86zvVgm|zgmRA@UxIKjA3*r{ zsF*W{V4Xue711@Kr<8nD`tnM3ViMFjPlFn*qJe-T;=74*>~+7%%HUfymuoBt*A82z zDFa;O(-=op)qU8eyyd2OA+b0ju>s zon^*M(0LD=cTbm%QMj)h&IjJgIvxm62>h9$sP4FJfn4TtpE@obUkjZe1N3}BoHSk% zNlx@*4)o=i9A=si+RtMqeAo96f=N>8C*#rNi6gy+23g@57yT|7M|M1Hm#2v5;R+`i z{7m+zG|@I?1PW2B0yPam8N&nP@TkqP$hdRBHGWGdS~sV#e`n0gJs*4%>}Fb218OkI_4fUA0tf z7)VfvAZ)q7q%$K<6s|^s3tE>AIAPBt%S+G^R&=4@&5`XeW;7{1&GZy0wZgqmhRw09 zW>T|UdyRbNp zrNF%1fGK16zy<2njT|b9#)i=|XJW`jr`rNbMwApg7p;yWi^9$BL%)6%WYAgXI9KN` zrkAA*BSmP;b~hp_)7(7xbxqTU!TuwCg}xo&M{UZFyd5aja)W`1vt zTU6gzc1!P*)2tC+;6_eTgIdQE7rX(7W__Rk0b&0Fn}1I^Io`x;e!B~dp?8=v-6J z=XOWY!O>n+c|V*~X<+KDsfjpS&tG37+1A(*`#}hg*F*CI;%tkU=OyPBYyUNI+-x)s zr)cR3!pV^=W@5d$ROZtC3HI1Tlheskmp}OH(>-(}uJmKCIIc^bPP+$bZ6^<*hV@pT zV{${1bMdXLMNi)IT>0{W>nSsvNd-rKlA<1q`%PKg5Jtd_%yl~?txktm&(`{9l?qbB z#j(}Gw)@tL@BR;qvqPTYtiDU^>1<{DAVJ>DUMC1P-?vL51Rpsy>V2@-Ggy}#(DHFH zJXbvKDayR4iei00E zBDlLfTi@!J9hl=~0tAo>rh5Imcm2B2zq=PF>+jz6!~Fkd6hD08H#X$&1jv8YD1Mcm z`rRmgefpOh1&4n$KA-37O9o72G#>8|ebm{3`OEhm>QF3vbQNJoTDkILg|icD679#H z;OKCwTsQO*YhL5lx4C`cnul28{*Xq*T-#^Lo*JjfK}D_(&z{XA^Z5!~ZkO}%tPUIO zNfw#(8DFKXoi}B9=oRFeYc?y*U{ih9V7J#^wlXa1)#i-MJzjnP-7q0HPE^ra<8i8z z2mzDh4`*o;->;9@%U+t@cGMLTPgX3K(#Emr`HHi&%2ygyk&A76Onbs)bQjpRrXT>x zWiy8;>auE;po;@!+e(Xf0{&`=ueZF;2;42NI<6l2TFsH;g@axX%as6GWI6U6dO7twV57Y&wZ9~OGURejyVkw zf;!o=n0>2`ILw($tHn6!UOC>fdOZuOa*f2q>k8EoHmErH*TrK!A_y5-PL-W1ogJ2t z(}M!RhDtjfAD2A8g*D72-;MPS?>8?Y)OZ{K0az!rX#1x)@%v!Qo0l{FDNg(Y(Z$H{ z^FaFlkWu{m@c7>y9#8|o0M8x&Y!$!r{y(hZr`p;NVDz_8@e`8#ORVDGr^o-$)8qHX zq#q{n^Ymb3_&U@ii1R-=f=7`0> zvQA45I&J!}3{ICSVd~4Jo;}gca?){jM>;BgoPSWk<}0Jvf8*-y;W1`N*XQK4>g~hnCXe9fANjh@nwyp4nUNV$QfCa8$Su{2AQt6Pgsps0P7JSK=&9Ux zfM6t1qtO$|>{rWFB)jGl9dBBe6;Ey_;P6T5 zqd|%`Dby_8P=Znx*L50UYCjQh!^$$jXSQVGT6`rVXS`RIEYSMElvdH$eQ%>c3{0@`e1Kpm5>;O zeETt~SnHWKq`O`NoDs9GL!hyN4*G zG9$Mj11ua}q+r|l5pQN};+WLpV0nrAh>tLit{+9kN&$|a!y5VsJxoc}a|yb00=8N` z;QWY;iFS3{9TT7DvrTkX2m-1QI2ecDF-C##pF&z{ZAx6v`OTt4wk|{_np^-~q~w&G ziIu3Zv=`GODD>d>;>pyG4jt8N6)t#)Q_b)06x@_57Z=` zUEaU0_Syb~fZxav3r2Q00E_;aNA{7J#qn?_?yJ!7F<0+h*RDcx(V+%Gk_Uf&JE&bs zIS-V_0pjSLdkx$q=Krf3o2t?Wp#p(Up^vzfn2cdizJ))3=MIW>(7*X=fFh?8KW;yKqZ$V!wVkVDX@*uMyEIr{c?J4v&bl=F243JfOMMle;_)P;&BNpXlkSmg z*gf`A^?*!^0D36T`m_IOyC86|jpe+25>eYS>WR{dOy~eAOWV7%15ie+6oU25Qm~vN zBE5{Xz`-DY(__rd@*bSdEBDJC+&}`W;7uZHR8~Fw#s=|lTBXW7?1Z@;9@Eej-wXx) z)v}#1xBI%;l$V8%?>yGZst&41FznJi!iS>qFpMH@!Fy=F@pLihQ^5qOv12rZPd7I1 zoW!ttlcy3kN0frK)<409A(+qL%UQe|<|8uKP;o^4Y<4cmG5Wl$zR1aQlj|MOP?2;Y zP&_szEL8szI_iHYE8mnA>CV98rq*k2G@B+~7<}TUtbf@WGW4SKg=(UFNdUY4+bby+ zrV`T}d^Fx@{!(GltOwG*M2?ZN^eATTaG_@J^%>seW>cBnjh9#QtHAB;!P@=BB4pFq zh7Vo_PW<%c)-G4j`r^?3Wi*PW)cUv2GB=gmhge`pZqQ!@#t)zkjZzC@0wnk+V-BZm z!44F7`KBb@-UjzLE6IA)D37Kutm^||Tm25Z6~v3x^ys2RB$0G{A;SQfuiUgwW4!?+ zN2TNc;q3cyoc(_Gv2px?4;cTz2mca2kCBm?;Fq6Y**Zo>mba%LdC41($H>U~_Vfdf z{&-@0d-|2*dpk~lp)vlZoAuX*l3)JBi1x3X+OKO&zwm57)1P10{!h8Qzc#%5g`@lR zgZ!_E`iJ)Suk#20)bIVvyZ={6x_=|;|CxyTr^Nf)hB9&f$zy&`zWz+yGX2MJ@xN*l ze|%O8l><#~=06-(iC6-z0$;nf@T{WC&P(EB*YU*~$EC4EQJ9@n=fnBz|4C z`fHpHWScdW(;{-Yp|((^tf0&&T-DVal7}b z6pHY53xTX-xQda7&=?WI62J)1E&?`aUWX#!p-i{|@R1q{blPW2Is%>)8NBA84w&f# z>c<gbIMENP*5#7JGN_>GEL0v=>p7ostNgKUHIMfZGk|qpWm?8~>=)4sakf1E z0dW7=!QajaX11Rl+l);A#N0FesA&JT&3~`({ds41)Uz)!$6erx{Yvj;<-g7g!Fp>WQ?^6L)7B>eZX{E z+)3OyT~CQPT4M_|@=SY4+cZzqsf>tV8Oo(M(f9QED9FZYgq-lZ)U2&sRah_DI^J_9 z%8l^NT1PjyS2RNxBr5_*h*!j#>jzFM;qeXqA?=l*kVtDjLDG3$G7Lg|SI6(*x!gX9 zYwRCV*0_1iok*B-M3;RfRe+lH5Tz~cCqL}7jUzekUHgof6|tY!-VW9gu_M)}*_ewd zE1I~$3ZcG;>Xa)3;3O>cZo&l=3a#G6UPUdSuX4325AQ%I1K_y3ldc2(*lOAXFejZm z5HbYBufr_;){KA`RcjCTk?9F-^fmo-ixHy<*fA{=P;zSvxOWpRDAOSVQS@vkJq|XF zlQnGyd%>X%T;R1aod`~-E)54JWa!Bjg}eY_a~RRR2x6TM@fqcti2REXN>=$CVMQdz z0rGo-B~XyZ_AlpU!pX9BMpb4A(ZCdf@AQXb!K9$_P@VMz$Ru~Whw%I2g;fu`sp*IK z<(aj|QQvQ}?3zJIij06lQ_y#WVLjtngfue|p~6n}NMQ92N#<-*hZ(vk*<1-vlepBA zT8oS4VF?9L7*h&?M{qI|_8&_)h^yimOQ>}}APE!e0Rymoro#rhs&Cs>)J##`kqK+-Vh2aLStm!X@a|!V5+i(R3 zYAG;*wxT(cICY-RD00Z;4sN@QDSwoCW-~-QM7rn&^pxyh!pH%s@8PSIzSnJB|=v)vv*>%$!3 zrc_)WvXiXTA0)TMX#&YSQwH>NsL%~@m)-}PW~~>N)K!vq2|dE7cmW+JBIqT%u6Md+ zrBd`8-;u(wn$Pb^)OSz_wNxM`n1CQYiAX62W< zUPBW+Misx}iAhI>YbIi6pwsMPq7W~D0zS+wP1`xh&dZA)4~}npZh(e0-PD2VuNcQ~ z3KMO8Q1VQ?R!C3t3!%x95fDy26A}O!UqK0gRYd5JR-_b@1(J)Yx0f#PcS_!I0T%Bn zn^UP})!yezYBS|B-WS7fA^aw5lQ+~L(@lsXs+KZ^8?ZIMuN&u^(Bj!NGqWMln^c^O zJCmuDq7c2UKMNt@{$6x8dvH6i24dVh0$N94e{ZQ`C?k`JDOdVTYfe~IL{fn#5vaCg z{QDC5|HIx}K*z0QTf=6InPbM7nVFf{j+vR6*^ZeR5_8PVY{$&Z5HmBy^gFpX7iR9v zqgn5N-&(WUa;r)uwOTq|sQgOa4wcd!H)3dqw`ILQBy zwDq3_dj5N$&Ug3wdvwwtL83ncJwHzUZ{4>)=(qjVfa|~N)c@Ok`@iYF{kYA)4%Pk$ z^!za3zq5(oN9O+uoA}=Wdj3ta_-~Lb82&V){u{~Sm!9nJ%;NV6^naVh|NF$vf5N@_ zO&;WjWB&)U_z432vjA7RAA*R#%pLrhXub@2Nhu6r$+@%K^}_rgEZ_zky8OXDgcZuz@S=I*}Ey zV8i)*G`!XA0k-+odxE1{RTM*Dm`5TTLlfB1EY-4RpJ@}R`M3pxo$Rl1lx`hWM2w{>%6LwNIsE`i(tK_g8`(bpHiKj$^eYD@+!6 z&s~)>IiMn@ffZtvKz&Br?$-1ft!xrF$Vogf z0o#F%VVj*{wX(#}XBb8%F@r4^e5-)O{q`k^M(47vZSer*No@;){q)#+1y_7znjEqy zVg5A9pqLnFNy;3e5UM90^^n#uK2BL8O9y;68uzD(_qL4LRC?Gwj64o}^pd%eQ#^=| zNiB$rV74UDd0)tFh@?z0f_)xKePefw~Yf zwJtnBo%a|}J8j{itz!wkQ8CjzjeJm9j%?Jl=h$?Dlu_CDm~bEE$zNU-ctJ(QwRi8t z#Ik+i8s4%Lth;=RBl)ddxIKp=92z*IVb-7RP)yxqp0(TTEh0T_YOk8&jL;{7ITGr( z!fPM1U>m*LS|j=sN17jz;ijq!Iwlf<-VKyY<|)A~Fxfkeq(2~P)CD~IEV)}5b9xUx zNiBw2EP&QKS6B=mH>oP4H2G1fXpLhgJAf}r>6jf9(JsBF46&pB8ib@e}v8K#}kD+YdV>0b)I{4BpG`gVjj zjOC*y0|0C4!WJIqI9r1|=p+veWuQL^-ibbg2|5aRke@`L<8)z{nYl|U>6>g5*4)rq z`+&NSnuPODA>-Br{O$Z9Zpx^_avz;?4Rz52n6whB>9Y+usqzf)>3pK~5*v6E;u@`_ zXY+?s;Ap0XIW-Uk$xs-V4t-tItKc{VX&OAcB3sv=p&@`lY))_JGx{rC5Ze%!eN4iW zr@X{02dTISKaIOXxm$&DX*z||)+#kqx@OJlt(%JASob**S_LYDGdq4R-JC7VLRA@~ z&3|f%4W?8!c69F~d`%4}?z80^BV(XAFlY9%j)SVRFVf|cz@yK>lqma&%CXLNiUvbi zOdhJP8jQ-uU};Ok!PIUCsxypf39Bx3r!l(kMdECeDT=057<2v-)rmUeE%ROorA27I z<@!-##ja=LJ7}oRw5D5yNG0|V$!w{;%7Z4M`j=i9v3giL)QO=?0?AMPB}(l~f{jr- zbbYtYrO1`7?e(#gG{{NZzN@@O$Fh*`i~S4ZyWTkAo`r(b+AYw8fhf;9eliDSfWTP| zaaUE=^Bv06Yg~0nfJakxI%T@$@fpXsE86iXaSKJImMxE>cI4GB{h-HhrY8Ve;-Hik zGAmng>;?_LFy8K<3@v@}LBdBl!ikEF33API!n6cErrMW)1^L6P*ydvtg)n$_A3K!f zS5mEmkkvPCWuW_((32b!K-YDU`)otlKD9y>R=|35HVHG3Q+@LU zc^6gQ14jWq4`EiBgNEaF>$HXe(+1*@?Dz3#67CdG&NU#8T4S26(36Zh6>FLs9Id#< zzS>e92CW-tpbnp|RlI~==Mduztb~tZ2^L-^&(5LHTJww2@jm*|P1{CWKaK|~+$oTy zd29z+UaHBR3aBXD^yk%*_|f=9o{!)Uxi&7coD|3>XnW7Zse$YIV6rIplBbuRWLO?2%NQN5?e$UJ0X%-0D%_bv=~KLyeY+ac7 zbgWS9nX)H+_Ox7Xj)Ov0dh?vD*&6roV0XH8c1I^P)amPSbtj9Jfn~)rbvNvdw_9w_*ZVN?9EUrLU==hw))XZ(lY+0oAUs zc#222xYpLKU;#j_u`zWi>jM<&$-BJ$v7UA+ydBxc_5U{Kr@L+wt{(pbGF`b;bX8+^&BIJp9)K9{!lH^pErFKTP@Wtm217 z|HF~&B6fq3?Jk{PtQ#*vxFBPbV*%`V}d82 zG@d%Pr7li3z%29f=Mcrj+sQgWgo@bpZ)Yau(u)fbxc70GA%q$=*?dZe^FjQ?i}beJ zWXrd&`5m=}snpPjkA~51X)rvj^-$Kg5csb+v$^95ggh5tpLJ0Z64PDQl-W`|)eg?D zH|xi6tzcgErlO(*+6UgWu&VIJ@SS+ai?1boW61+~N|TrT64N!|8vY(jE} z;AZkAdaSk^KDRB=gX4JK+`MnK7J6|7Z%8oIYDZ3zqldi*SpCW&bI18D>_=B6=h(Vk zUyVJb6qzHW$fKc+K4fH6Q!wt@UQ-&@uubaClB#PrnGYQ|0m&+j3niZQdP|eLK66Fy zPmyIjC))@4jg8}0r&Ctvo5*WU$(zcaBIbS8M*{CqE)F{kk})5>KUJQO4(gx*Q$Axx zNci~wg(LUF41P5tMh4dJExwoNn19X_{ONh~&*uaF$mp3-w|r&v!2eJ&Lmj6jAdW#C zM-iQco%bn)Sg*yM)V0ChHIz7-7Ss0Aees;eCe9F)kDco2i1k4rI$w2l_8>(d-nr#X z{?uwa0BHB=+SVTe9Fr1@t znLX}GkbMus!O0U1{^1iFk8!p4*L&>}w-jTw&zGF3S(Q_2$he~0;chn=Wv4nCoehEK z*x{Jyr)dSLBas8eyIXlwjZtsB0Ki;4Avd!Pd-<`9jBTED!CtH&k6{|CO-V6gqK}xu zdAdUwwcvHtxg15t;A|iJ9+TQyjb2U+dJMHWie<+`;%Wto*mJR}^_CH^t#$c%%Z*_p z2@z3mM{AfV&A_Bp@l1Edg-fqTgY@INvtipwD9`c+LyTNez=4wH_J>qh@6mC&v(=n$+p zo9E4ma^HzgI94I`4oe>f+fsNqOBq_0!8?W~%HP$3OK6JHY5Vz67&*FfqqY>q6) z`)QmlOCscLWm6KysCefCwM5NIl4ico=B1NqD1(3!XkIU3_U5oSJvTVju?OX!M?2jX=rxV;)Vjh z#wld-p$$8?98`r5eTI{g|3|;vW5an<_OBfpEIvQOy zRLj~3*`zBd#10#U6(r8eJ@PKC#}uO_l=Y($VVS1Q^7hsy{47NF)p!ods9#h$7-LhO z=t_X-Ec9k@d&tL0_GJk!QS2o5y%DonF@}i2p4I}EF~kFq+9IhLm-JoLLAT9)h2PxL z6e6o zmk-}YS0iUvh+V~@8b-KhW*2e^DAyHkr&q8~^o!3$jjQpx)|pD}klooM#n>~N5^fUQ zU8+wkBHbPxqj@Z)ajYZl=CR7O1kMcfVdqZ0YR!4K3%D_F1P`PxZbbU(%67A+mZ-e3 zx7yL{LB_k_RU52J-tNmeRKh8|jd^4>glH`jvXe)%cec#4o@3UVc(+t5w93H_GF{~Z z>d*)DRH}0yQu^_Fq^4z{2%}kVzKy9zz35>ynefIYsWZAQl?^J`&M*T%UBmQRZ%hL! ze|L~j(c(2OO?OSYmn7ILvE(-EC5f`JTp;cI(FCrXe*xbieAE1Ryti8fa}B{##=@ZI zh`)dsC%s}!8}8yZzR<{!X8~iY1Jb;>rz&Z(!0_~2)-Xf)O$Nj?&NX;*7xxV#nLPXa z)U-(;}{&sq2nrDHZ#M$%-#s=Liy;8k@O6~ zELCcu+?r6qQAZpUrjN58a=JWCHasP?NR8yfSW3AXOuUE_6i^`JHQe^bm$f*62-q`uHM zPeDeDUE&9kCwjNEk>Ir2Ob#!R)TF_|;pjX@81!Qrx6+8t7PT$|v*ytiaW%dnm+s{1 z$t3?Au!bn#$!8Tva5{%vK2UsRbDOWLkcF;r70M zfF>vjb6!Ma3vILU;A2GRrw-*;n-7vx49FY+N>(FU!7Yq$$gzQmA5l&)fhu2i&P6~| z-EoLU@W>S7mtCT$C0IPLK~W8KE2Ay6dxbLNy3s$XTgLUc6FI7THHQ>WzHM5h>v|AQ z0l2YmplgxH9YZVx7rRG*sqQr5tnYs~nu|{g8p)a6enMJzq-lE=5$q%LuD3Sl!GaS! zf0uyN!qabF2E{ehkdm_c9Es!@=?1qoz`5kFp4UIw_phh{9V_$iqdw-J)a?Jh_RXJx zSLRo!^>z6bcx8TtT3?r+rB|qx`3EHN55d*{EcfZp{H5>UmJ!u|519Qk_vy!}|E*`l z@~`!b{_QaT|C@>GpAZ^;-09z(qu(9oA2$4VX7Rf(^#2ae<=;5`e;tQs`F^8+vx?t| zqd)qxzq5*eZJgV`JB$CjoyAX<(+?>A_s)Xl_b~E*64vxXuR#6>3j051Kc$(x|D)77 zzGiGJ$?xo^Gb3rzkc=q2Y20U`K1StJwTWxnd4lh_ugQ_mqs-3C9y6%)3;6WSaXny=e`5e++6 zma9=7cpFMHNX)4J7ekNVbQ!)6J^sLcV*Ppb{sGDrBLi`D#drs15L{(Y)WCciFgd~sTJ7TsZLbCKCmJLFu8A+mv*g{txA@=`UeNK zhY*Aw$3G|7Q=oPB*~{7hk@I2fkLUBg|KttJP+qc}L|!X&@+BB>_=y(FEB$d&Q1@(8 zY#hsM0IzL_R0I=c=@#Lir6!p3<_jMeXyoN zv0NuiK@uAG8T<}~;||+J&+;ItMuQl`Je41xRA-5)4!sl{ZZjsWz%j6ckMi zA`(P+DVpYsS|f>@o2a*NN`RY*hT*(_Q&hxC=#2~y&vXM?<v zDtOee)lR!KvjCq=y$|i{3@nZ?goXJPO@XpC50q0W@L%w8qLCFyYp@juaN+&4K^Xy} z2nQ}CF{%y(mepE;+;3;+Xi&4I05**u9$`H4U<;W5s!qX(tR(q!DF<_JR)CW?-rT_w zjw(to#Y#%uUq8*TF25fYPGkt7d_`wg9fNomlOU6*d{d4&s?p+}PkIEXd0PjUJ6J2GG&T zBN(yfU5G;uFh-ELZd79sC16b1`v!ZzIaP6>i4sOSh7qNM5Cc(tX=(y-2VCm-snI{C zR3d_806EK25|>8aM-6)P-PYdm$hSls+^HOAW1jYjo$$V^s}T$~Z|7N$zVj8()_3`_ zNT28s+0D8%1X~Ksy;07WWWHE}7Qnd;3*J&RK8g~ePNWE@wB_8!FEvU_t9W%LmzkuC zk{n;gK1EF2uGR*5h2gYscAOG<>$V^J&7Q{d z%$yP#%e^I$*<&)A7A2xYWs_l|=#w-=p$PLaG?pE~H@Ealy>RzOvDpPnoCl_AJD}>< z?9a!>3|Zs`<&d-dWK--9BJ4}h^$fLyKUs-egdnp!nm5aiT}=&$(4&X6C&C2RKL~wj zA7^{0$##@it`4Ug`=!!|Q&YrEfNr51g{ARM7V5v_>v2GoQ${UwF=(htFw#Nik{*3ux2t{HTlQ8oG3|js~KdCKta64}wS<cI=!TT z4f)8z!Li0bj2su5myI45D!Tv0iD4qoiN%81?4{M%h^L7O6Ied<>Y(LvbeQdk!5VMc zBt&EyeO*z%_G1IO9Hu`C76s@akwB-9c*HwO@MR$p31snzUVXgXdUJ4t*j*teAb_fQ zEu~Jkr0uy{g@mP=RN}lLigivG-1-4KWdqk*U+62Bp0BL=Z$OL@nC7#fF(AKeaYvqG_>cM=Ptv)UN{d7u>5g^Fz`oFE~33LVUKG zC2}+rY9rpi9-$wEx)>}EqsI@cSFyU--VJ6MQ+C}~zREkb@xT(6Mq79F3_{1gdIrs8 zg^+>iSUNAn@hQ0Nnvwy|#PWG(flL^$)r%Z)_i=)_teGL5Mfb3U?B=dN5(g`l9YE>{ z^0;k+_!xFkXB3F>N%7;prb&FID1$B)i9j!c2*_P=j)vf@N#)u$Ieo;^q0R1UcZkR% z4m0o9SZ;FRn{oINz7Qk$uRcTDc!Kw6Ar~+HF22+=P)U~`9SS51EQ%$U$=*&Io+20x zsDO|8PSO?tN~b~dt~MJcN``4ebUVi=`yx=~#SxUJd&8Q!IB(Wa)*WK=cOC<>)5LjH z-%L#|&2j^KILwtvpG}+J5=yK*IxGs%Ij8Bp&mWaBT$%RLV(zef)n(Vgrz8OYdI2ve zt1Dx+BDXZ#3&{%Z_5!}dpdJ2;pWP3$`}JqX#6HeOe`yVn!eoL|aeUgw) z0P2r}vJ4g1*UWW^FL;~{gRq*BD^SPO4R~A-Cj`PU1dsv5&Ac~*>I>#FO62Y<;_{yr z^W@(bRVky!@&f@P0yTVu2mL1L-)f56c@xfH%(=L@QvMZfY}j3i4`b|+sQ`9u)7|y7 z`E>Q6x&6WYG5{1h!1Z#6Dok>OET)x&g3{e%a}zVr6&i#ux$l_^wZ+`)tSm&B&V6Sv zJibI%VQ2f%)dbYrt2UMg^hWjRLFuK>8AP|+yeigj`qBL>y?xc>5Y#R5v3O`v2<6KA zvT(1bgmB|}V~MGYn*o$4l+*D0k-B$I&|TeKR=VZzge{bU)kvJgEhInO`bE<*B~w`AQ*CM|nRr8Im_f)$FOZaN(Z#j;378b~iKtMT+87>;6%E zWw2hEO5O3aCsCvE z)_^XT;4{|v9zlIHc!t%>TQsKZwbg`+9~u&Iy|Ft1kLaBICd?f$Gk9M>KYZ>~^jFd; zqTjDXlw_Yyx$<#SV4CGaijCxT_ilz>%(!t122Dqm34`nOkL+>b3kZQit0I!;AMg({l9f!!RvKS)m3jSd*fBOw-CZI>3 zy~Q+~uW$9}5XndAG>97{tk1_&jeNVY@5A85W#x*ee5JK>Oi1+xs^G_*akFyT`5VHG z6@4`zw%k^G(4B%jL7>&QO4%#+mJT%_m}^ojq~{0B8> zmTb`9MjN!fO}hjF@{Cm{Dt{}MSy|Fn1xs#z9rTuKdhhLYApoVRQq5sUnf@&tHP0LoDCS zU&#?&tuC18%_b+5qKvCskyRq|Kd3H!TmYuZL=_2x*=y}I;hziEzXL0c)$wD>sYYiH zd!SH5l-Z0P^TOK0W{@3Kdq%3uc!CL#9<(*{^Q)8wWD+(bfidk#ON%cQ}P z2&fc1W%dB6$P97TN@5IGfuZpHc$H9xhPS2nSxXJ9$WEY*4#tH1d23!kx4li*>H{QV z`f*0L&S`qq+-Gw1FFQFQE-YD51T<9}5*Oe%9>MG0=_z-ppWwjX2Acu0#0>6;$Dw|D zqjViaUPwRvxe}Q+!lN(I8t*n(6Q?|uGmMT4{N4Jx!589|QLKX|dat+AlG3+cel`eW zg;Cqxs#MilP{nF^8m;gJFb-SOoce`QKk0Hpit-RG36yCH z(MzjDAEw7DN0$q{^G*2jvNG17+GL4|Mk@PbxuT;e`{3fOMk)Y6oR0trl&)k1Mh-q4&-y(yQG2mf?CZOmAp`v{7LLjPv8Ys5(WDN4r=_m$NcawE=7c=~7h?2Yzrq87l}gYSyn`?B$m!E{SbhS0 zJ~vu_7DTJSqQa|IprrRE}5u}xjk zaiXg-4=&$xe`APW0(SbSYzNH4N@oYWH;61>!$n9&jrR32dxmmK55!s5Z4|Ui6TQLf z87Tc_y&9iAtG-U+fT58#0ZsJg7{t~Qb|Omg?y@ENbfgOVtC(2qZmxiIlN(wa#9a%A z5hIMSe1X+@w=@fFQK_g5mCtmS>M=8HMC)aq=2!eg#OA?LaFrRI6}o_& zJ!{*g4*hEO3GltL{qcETbBfv>Rh?pnReXD1Ig!Bkhrp%f`Dnoa1?+v1-!=+gu>0Ea zB{wlv-V>iGn?_B4BMFh95NjD0^6g#GXpc< zP`yUzt^f>z@%$!@?Qo!R;KVkMQcA1}FZ>vkBE%@>Cr1qVVIi7mCEp_+lnxO$l{&ZB z=ea3uzKZjU7s^%fT2ZFp9asU_IZ$ygdr}$jm6M};Bg&SgX`QB1zbQpk|9ifPBIZMN zzA>C{%A}6uEsHqgH`B1X05(nTdS7YN**(5IsgyNvPe-D4pA)?Bxif~eD@UjDNvSj< z4QAY9DW;u8hZkcShV|xy7mwyGI*xyGbye;I2m&s<YWlDJ6Q;YkqVNN zg{_bc(}x`E=)|N{L{~ysmgf?-nP>eW7d*vGhOw!3F`G1_0!kdHO@>LNFg!lg_l^FY zW-eCvITlcNLK_a09u4kyrpUX#cX$ON_suCH_?LTaqoM)eu8#~UJfhUJ%x}U4)?Id8 zM;kYYtOY+*E|}0Qew;9>$-xfC7RIdOBaH3JaKFeD4(Z&=To&t3QPkc!Shv63o)CkO zl)m-|umK4!elpveyA#L0*WuS|>2z^;(O7)pi>^ggmLy?&NbqNs&(d3T^D!9z3v`l`vsmf$Y4}*6l9@UR>Mt!c+a1t&JqUUbc3=rXx!b1(2Lo&`boOt z{=<9yf%OHEJ+`(onny2&+4xcpG$str^=00{mB%N;zbOdDcmG7LX`PmBacH`M|v&yO=q&oI`6mJa!);5=1fjRDp z0hY$is(=@zj`N*N%vjVUsd$M+-{vLvIzAtjLs(I*rKJJ})90X!RS8$pk|wP$1=-%~ zkkT(e(C9PAy{|v#kklDFbpd)D9pyWNReQyT8q+7I*Q*i7Do=bXQY!;z!tH3m!SY50 zmq(e`k`)-@G)5!?X2ON3fn9Z#_Jr{xSBomt-o!zWM`*l5U(ngI+fYWR(o980#OK%% z>}RZ4*Le*ncGQ{1xEAI@FAksS1%ppHGqFou-UE$;Ypy_}y&Fl700yZQhB50b6ymlK zv)f*YkzsR`NyL%%jWL*WTIPHwW;NuM)yV;E_*RI!|1yPW0j6Qjt&o9+NG#F@@H~!4 z7ddVeGL`M39V=}`aL-(meqi%E8OJmf`Y}`0u2?3E- z@B=PKE=R9Ig;|P2l<|)x`t506aO16rwt)>S4m8=e@s_J%r2%F7*3dnc0f z8-mFc8fu?HA?&|UwS2`6k{+elwXRymC4CnTLBHe$O;-^Bh8FaJkh&q0*yTxvY8?YL z{njX0^jNW53`-xcl_!1(-nFH}&z^Z+WEgV9G}&2U?25k0D|*-{P>^_K&^K0~#~4Qk z2Qr|oXPp0ZU6_aXO1oP)fl(fjFlZs9&ZhW?StPCT!$WkBEb}UchvKBHT6vige`&VX zoGeTXfq)f3tR-XCG{*t^TP)er!qYjr8ZGpczFUdKZ3U%a}*b#ai^{TtlBS{-L9rw+tYMVx{&rEk1)wytK zYl!b{+M^-SIJjDRaU!yJyZ|sEBPITozyC9x%`0%lz{d3Zbmb4-u)m$I{6#?Q9|i;b z(Ye=D;IrDKebaJ?!d@5L6)B}gr2|5`C;@v+&D;!ELCnrH-XHW8>*4{0O$cpXpzGX3 zG?J{zjjaV|vSs1GSgR|Bg=2)wsEu+CYd+E=HEw~4c~tkoZSutiM_D0ZYxB73{60GW z%T;TsS3>ttqV>%Q8#Un?rn%)cp~$E``$97hjfiaDVUyQI%9N3L_1aRu0@*Ed$!T|r zW!?Z>uz9|&LV-cnz$pB* z%qD`;Lqy3nsZa^pR%_%W**gess8zsI5b$+b8wCpL&MR1^j9G_q)=rrY8NW~aic>)K zlS$)A0mf&POdEY4aHF)e+z>e9T%3Rz{m*b((74=O_l5R^7NO^%ojRmlU2eWEbXTK| z1+YaA`*y@#oJk&FG$1W^$rO9xd~!vGX>t5o3cN-Z<$UC@LwH8IDmx`66{S&r8mK|j z2y>Dh(|p!INaHNHF6Pq3DYmn~KUD;l48oFZoO9WeE)gyCZ4q6KY~krt6J{=bDD?n5 z`++Qt?cMWp(5zts<-s4fx zzy7^yOR&D?T4H%k2dVj^v6zFdg{eNDm9d2(-Y>iJ+3OoxIec&Oqrvyj|6cyS?~e)r zU7KIUx_&lMa4@t~#$)|u_wNPKpM~$|^~%dIe9giAi+bL7r0OS8`R8xscfj_0^BSIsTH4UV}4D3&hmQv@1>td`(DTTy5EmhuiKcJzaRH|>HFIEt+c<^{aE`^ z{{0iapT+k!e|-Ob7T@c>FTbDb_chj6ZStR6e!erj)_vdm=U(5}zn|mx_wUOOD|($` zw^p(;eZ7E&uQ&RaAjscuH2n`1!N2MB=zqwI{c`F55p(CyR`6$((^3`E<^4>87k=Xv zh>56);KKx2w}ZcIRSYsvfYBP>hibPd{UPZViK^NKb&G*!$1SN@>esb}D#Jc^i+8rD zq-ywLz+$396`-WVs4FSC}XL#+FURg%wfA}tM}FvHgMOFp3g1FlI|0X*n=Mfo{Nw9o>RHAw2Y}VI@TDj zE^MMT;s^#$%1j_7I~b*BMyP*9xYz>)nqQWT`8EYbiC^ ztc&G3ydmMNG`Vz}nf>B={=h6w_6Ptp|a6OE(gEkx|iCFD- zPgWhP_GQ@cL?6f4t2dW6EZKEif0gyVcVTqJUlYoy?4fQBRw!Q?L7{7Z05mU^cjb_V%j>?O}I^ z)eYAea9r;S5aiTVEz!;C;QnJ}OehVoo%cJL zDVBLSNSt!c>a`-h5UO*SMC5`ZKLM%b|(_+tDEr~#JA z1|v88buzQ%X#wx0zb-p#T)=jL1gW>cp0QKn9D!XaHZnPlFB;BzFkn?7*9}VHSXW}M`rmmzKpjM^*jay7u)lNBX5mc04}_yUV8@qOEYShu zlU4%xjCHpCrZAE)y%)c}9PaT+v5-X{e6G@~RR{ZILuN3QZJ%%~VMCvm^WLoQJ%q81 z1_xdcU?t5^`kSF*Q7PFuxvxR;^*!lfHURcBp+K_8dq_5(SFGC9cXkhoND!^)wCcYDe3 z=*juU+<7-^p+eRm(L`ZV7_OU@!vKNJw*--yJv7>zUKP78z4?q*FUX$}&IHD`C-iCA@74RHK%6kzTG1O>JM5~C zsy^N*jTDw3<@$0y@C7&w&xpDjO&HC*1LQ#FaJ>&7QGVn}+mF~T1Tv#bs0^r2F|P1u z5l^ZvcTA4j%Si>uV~8Q#ei>gF7$h`er)h;rvimV4g`j zlJ+8TWvQAzqpr|Vp(0>0hR@0f){-)cf8LGAQ;nQyF{i?pC>ViJPFmTq05q0(ABWZ% zROj{{d;L;yuFy)Bz#vCeQyyUOF_dxnNeZieN}#U2CO+pX=7THA2jI|jyY{9iplF?h zPe4N*vXR^I$uR6C%+uWrqHmXb0X;xzu|CK(M1PE&bi%ksAhxBVi7Q^4>wG^uG4}q3 zJ~KLS@*~SgEof3_EIXi9Icw<~J~7fYp_Sx-1#;JT(3`$4`iUg)widu^dU!gh0-X4Y{h8JWGg&U&dx%AS?u7RCSrF5zqPRl_?Yzvc{q{!hi zWHM}RgC09vr}e^X^&wrzvR`56`pGwCL$sCgC?NtFTDMVPqI8;f)n*%2h2KDenuntc_Il|&3f~`*_N}FI2%~i!-@CVWT0YYE-Q9=}hDHu%p zdn>&<{pN*z#HfbGMQA% zslX%e2@sV!%@*9A^OP<@1ftNdHEHn7dg+985Fb|5a=tR)v6Z$4%mJ=dX&-TeY8C{G zNIP{8oLok-Ab17u*1r2fON=pa6dHU2^6(0(WoGXmdVWc`+Kl!hD2pR$ooT3MHe$2+)SG- zgp}m{p1HpVj3U$udHFO(sqeVp#vyS4o@*K6GXwG&N0dBl&lgU8EYV5cc!129jsy;-{{MsxNfG^+!vR3#3 zqbKWQKc*kY-R${hR_9W1h>41kx*i}AYL98%#b^A{803Ilommrvz_oCtH9L(rXJ?pS zH&|voM{N_JE)tIxbK({GP1L=*D2zf>*p#CkdEGm@U~iLVz*sI}fn%f5uYkaQ zfX3t_Hy`k|08y6U2|mm>VaqtM)ai(#UU?HcCN|8B@vSZEb?M}d&HJcj?>G{vIQF{m z)p5g!G7=WXM$C)|*gK>LrhA{0ZxrId4!6V`jk%+8#^v_Bt^TX59kOaFS_OXUN*Vde z?)9P?gS``1@VCdzgt3CEFyM7y^*`iab z-`Aq*GMqR<2}Do4_b55w^speQ+szNCzZcG4dwa%LFoxQd<0G*6u^*bCe7p$`pY3gb zUvzp0pF|QGkd`|8BPltVkkSYpy*W}rG;Y-(KDP@x~+Z*hi$pYHVJAI4vb8US-Wv+LgD zFAFu~EnE1VBHmy)F}uE7JVS7D95x>dgd1OW@F_{<1NJ9+69XrDocB$vjSK2s^z9zu zBKPFm2*I6zm$;8zq}H-NF|dUV?luBP>&Q(vK(;Wh506|mqsMO?9Cv@e0Cm?<3=i z6xxsJqwd_zhGLx`BhzRrP>sO=@5-w$_MU^}lm4U=%;_+|je@wpydrbqTfjBE8@J}p591LT%I)BfIHx*G80)ZsPZJ=l zX=!++P}S2KAUoO0rqzh*Po-YfJnS{!)@hC)Q^6pUqzQ%J&7vKmd{o&}a-+gpO(IV* zHMpbAUqJE3h}dk89wRVsWBLT$HtCV4D+0oZ@}wZ};+o=-_krC#+!3N}#Y!2JaXjyO zVA<7&N*J2GgSESwIR`SrV?(K&rBD`%lnHqqU%cKqTX$e5CWvR4*4;J+ER?BHsY_Kq zjRz9cL;r!ULOTW2g=seY#&ars=S!;GV6Su9eDt?HNhA(XV?bX8z(cI@RF<*M-B+NYU(VGcswaCn6qO zZ{VHiV&hnKv9G$LY0xhseVwQ6fV|!3@;QvS>xa({3+R~5bf7_&#~Ok7*NmJiu{n2D z@3?)Q5K7Y*g4OWv864-8Uz6>(#@nGy49M(rc!XQ&1d}obKYy8LiCONlFRH{sAG*$8 zhwTuQa?^!H-htSLMCl;0dDpKmr;JH(WN#4!ATsFIqZRE^UBXCgFT`1#20^jAZ`!}O z9ZcQMC8$r3$S^N;1lVbI0soJ&qPxA$6&;^592ttHs%AqdC9%`Qend{S7Gu~@G*WuLc&jm(6npqQ_(UW>dU1ihk?>`*GUQ815W^~#Ox_6Q8o+n zOqRnZ2bKG*?6=@^ftsKMtz0UxJL6xVSMumc1yTew<4X>q=&X2mty5m9vOwOcY+6ct z*r9ABmm=P&IEh?pcAvZezlyp_xqcF5L9%Rd5a2)U(~`C;Qil-NL&W@{lgJ98KIG%X z?4HF9Z(PAbH{7a`a~$wI=mytgAMlNDzq;P2=?DvopV%~kX$-$Thvr_e5ia)Pr^eEW z)p4jJ{|#0z?-M+kiAUet;QAPKcPV$rche4v*NWJ_>`IoV5r}5-wZygLg>n-HY6t>{ z;1)238Q4ivWhkov6EMf_cVz3vk+<$vyl1^Vwb0gQmCg1Ni(uz(;Y%mVvOO`Wol6e1 zfLF{(m^J1lA9%fzjG6`li#M&otod(Y`kEi-3T0|eL#_Poj26>4%Fog?=9w!ijj2H9 z*t7DuP`LA4^KGa?X7eoB@ zp=}B%uXU(%w@+l{>UQ`UHYP+%Z_Pc7aqX%B1GgLP==yu^^Dx|8^4v;@R3W$mM+IB} z8bs!cfv_kK$({IOD4Ll9Pb$-SBn4I3y?hk}T#$qtE`dCZ#~_?(JXG$-5*alRLJfmy{nIzP(^ILy0M5xx6lA~uE{#VI~t&5ATTSJ*b!h7Z+r z%R17=Nf#+nz(CohMTij6XdeGm3ZPA-p;=;4{t$VZlkHuGh&+W=n(w*=W!h^bPz{(3 z?1!sKWrUe*DaCzMFz}>YLisH~M_#B-9#%X>G|92vDcviU9%Bv{+9UFvA5Ed*t)RGQ z@uZ;lcs4EB`*@v;+HLN7O9rTxd&ON~D0_8k8ISnR!IzhT)*Sz7kSYY>i7*xnj!5bQ;5=|0lB9N;; z)YcpQa4px(P+=O?8FX631_}8>$-E6-78`KeC)yOO9xn0Rlw6Weo+phqg{Vq<>J0#8 zD1P+!b0oh2fIm5rw7*l4>1qEWDuw<(5R?D&97%KJ5-t4EJqjhw7e0DiJrD>mzvkXA z#C+)|wo6mjHIl^#?3z!cY4u$HA9HU3l~=N~jp82M3Blc6 zgKKcN;7)M&-~Q z6R}p<<0M&C#myUZ8%}lGIhr(ve#4h$w~@uhvvx%vg7$mWNI#gDQZQh+1>>sZgsbJs&m} zvkuBQMk_MM7*>OQK17v&hzoR?FF*27eRsdgj@9fUX>tPjUe^tp@~ zdPoTuAyM77iExKac&x?u5QG}0I-Ug(*thywn9QsnE(F{6ymcRxY211%B;u!J04~Qs zv!mNwW9R+G{XO8_?ale`hSd*i>SuW6=P`-&w72Cm*=T`qe1X!M-hv)xiSmPO{c)owWKL7uKA%0wcLLWcC zjh`Xk0Fx)sY4Zp?zsNuH}^*zsX`1Aii`#rzuM~-g;^e?#0ce4BI_@Sr$ z)uiHI2hl%|@E<+;zrk%nRGi+vRfus9sB^AY3sI|+EU6x=MyjYK6dDrZlkPLY#S$aE zAWuUzDft9NDgp$q(=N+VB~2mSg^CMU{st9^DInQMd_F`hv`BJp|BT{xWpG{z<>eO3 zY0sTU{rTdPYP!qt>#f^noA~a*xHj=b=KZOtM%g+-1=;kt3aw#IgD)_C+Sy|*v&Z1s zJvg=Lo&%xpPu(D|iJDN7`raSZhPX>6x^X-vr{g^0H>^FP`)kX(pLRA1N^KU!h5vQrR~m#T@OE)#XT zcalTTTq3a*i?3yFc%XY=phz1^yBj|wPJW75@iD&7RA-7-EgohQbd!1WQk*!lo3pJ@ zpPBYFo+N%NUSaSJak5G;rPeEhYPyQJo_LPsGum zR2UL^#qkMnBCkUDS=?_7CSDa2)2{dRnn#4}3T@Yi)XxIS%)lDej9)4mI9i zt~5M4k9=|Iyd17oakxCQy4sNPQLrg{8L` zx_4uo$xA6<*tr`o1PFUUj*A)q=EzS|P&M>0{UUa77r^#4g6v+S2r!Nr_8-20tNJ0p zu4<`QLVfZ}`$FUm>!ijO2pA-ep9O*(0cB=|tp$ux9ApfP0-sxovIZMBN8ZXS7dr@T zZBa&qg@-1VzX26S5sab?5%&)18U%p%eV+@elrlSVSNAx5= z{mNse7(c1%h$u=j5OD=Oxk3TyfGUa-D+PwH`wxq3ArudDMT^q112 zzHyk^08$5XOk@ar`AW>UT9)zrFYbACMWbnA<+s!L)N~d-OF^Oc%4vJsy8$^ng-6s# zW`q+woATnde3mWEYKC9b!-~2f@BzO0dZv)Zph)2$mfI1qHUPc0C+;(S9LA*z`+B4J zQ?=nn;vO)$+|SE5_o7{cJDTO31l8-;dfMJu%ftwDiZ$ z+qxhz%X9JfFM)#y1?<@h-ZQlmBj@Y$g+YcGvxZXBokxT2y@24_bDdoRdO&q3=-~5L z5vT>vYbb%A>h*VGqFz)dqqnAA_-6W$q;JF%=};`I>}(9_u7X_b zbOVBI>@N5WOU_A~ofZr()R0GstcZ>QuE8K(;4V>&qr+QWSJ`Nka zc7WWVcbzWgkLVV`sY1K@oGNwPSYQ>L1(vXB0hVBj1if9d-r_(ff%#tDMXj*7dH2Fo z$2sov*)dndykpJdukn3`;&Mg&RFf>Q zl%iuKu)1L5mqcS#$7a^Va#ZtnX+Y3HpTjN!f14Dyg7H=H0@@3FP$n78mMb9Z!^js| z??xcKjc(WZH(Tt{aTE`%Z44pzFYMhBO^v?zBEKG#FevoRR-I(-OM?{Mn-7>l@j+rO zgp1~{olo)IvGqCZ^;#$1Ti;5w!@e`Phj6#QkO4IRjEta_&MA1A>3j;CuhtK|ofUAKuHlS%bZ#A0hJtfv$dcSNt<(fN8ik2ZM3K>=h=?bPHy)NP5*jAPrybsq z95oppi6b!x=735<1{0)%`u9EqdUHk58 zPM#xND6JD7HfthOv-VlJcH9Se2?lkiDBG*UwFACfatPkk!JO6W%^l$B?Q{(q1eZ-M zgX=N=*esSJsd|(;=~X2Pjm%xP%+)@WwV&v-;JZF%LAFMeYX|GZc>INe$?J-LX`qip zgc#?Jm#eD7W+v1qVlEYKi-*)fzzRQ{c`6LftNF>j7+ozs@m!r+ih7R(zavy?s9vhq zo?KvPSh8en=9N!!TX9;e4Y0;A`f7IDgpSVFX@PZ(unNHnkmJgGt znccuq!zBpwtTm4`EV}cI#eNc8l&y$QU_)}7H>)#eKjp-X&E%s@~$pJ*91y( zja#-}$d2G6rRtx|lwMjujfFf4-YIQ_BfovaLHc4VO}T^`*iL20Kpb%X##&nqv~t|X z8Y8^}JvXBiUg&+nG@wRK#RMjx*mN`3%M`D4I_8i!NctBaWqVPwc2VW(ov`&0UI;J(Gp%u+!K(7Tf^afL(1^aWuP@k_Udt^vn&X|$HkLU6-q6_K`eIs* zqJn}dty-y=ft|m{G<*Y_yF0TX$i3`isP~=)#y;7y(bp0%H2#J>y@Wo_VhO=w72t!f_#2>jec7AxV1o7SIA|l=XYmr) zxIsI`L@o;PltoE_RCVlI1^^}fOPD<1c}wEUOBS@k50Op*jDy&Kuwl1L9jay7U$t6B z%K=e~?%KaiZWVQ3P94_l8YvM_j~0az5^aKKK=eo&oOkrGn`o7KZ$<5Z2B(3cK0eXN zXuKFAJI}|lNfLH@iv=mkc)?^VJtUZbX=Nx!6*`|y{F-rR%x4osrL)n~1K4ZWXxCjM zAef@wCY_|G4im@QX_Cz1^Gk(GkNSo|(a*!olw;&UyehKEo)iFbRBEm|M*%M9Yn%tR z9Is`L1m;55=H&1g5l4{HO0$&-z^atVX{Pwfm`j+0gvM!{_P+4HTALOP@B|t~;ViIGO9VS->&`$B=;6F2m75GNOuDN8Uwuz)yYvtZ5_-Yb0x zNyPa{`T0U`U&by?^GfFW^sx}hO5o|XY$)0+stE$1np|P-_JKnUB|{k3rYWC-r9!Sx zdw}{<0XA4Pa|5>W;st_L@vg%p!Q2DTrSBF`JDzkwF7hAA+sQcf(4$&;d|OJ*I0o|w zI2wYJ$!TpV5qnu_aSOP-AVfdFSRXm-v^K=u)sZ z{_itjNH-^a6s&ss4kPDom5@2#Se$CNL)SV*?qsU#jMx_e&eiUx>4MDE9iRF5yt~s@ z)Jc&^3EJF_4P^0h)U`jpAuomG=x@S2GVWlK0YR%zeC-05N}_Lv(vao)c5ALv8{S_} z_bUr-7Ewmd5g~H&WTXH4oLiQK+qPa&bS^8u5{RWPhKTT3Exn9bMIV+{9LIU(vhy_+ z2)LCPlJE@U+4%O@IAyL@w|G@3y%C^71WQ?E)?(60cL9bX6D3p1}dY zig|z-h@+L-5&>hy;o8zPVvHAH(e4*u4G6~~byi0=GmG)6WZdCJ9?eQP9k&dA65*BJ zQ65c0maFQzWHy;3m`UYB4QwydbNrwe`+@a4U36a$Bpz9FD@!92Dw;5Vp`KPw+5#?&h^NLvPpvi z0xKC;={BU%HxRA>PiT}->>otd#kC^DYHXAYQ7^W@Fn+ss8LH% z&4`M(QZTj`{oDFCCRY*r>Re$Z7$tA0$FwVG za!A0O_v^d|yeRN$`#(ZDU*9hUY)Af8W+~Sj3|o=qAloZ~u_58+2&MH( z4@lYwCZk+tQF++r?fSXWC*-r-RLw;Hd1zXT8UUKlFXe=J7vwf?mKv+;-3p{YG-OgA z;78uQrgnhgEW60K%GvdkXp{&D??fv%*0aV-Oi07Rjuk%Arq5fmMp9JQg&TWGLrCUI ziHt~{T8##onA*5LQncOCsSouS_I`_Aa}QB*@N|Y+CrUKx2{RtsoIIL!4v$#k9r%DI z)ToZ91lQQpu_^4M9+L}7OeCsFt)~Fgdy>fNoYOVC3 zJ2uHBUOFOOBhA0PfHDbdKk`^Be$dxso5@L8Ho%Ab0?XwX;KfQ7h>Jw}8#wuT!I(ya zRvW!cGLxM%k0sp~I>GiTLPu#uH0WN^qy`x<-4;wC0IG4Z8TrG?phEoWMDOK0UkgjW zC6H0@%9qWjU;<{2$YnDdUK(n>H*6wogSK5(1Otc6oPcP?J7oiT3G{Jzs$vDeZDq`w^aw zffMyu2j~vQBLm5*))`EHmj)KCn&r-9Yx3!HM~G`(^fYdM@uUZzSp+dIu3exi8z1Bw zbxiWMPgNOrPRnIe{2%EoKi=H%H*z$X()mc*PO}B`Y*goG;irG44o4EHwh{@>J7>!U zDKsjwKB-(e=YaFHX*{=c4gKVKA=^hG%^8mJrImy?r8pNP@C|u&o+gN$vjh~^iz~~X zRZlzG(gUOGU5EwrS+p{qneqJqA>0_@K!L769pET=lz8atiBZa&QgELI{fvIOG){H5 zS4-(cVf**3f)H=_lF_kz%Gz{O7$Ag?(zMfn!1@XJq`({*zD!Few{6UT&ZyxO9sooR zjApNZ)>f+)040~_KOs5!rw&k7;LD94_uN6aZ;}qE)9zR%?LoeLJlGdrLiYHav8+v4 zpiC9+%FkHPH<1*=>7~cZ*&15}Uf0oiGPwvN@4auNW+4XNIJ_B2L)K{p+9~@*ah$KF zq^a-Ax(Bf^!@Z}0VMWs{?9c_Vm>k7R9k|HQ@Ii@J=x+D-l)SEr5wD%_ljiwndLnGu zDDVW3l#XBb<;0diN4*2O3vnHrdQob}|E5cqk#)S-W*djhm%&lNnG)%vK1eFBD$GcF z=~3B*=`n5;jQJU-e<>H+3!*J($4)E`fH8#W-K*oM^HnJj&Q5Wz6rLmjARD@J`s*X) z1|g5#Xf`(dUX+qCZvLDp^;Gsm$$P@)*nk$$L6!hy+1#i=yK4hh4en1N@;pku8R$0J zk_7;_FT$Z%R`yCw7-4b!ldxxZhK`=Sm z&tZ8W+DTMo=QU#VC!$Dz`N&2cPQ~-88PX@5YfbIvcUre5`!JD&N(=@-I@kmQ^oZQ4 zIWq)_ySrcmH-KJQOd6VM=zybH=OJ&_F{-{h{Se1<;fMq^K2zlbO(429MLcYikoVY} zVb%dx0pY;-5T2&NF8~*@(HJF*r_y^sjDn-i4MT;dmG3Oq3=eg}oF{kPF?znz2njEl zySO0*qrBR{Yz-zfoODp%t~-Y{o6c4`%2SCXxN`0qgGx#?i`z$+J#l6$|qH8R{##Boz~g}s_Ajvkn5K1?gYQyCad=9J!f&QlA?FMpJEjzt?}0=*ZYPcYM2;4 zY2*nwJQ(fCO*npBJ&B}Z5`N;|1kfuV<|a~{K&Yv_)XmTLLJr3OQ7}fDU2tSu)N9cs zlH={HMX%?mfNLlXI0xS?xi_#tEQaa7q!~50L3~V#f6E%30f(1&C-2h63YI;VuarN` zS5#WvO9@mVa;yh<`7Z7H)a9%4&3IYgte(YUbL>Si(17QZXADH8z+Ea#IUJybz|sUZ z%}jY~jK1d9TS)2)6>CDS#P_@DyXUQ@`ATZ5YkG%bEF!Fq2OqmX+cflClC?)6M)vf&<~;rF5Oeup&uFkpE?nwVJW{_wz0 zPx~wI@`v2~e?AB3PXMO;fcX=E*?3CfC=Tao%7w&3D@}-obHlUX?m;N~4ZplzZlN(G z5%GLw`cbH%V@0H3bK}Z6DMx~Zdw@RaB)i90l1MXF4WsY83b(tdG9djkL&#EM~)F_cP?c505fG#?kRx{AWK_=?RZ)5vI*9$zE z!P@NdI9-69Gw>{04NvNH_)R@B^g{%PS`z>{?**;`&R(vtaaL?%u%Bryx5@PIl8o~s zKc2l@o~`H}&(FyrlilubR1xAKXx$olvkXb=$po2hG~-U5}OtqDy55Qi?U0B zT&HxsJxDHEVx~ka7eZ%3CkTzYey|uqn>gVu8B!!$`cDt`XR~cNPY;JM6;Kg)sZ~7{ z)rB>(QX{Y_RJ%o!3{o^sm~{WdfSb=y)UV*ww-fySH{j;qSN!k6O_uNGWPiqsalg0uKLR(I z{{q}ShkOtHarbxE@9BQT{>b&*?LWevuYZ2}HRi|t&zwKg|2MgQl>H#_Mcz1_rp+3m1o}$Qasi;b397`v zfKnhjA!gkWhAsgvg4G2Vk9a8%ZG*h~NWF=zLB;cCBIXmflU0?IDo5cIW|4Eji)G`= z*o1X&xMsTRi+lfIO;W;R=}ic-H9lN_TktzEaC%kB~B#4W~i5t!byT01qDj$ zcI{HdX-)C{;O#8KD`B+NZ0jO94Mqb#Sk+#xEYVWyh^bES<7jUZL&N*yOlJ`TfdlDw zX5z#ANU`nY(d$yQrtAqg|pn|hxQxt_^luQ zrBuW~`-j~%J>Bngis=4(Pq*sQZ6=+#$c?ushqW%s;`7xxxKaB={$^qm?jB=?_WBSl;X|xuLFdau?kK-<}9xZaCz{I7)SnWiGnFvBjNrpuLYqs_2C%YS^TpIb;aFh^ zqVa=NQ(vRl9NEAFHCN3CTqyH*gxE0DGRA}(Bzo$R!hD9OB7Tc^Yahq zKja9Z5|TUTZoeJVwW>F^A8GP%(P~26D9p-2v<}_kTnq}vJIFtA2lNK9>-$}!{-RPt z&+vznWqP`Qs8S;!A;u>q@rz2$(+L9q)0*>SUizf#!1!e9%0U00%$1*#d@JgQx$^hL z?58TtkNE$_R{7aV`p>HkJ>9RW5Pzpj^XtU^_Ax(IYW}wBPkH2=Y@TeUMa>N?o-;jL zL(A$L8b4W$JK>V@KAq{LPxc)C^hYCQt*3AOY@ifg08kgor6{tkM zed+g()6;%37=I#;-%PE)HM;CKn*57_@%Op>D=$D#_k$CE{>(o}@^{Mptrd*_>ecf( z{11}++@t^IM$s(fwHPojyq`lPQZ_sHGSrK9JTG4XfycH0aAs8qRAzkUKrNo~AW>A< z!&YQDLQ6E*7=a7S_r6(nJVzumGe&jLbG80ON5gWQ42}E&TL^FR-dj4^ECp~lEL^y| z#7c+4^DUSrDt1&ReAt{EM4L*kQ!R8VlRtH?BeqH#>*r?jVI;=GQ&;+&dA4`o(b(t? zZga=m6zHLu%Rkv;>7!;eoixLX_35>zjSZIT6brlkRK0)^c&U=+EPqa=n2$5S2TzN| zLBEf{c+QYwo`!b;1hnhAF~Br8Sz)8GeUt^b3jDrMrI>kqyv6-nc_3stSqVJR1v0+N z7yQw@=d5Cx0A&6CN&Ia+FEP^INwVot?m!-2I!`=;YK%L#{f%|IhE*I^2N*`8J*^+ zlnP^utF|`^=s_hxEc*p44fDrm(p#bz{sfpExnW%7XiMyX8^U0K>^`~l>#t==UOW$O z#d7^>wsYH<40Vxn^##$(^xUaN?^73%v3F*Nk2vI*r**L|`d&-Qe85 z8HXZYpD$^;wS!=?bjwYtf#Rpt{QZpCJR#TCo_<;JXp=28=V&Xk-?ZqrM*7!UM$hn* z)u;cJ0r^Rb{+87jkd~KuBlHW|W%!?2{pY@6d^+El>B))y_sRFSP9mO?{4#m}MS5s{ zQr#c%{~gu+u37ff`Tz0|@kayvC+hQk75Rnw{B4c@p2ufo`z^uz*4Y1u$7lQtkN^J; zzxw}&QkkAkH~lNm{IAp1f9c3?+J`@OYkv@dXP)fuiNJp(&~op@)%4N1uw8FDhu9=O zb`RF+CB(%I<+V8m1!N#SifByIOQq{rl4Hcqo3_=Qm|7!=c>v# z79RVE#-@VTV@1C+monE#T~nteTR41gt2A6K(t`P_Z!JK=$(A!gSkeoe`Sk_273)E| zP?4(AXG;MMwGJ!)+KzeN1Be=bicO7`3!B?ohuZVqOo0)rmcGRZ{b?sCThKDEjrLfm zlJd>@FHTW`=z@q4)2)=dsf{S-KtSIEvK4Y`=0)tqY)) zS(3-ZLFjVQZ=@2v&9JFIqZ^F!yPPOU!=G>ol%0%@-r*wb72TQkNrS8jR+T$K*rkk+ zP10ILCF@eh$S}6(PV_BR2tJmdkXtJ8)MU_tP(vseTCn0v=;m8N#wUAJQ3a!FD9r;!$}=mJWOelg{;-56HaopMDuYdBmH%Q3(oSOB@%Zch=%PcNyH`pt3tvXyJ?jP z!a>nVT$Ki(uDX)NanXsTxk zM1KvlW6`F;hMfxjWG~NPsOD3O*MCz9oc#e?yGQ;O2#>!nMFe1s=lzG(v=1($h#pL7 zyCu6F#iL{C-MoyjUo)my3#~5Evv|<_M)V?j32ET&MQSC{%uZDYcM(q>tUtij&`ZrD zRD)u3%Q6ImsXQ|g zb!x%kU0Ke$hRGvNlT@X*MX+Tnr)3C;U+)?nl7uLy7D5UhH(R@aFh$U9iAf{SO2U9O!JLSBz!M4J78L?dE+>9JA!2wuz9bB2kID ztIPq9TJ4nrkEY5EL2qMnK2t_g5~zpQQd+1OYi^x#sJ3>FyWA*jEG}n2XGFeJOokN6 zYsm(cll6q`8kPA%Vq9u%G3!GS95c^QL{|yR0v-hd%A^Wof-e72P9AR|QGa#fIxC6+ zZ$yWTpib$aC^ANyYC-}0ksVt^p7N9RPD)=1XzVKVht&8tLp@;usn8nucYFg0G@+|O z5#g^ZvDdXfk%Ce{rvw+!eM+fJAtoe!xV8l7@bt7?f&f|U4&HckZKx`596HNIEL|KJ z8(4vrpk-t~=~95lh;(YON7g}l1}PzJy>M?fBh*;Z!?KO-$Fd1Mf!o+AZs%Oo4OFDC z6N3aRl1!w1O~C701L38QA zLV?9!ir;)t^VLo%X07N(4knYxcijS2M z{ZuOL{U;KM_$uc|P}S|K`rq*vKla2=l$MTx{-^x<$vMlWcMkuNWeaaH@5F`a zc1USovt#A8mT=)m&a0=!xDl4P1%Ql0&I1(a4XY{foKW}*@NhhfQ|_sGv$dE2arc^) zO$)@V5URGGO2h}!P*+94o1R`n$|-hW8-wJuv;-k`(WK`K>J>QAG`c-2CmG8MHZZ^g zDl(X^A*-vpAO4HPOYYjV5M1SHPd1qAaBTo(jx>|23ahJv*hkGx7CO2O2Nhv^I zTXcTjFq`M5ZhNa!Vujc$FFg#i!9Gk?+`=hQ-5hUp=DO{)(O6dZ_=05ddcA)aZO7NA z@^{VtW7qu5C^NJD!R*lgevA3HY@IZpAg`*(FKiv-|IF6WvwfG~GO;lI-;m&bV*!5M zwK4pVWdBp{?(Zx9_uL&F)9<;v?_%X=R^#W!^ndjK_5T&u^}O@PW2<~ z=iSfPA9sJ{)V|I1Ups~V$vNC_=KlZTR$A8ViBm&v_H7=(pw68L8i23RpH0F+$4-<~ zj|SD$r)#^kR;@nq5a2>4y()k_c}_SZAhe8cHkO2 zt<>s(d@mqsk}0+{HWoKE)?Td!)|oj$)ut9~$j*aY76}zNk(V%9urH;3HcB0=e2mFk z-q0s>Eb-Ede$RZ09y$vX9s)&dC^GfI74M#xdSvpnFsaG%LzDj?U~eFz=|EMF=e~gK zxeLQWpe;BqRamaUF`Dw7-RbatB9EB$kiPiHM8??$#~Gn4%d*|bi)r@SDYdD>0iK|+ z!UIuyFVjRmH6vZs1uoXA!y#`PMSuYWanhH>(Q7lQ{*WPfR-F8kb*6`}(b72{`*h!A zH8T4&3RL;T5M0X?6Yh1sLd*g6Q5<*Wb0DQ6bO{;-7Kx%GEEp-eY~-U_B&tM*Tu8J+ zxFAJjLW@4peUJSRs_Nb`fHgY4Ko9Y;%^pD*0KERjyJ?wUXFNVZyhzL1eI{Kvx4S}S z0zFQ)osk;ATx0;+I4<>y{X!0H{zXL4PM8m{$Ep1e3?J|p_GEL*>MFKIW-T~P{QK14 z;X$Hh6CI`-qIQ3n1EmGNl>03WR!#wbHui+u;Bj! zV65wEO#Px_XCs}-XYMLq`>K|`qCl-q2-#~)n$i_xGmkol&AU*XeYdfyS@p982n~2- zI7KUNI|<$5>v^~iVE!_rmtbpdNUtYG8L%aF5syrI;^cf3$G*(vzG|B^sPS5uGO^rE z+mEUN8v#-z+*L%NHB41p?@H~Hek1w4N4lxF@j8QK*6d&Z2wyE2-FZ3 zr=V3Md&Po^jG_FyRr43|5*;nePs#q%vi4Vk#qdlL|9)%vC;3wN$dhCrzWb1?>t&6< zV5B)e8ef_z4ci&q6SE>jk~f-*ZqqyGFsTpydi(CqfD1#|eJ9oB9sbef@}vg>v94X~ zXER>BU{r!H#C3x6T}FQ`N29q;=h;9V?;@2#4qZM>T15=o}qS z!hK}pna0O9P&1IWdRRtD+l8RB5^LV&S=T+L4Tx#GMn|a%}x@j^*jJ;P1=w-(b$HEdK(X8QK1?uq^*BkYf9Ng}>F| z&$8riK|cjje_!+efo1tu+dN6bfAWC1^xqo&9|@$Mtxx~VNc?J1`!nW;_36)$=er-4 zw|@@(XHVbD_*v5Po1RN}b~5_c-*f11Se55_{wG%D2^9Lx%>O?VDrG4fJF0C&H{)Hm zYePfwRz%BAjq-THR|A;gQHqL0!W&v4(pc>|hMTFBSE)1-h=#uYlFm_5ATeSFR9e(3U@FYH&0Gp z3`A1oE7^wc_A&Mq+7>2hT+ddawSlxWn-AG_Osm(s@1JYVkGidyvAn83zLOZ4XSAQ# zD%fMOXm&EOTS(x4hdF(>Mb$IC*j(+je^%sRK>dgWb=1!uK_=j}R7}7YKLB*VaO0$% zRCF)Z5EeAEns`L#w~I?dbS$-9sDJD2Nk3d z6g-Rya5ppURg^{;7ytbc|y5-dHiNzRav};(!9FBZGMV!qd%;EeEcjf;dawDQVi@qh$FL=+2s5zU(Qxq)<;8}H+bymG=i-KDsAPhed* zuBjqa5A2_uY<+V7U}?+N3mPD|F`j`Uy5faS2dm_2~} z2huj^?6Vsp97K}K_~8miOIUz-m+|W70UuD)VBDXuZA09|NX z#sqXfZ^T<4Hx`V`=Twl6eTMfA{DMag{K;M`D(GF8YVMe#iVuV-*Dgxqya>6B$#ep* zt}(5$yp{}yd@fMoN26N=Fk0-d2Yv_gl}j8@DX+Nh26qO9JWH#}>!6-oRp#~gr!|T@ zk6tm5ZjwV@x)EBGzsGHkk745kELLfMc#Y_wF8A8Rm=}{N#MzQSbU5?&R+knY>wE+k zW+kj*2@LAs%O13WOzT33zzCNlD@KGNTm7Q9Pm?&7$30zy9Tup)w}P3hhp5cWq~d|O zRw~aYZ3l!~{c-f6sckXjBwbB{6g?ZD3=dJYL1Z64k7|WB;0hs462LqGb!~DVw|No! z=~#L=gh%7US`N^?rSXsD4YrbOtoo8!avc`eoh^-Y7hLU!me~+2K;-K54agds?!vWm zsM^Pem4br`x0i$e4lb-`UzFTw(}`bAV8H7VqiTAmuQ0w0dpFA_vG#(f_*-8GbkMyb&d-yhO*R9NmlTBf<^tEDZM2E7x0nKPE=(`o9LzDEBgHmTx2=gl_V>X zn6x2zgkE8I0w*19EVhs9Vy>r6j18|;ZxdWf-{swM61OoAhA6`DUWeVVHcLj%uz%)) z-meHaKBLX__mhpJi~BHKIduHe?(J(*A3W`KTyt<_4#6pM9`F@bLP@iX81Sr7B{T(I zfd%~oei7|h|8iYnT*PA%5A}D1RlXbTd}PSdAGUDs-eoIG2dsj{ztn@0sJbRCg$g{> z@bcb_Vunh{ZCAR))>Id0^9v4`sYX;QRu{3VjC6^$tfABokexk5OAy_?eWLE7j^6hu z+S8+}i*F!PZu?e|l8DwnMRv^GSt*z1B6wL^rJ;@hblq$^wW|heo2&;3q$YE+0!PXX{dFGRtdf z#l2Ej4@8aukl{!--=cXmkq9LS0IK+7vNPUqlBGn~Cn9l)T;Y52fOsKDA+LFKe9ps` zam2GHRh@>l+dr3a13JTwA-n*}Zfa_K1#!_C`8s(tc{?;1OpB0pB^}NMO>+V+NL%?O zg~=Dt`32|I8z%*4G(PP9WE1Gzq8qS^SK`hMsCFKHF<_|}t_Cecdfs70)10#aB|F6D z3+&rtU7zuYe4>i1qkvw~MTrdXsA^DCOY`yGYfOAR)Ut}m*0+TOF%xn3w8;hpg&`&Q ztPG=^#!a3FB>GuKuo!aFl)x_&F`_>$?r@derAP)wC_t55P8Q@%W%LW_&(h{J>G~QS z{UC9r0_T9EpixDYgY)EsdsQ%TpB$8@eo%Ya{@(2_HwXqhb z{(bLp*+PKH9z`u{(&5x%FYZvH7fDd74f0MhVAQAe?Bc)+ExbU6?WH8LwaYIV;d&w+ z$K3r314oOnVPIi8FY* zp(QC3s_*f(?HrvCG;0YqYFjC(YVa*!vd^t&bXuxbER{KoH{IJ27GH>6%qS>naz=$4 zeA<`Q(OMYGF|Y8<0?oy%iSWZd_(cNNC(jjT^5*6jNAo1ts>&4mTB`?a^g4h(Y{~)N zz6?3iE*}+{I3v@(B)BH$_uVY+Dts|2V*YT^z1Ib&p+eHTr%ot$up)S&i=#of1bXA* zrJi#CAY-6*!C8e7WB>t*Hgjoop*G&wDVPK(Ofl0mWq<@k#GG6WR*AnRGl55LmEoh- zCN`gu$+iqz@7;S|p(OxRXE#y!n$luPKNwQxCvfkl0JFk?@X zZnKSLKn9TNtm<5`Ul_T$Bz`6xhPW*+J_a__Fpp8T9byl_Qq+r$(@I>Xetq0nxlKy2 z4g~UI6r}<8aEh!i(rYm_PmBQJ4n7&$P8T(egl^;OMU-9t3&Q9F@g4>Gvq)mYNbLPl zy?5ouK?_u;Q9NP+Y5~+oUAf`){{6492q~+$=d*m}*0-llyaL&Cb1CT7snV%zfE6(8 zX;xCQW5O*6raH1A9Kh#Bwp#+dxtL-B-h#X6EofBX!i|7cny1B!p_97ui*vrm=?sQXeJJiScevyGV z3m^k!wuT7xwu8*ddZ?u@2%F}B2jB{wY^K?aaP^L_Eh^uXsY;RY$QDpe9RTlh4e&0u zJmMf*hTkVyI#A2DFVAzov^^&ph~v1fpjcxm|8M*>yIpJZY%OQwmBRI_*;0^!?)zG z)S$ldBUgU#I?09oRR4;?tixWswn2^OoZq_h?JDWkR!&4|Eu6{CWDk`^$Bn>ZLvQf| zwU?%C%3h++*`(#8ydkrf+#`Wk@{74>HJ-XG1I---QYz}Gy=mZvh`^CYi(L#rs8>2_ zy^$g(wJ}{z_!KQqF7-MY{A9?2r@98{aHJ2yRP?o?F;Uoww!bQv)WNQ^=amgZ?N!+- zJ2LX?GwXl+T;thKb37^&cvB0NUv7(j55INeUE#x4 zS)L#d!e?SCH`ft1JJ=9)!IcAAcI+ea#D-q|bNKww#0XBBN0ith_a1$xMoO_tS%ltv zCSlAAuc9d;!426wF}8FqG*qwxS?TC;7?xom7ek-4@d8K;JiQNJ5Fya4oT)D`I=S$X zSE00v#4|y|sX5e9KhaW3cvG6iwNGEM8OAvGEx$F57-mc6f4vX|c$3j#rt3O39z#uK zYtn9=8b@-|T39lT1ae^!hJO0t!0BYKog4n%=CjL5KW>Sw|JNMk0it-_#taFJRjm&N z#jvl1G#WP&$aU$^gUmKWk{>SQ&mp?+3|T0uZaRE4dy$cEbngVVg`BxV?t zda&y^Z6w|ciEJJz7`wka_LD1=JOYU5NIIaA*5ly|$<(ey?KWA(kVVN<`$JTgVH~)v+G-_Sl4iE{ z#fA5WHu{h>ZgUX|Jx)@KSdtg~<=o6joVU}!`oyvI4On3!Doj>MxFPmAL)w7;b=$`z zbvYi~NUK}k8@4_;04bImFmHddblReD%><9)F$2$p$oqr_>y}%I1HbnoL_Vq4 z2l)Nc0=7WbtJcWlV27#MsJVqx>hnmlrBnC|#`t0>x(TP+b)HS09xjxitN^z-bEz8~ z$$jN0(?!h@q-6U%tiWu#4RDK;99O1_9M+fH>9pNZ7HqNy6JvwT)h^Pv1FR3D0poi4 zIu&%`>|6&~*qU=l@v=jw>g)IJ^~1AIihhkB^TVIbW@U#Uw#*{LIki zvawS2b-&eSxw|URX{G*^UDHwT4q=YqD+(u0Mh&J`$x{EtphfUy+(o9wcPj)}q*dgT z`5^pqLD?FBB_IUvsjgo;(liQE6;v%hmAXA(qFKvAa=96{WbCe0QVUkx6{Jyk;cF^c zv67^^1btTZbu1`a7cndF^|`i~oZ* z;!~1ua@X&w#J@kX>R(CzD}}^w0>)oOj%+{X!9Rtp|GwsbFaQ0UBdfkO`ahEY{#C;I zPeXnH$p3zQF6TMy`|sal|NZ%U+8^nET>snLKhpnussHWsUnR=lh}W;(OV98-@SEWu zfZxAb0Q}jsM^{fvTU$#{Z{0?6kh0%lV1#0fX_`q-OHW%%OAACN1Baelufb{EU4-F2 z%-~@6;rI?5=^agI1f{fUj4-GOo&0gGSFWr({48N_D-5HAGG-TNPt;we{7BSfW5i&@ z8!#~9u(3g{Q%_T3A)#|)?!}}%)P1mod+&zCs#`dug2T&>Pc63|drL)yOT1^7iZabO z7R@$pn#2j{J@qVp=eJvuQ%x?)x-}IK?hk4_wr}ny>&ebvVk{JjHmpteP;PFg4Aj3n zzBpI2w<+8;Fv~Y9G|S((a?eVv(l)ps^oz%BD;k@da6q-ORVwdB?a3h#@@AAudx;t|O8-@uoL*9DQM_ToRB`)Q?X->VSblW#qKf*Wz z7oL*?+XAK^veFi#9o_cMH{r23U5uWSBqpP>Z25nByYg@-*EcL>iLr*kv>;h3%V02; zG`2*@zVBPM>>>Md=*T{@j(rIgp_DXa&rX(X$(DV|PQq`DBXp>9et(>QzM0GSUDtS@ z_j~T=e&6T0pSLL{gY|W0EcVjl2X>?6guuX)NG6PyxxmV6f!1p!D}N~4j?Q51Czy8gaX)0Da^mW8;-Uvqc09k9?Cby}1PY8}0S z@xA;1461)l)p4L?L;KmG{VI9%PyWc&9rRc9o&A*Eu_OPF6+7q|+kMS{QtTX7>g>hn z--V`KGyj8e?iWP;Ua5mN_TQB{Xumy#u;`|_KNo^??Xbw>J^4@}_`w-FjIc^_rBcFj zWY=Urd)4{N+4{4eOR>iF$4jY#Vba!Yc`-$VUxyKVJ3$~_el8&6I-R;yGA2nXbC0XS z?G|D#btwe|Xca5|i7!{5UDN8PMYl2A9IQfuNFywuid~g(b|_m7aEMd48$)+KMrrsm zU3@0qhGLh_qwEE(auE}{@{eOp^o(5&8Mk_jbRqy}E?#dc58bp_!~nC#FDewGA~GAh&V8{kV&5|<@N;ISL_ zHGv@x{I^$NIn*LIeKNH|@ZIQTE`4~GzcKRZg_8*@3?#^!twYfI)`Yh*JS|kI?{mc& zX76m_W-hjT2a7`0Movw|6MsfQ`kp2O$4M){OXBBFNifF?HgtnpLPkD=;Eb*c-gUr~Bk!x9H7(@yzt_ad{`GAK@ISJjjm z_NQ+~8+ibATttb<9a+K&u|H;Vg)eaCZ$;b?w)#tNDGgC`Q&P+=c4gtaXegFKLwg>? z$Frmue>ZkW4evEhCrGYIT_c-TN?>eW+YpeKIk|!L$kJiuD68)A>YWNv&i&OEN|SRG zq#X<1GQuzsse>AS-d}?^T5q@0Tbc*8g!>J8qaOJsdhgx;N9c`4g~K?p#{_-_X9uz1 zC-gpc=>Ii(@5ZGa2>T1Y_xgA5eI7>fqi6VV(Ao)RKco1uM6Tg3;>#j2& zo}Hs=t{}hWWB(k*&BQfspv# z-i@&0*OI0L} ziRIk{1LxFx$xDg-ee%oNUsmLeibgxmgCh$*te1YvXjbF3rzq%W95Ni?q)&oFT5u*o z+w-9I?E6?om@^Ym*R6`w6^U39I-vMM?q2-HgKH3#jc)qTSPZ0x1vRovhd6UpZ7`y* zxXy!W*6+=BNL=S3W$VoyoUUvhP!KUluZ8p+*||JcIxe;Zyz(=4 z;rXwW1hfSlnqNk;Pj!^73pphgA91ub2l^HGi*<4x5EP)+@%zBF7Y-o5ZkceXM(;3x zhilNDl60xn^H43sv9^G6Ud@+7i1e2PfcT={VNYzhj}|PwEOsE{7$*uYtN~mLH9!oP zQ|P?|hi02umyIH?yo$diuRh=&&na_m{Q!Rl;<(CTBz^9t#i1Vj>NayB)&1rKkTGqC zzYnz3+vPGKV@|_>YhBP*5$zD~O=wA{@9n6P`=a@+gNQ&eZmtwF8F>~i?QA89*~AhB zpI1VtW0+8N2r+gxbBjT}*VX|>K;v2kZaHrY63jt6HRg<<%VUIM1J;NmLIB!0NAP#Z z(K`^wh5#{{o3awO5Ab*BuR{Qu$U#wOKL6(-;BVz!kUehke};f#hyEXj0Q8g{BJexV zzk3M7L9IQQ_aJFHZpCsG_#Zpce*^w#bN`*fqh0qP_=8cayM1Tg{WoRx%@ph{(NXG$ zckj;U4(iL${I%&OzO&gy!wKdVuD>fw{1^c zO;u=4te9=oArhRUz?k_;V?Pj|l`)!_KDOI@ImvDoyT|jePh> zH4W`mr&rVN5P^PKQcMTuq81P5?@TY8CAO9YthlS@El6KmNa_|aw>D<@^2U*lSu~Y3 zt(={=Xx3vRqfOu|zxu=|_)2}N=as2eZ~kXC12WfKtgFlozgAfR1|Eh`mH`P(2g+$r zv7V(veVo+fHKawz)HJ5B3KA6{Y-O7~Ws3dP#?u+cbnBx@!g{^A=^Qk=Y=y_`ia;j| zu4fy1;j_mO8%+jXTwhc+MdDo`> z>urO)+%e$QxxC_j5gX@K`4N|%;SNWk{`YgarOp0)`11?$v6e6fA8UiqMw%YV5svp3 zfCVZ;9&8)zq97Qp&-d!2XxLkp_u~LOkPo}h&__>;HM-g=1{D#k+9?J{5rWfknuHK~ zGh6=l&|C1SWIw~WKB9zDiJ=xz7f4!{s0(>oQrw+fKVRt=Dk3QiJx^$37<#01MrBjz zsmxMJ_>@7L>40I=Nb|)!l^U}}!l3+kI6`SLa}S9SJN z?i+$B)h}9G4Q^}3(;IPm(Vbewd8In%PZY^I>U?fnCQyHg%m8I2<$ceYSFgv(vJDNu z&JqqaJDGJkbn-+NX{Z?n^Pp^&yX1nx{Y27@h!11m1x;q5QqAkmO$~N335#u+>%;zpf6>=J;G7G}!L_I#w!9RI&N+?&RQf73T+0iIFg7v&CoJpYOPBnZD0? zlT{2_VOHMQ!cC|6nrKat_x_s)M!c>u?or`uk07G_AByt+JwZQ8F8(uisLC4|A4Cow zR3p6|)Hn(r&>YhAz7a|{w=4NaacVFP>NKET&MI$ZWlzHa+260->8XPH!;ifoR8JKn zJxe?%1WTKggpwRt^*nN}-lZ)+DsryPlwR(D0mSV@R)>0LSmL7qeDzva`fJH&?410{mu(ej`3uOb*k}|a5r1AVY&BUK zfzE;cu(LTYKJ2QgEB%#HsnqcKt;h`op&rYdmZ0-XDb29~g!d@;8CfgEUQ-&dQ$(pM zR1_=r!67%-swRj#Q}92H!`S>}o;K=_>2-8|ih8N>fZuR4aF&Hl+{Q>Zi>=0`#-19N{)}}u5Gku_m3Z5nB?VWyIkTN(ZDsY-R&mRKN%s2=-?OjW1L7f zVS8n75_nCk$%7>1bo7IpolA|+7vrWk=r>L-=mnfry>h_{E_?aQz|F@dst-}-WmE*g zEHPg~+wZ0q3KM?HD3qO-V2OELd1>L26}V30?U1oH5!{rfO=dL5buscOfq;Pq@d&5aKoBs8{<XN>wOs==t^4PRb}txz~MS%#)s_62I$^o6#CM!EF)R zlQdfs$umS=B+F^B%2?+!W$pizUdLHW88R;>zD}2F3^mrxcnMj0dU}&&`$R)T8}je& aXJ@ZxYwu)>@+&A9#pUoWT@sTO$NL{da>MEX diff --git a/lib/openzeppelin-contracts/certora/reports/2022-03.pdf b/lib/openzeppelin-contracts/certora/reports/2022-03.pdf deleted file mode 100644 index b6ff81d1812c808e2f683c1e5fe10abf71ba5438..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 199401 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

E02esqZ$^2gTs{2 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 diff --git a/lib/openzeppelin-contracts/certora/reports/2022-05.pdf b/lib/openzeppelin-contracts/certora/reports/2022-05.pdf deleted file mode 100644 index f24a44910c4fba449300987456b5f440e7f99511..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 132223 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%0D7|ieYKPVYBX59b!U}f9eB5UvK%HwkWL{dR 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 UVZ$VVhf9Eu51oMlq$-2{KaJIBBLDyZ diff --git a/lib/openzeppelin-contracts/certora/run.js b/lib/openzeppelin-contracts/certora/run.js deleted file mode 100755 index 7b65534..0000000 --- a/lib/openzeppelin-contracts/certora/run.js +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env node - -// USAGE: -// node certora/run.js [[CONTRACT_NAME:]SPEC_NAME]* [--all] [--options OPTIONS...] [--specs PATH] -// EXAMPLES: -// node certora/run.js --all -// node certora/run.js AccessControl -// node certora/run.js AccessControlHarness:AccessControl - -const proc = require('child_process'); -const { PassThrough } = require('stream'); -const events = require('events'); - -const argv = require('yargs') - .env('') - .options({ - all: { - alias: 'a', - type: 'boolean', - }, - spec: { - alias: 's', - type: 'string', - default: __dirname + '/specs.json', - }, - parallel: { - alias: 'p', - type: 'number', - default: 4, - }, - verbose: { - alias: 'v', - type: 'count', - default: 0, - }, - options: { - alias: 'o', - type: 'array', - default: [], - }, - }).argv; - -function match(entry, request) { - const [reqSpec, reqContract] = request.split(':').reverse(); - return entry.spec == reqSpec && (!reqContract || entry.contract == reqContract); -} - -const specs = require(argv.spec).filter(s => argv.all || argv._.some(r => match(s, r))); -const limit = require('p-limit')(argv.parallel); - -if (argv._.length == 0 && !argv.all) { - console.error(`Warning: No specs requested. Did you forgot to toggle '--all'?`); -} - -for (const r of argv._) { - if (!specs.some(s => match(s, r))) { - console.error(`Error: Requested spec '${r}' not found in ${argv.spec}`); - process.exitCode = 1; - } -} - -if (process.exitCode) { - process.exit(process.exitCode); -} - -for (const { spec, contract, files, options = [] } of specs) { - limit( - runCertora, - spec, - contract, - files, - [...options, ...argv.options].flatMap(opt => opt.split(' ')), - ); -} - -// Run certora, aggregate the output and print it at the end -async function runCertora(spec, contract, files, options = []) { - const args = [...files, '--verify', `${contract}:certora/specs/${spec}.spec`, ...options]; - if (argv.verbose) { - console.log('Running:', args.join(' ')); - } - const child = proc.spawn('certoraRun', args); - - const stream = new PassThrough(); - const output = collect(stream); - - child.stdout.pipe(stream, { end: false }); - child.stderr.pipe(stream, { end: false }); - - // as soon as we have a job id, print the output link - stream.on('data', function logStatusUrl(data) { - const { '-DjobId': jobId, '-DuserId': userId } = Object.fromEntries( - data - .toString('utf8') - .match(/-D\S+=\S+/g) - ?.map(s => s.split('=')) || [], - ); - - if (jobId && userId) { - console.error(`[${spec}] https://prover.certora.com/output/${userId}/${jobId}/`); - stream.off('data', logStatusUrl); - } - }); - - // wait for process end - const [code, signal] = await events.once(child, 'exit'); - - // error - if (code || signal) { - console.error(`[${spec}] Exited with code ${code || signal}`); - process.exitCode = 1; - } - - // get all output - stream.end(); - - // write results in markdown format - writeEntry(spec, contract, code || signal, (await output).match(/https:\/\/prover.certora.com\/output\/\S*/)?.[0]); - - // write all details - console.error(`+ certoraRun ${args.join(' ')}\n` + (await output)); -} - -// Collects stream data into a string -async function collect(stream) { - const buffers = []; - for await (const data of stream) { - const buf = Buffer.isBuffer(data) ? data : Buffer.from(data); - buffers.push(buf); - } - return Buffer.concat(buffers).toString('utf8'); -} - -// Formatting -let hasHeader = false; - -function formatRow(...array) { - return ['', ...array, ''].join(' | '); -} - -function writeHeader() { - console.log(formatRow('spec', 'contract', 'result', 'status', 'output')); - console.log(formatRow('-', '-', '-', '-', '-')); -} - -function writeEntry(spec, contract, success, url) { - if (!hasHeader) { - hasHeader = true; - writeHeader(); - } - console.log( - formatRow( - spec, - contract, - success ? ':x:' : ':heavy_check_mark:', - url ? `[link](${url?.replace('/output/', '/jobStatus/')})` : 'error', - url ? `[link](${url})` : 'error', - ), - ); -} diff --git a/lib/openzeppelin-contracts/certora/specs.json b/lib/openzeppelin-contracts/certora/specs.json deleted file mode 100644 index a894190..0000000 --- a/lib/openzeppelin-contracts/certora/specs.json +++ /dev/null @@ -1,110 +0,0 @@ -[ - { - "spec": "Pausable", - "contract": "PausableHarness", - "files": ["certora/harnesses/PausableHarness.sol"] - }, - { - "spec": "AccessControl", - "contract": "AccessControlHarness", - "files": ["certora/harnesses/AccessControlHarness.sol"] - }, - { - "spec": "AccessControlDefaultAdminRules", - "contract": "AccessControlDefaultAdminRulesHarness", - "files": ["certora/harnesses/AccessControlDefaultAdminRulesHarness.sol"] - }, - { - "spec": "AccessManager", - "contract": "AccessManagerHarness", - "files": ["certora/harnesses/AccessManagerHarness.sol"], - "options": ["--optimistic_hashing", "--optimistic_loop"] - }, - { - "spec": "AccessManaged", - "contract": "AccessManagedHarness", - "files": [ - "certora/harnesses/AccessManagedHarness.sol", - "certora/harnesses/AccessManagerHarness.sol" - ], - "options": [ - "--optimistic_hashing", - "--optimistic_loop", - "--link AccessManagedHarness:_authority=AccessManagerHarness" - ] - }, - { - "spec": "DoubleEndedQueue", - "contract": "DoubleEndedQueueHarness", - "files": ["certora/harnesses/DoubleEndedQueueHarness.sol"] - }, - { - "spec": "Ownable", - "contract": "OwnableHarness", - "files": ["certora/harnesses/OwnableHarness.sol"] - }, - { - "spec": "Ownable2Step", - "contract": "Ownable2StepHarness", - "files": ["certora/harnesses/Ownable2StepHarness.sol"] - }, - { - "spec": "ERC20", - "contract": "ERC20PermitHarness", - "files": ["certora/harnesses/ERC20PermitHarness.sol"], - "options": ["--optimistic_loop"] - }, - { - "spec": "ERC20FlashMint", - "contract": "ERC20FlashMintHarness", - "files": [ - "certora/harnesses/ERC20FlashMintHarness.sol", - "certora/harnesses/ERC3156FlashBorrowerHarness.sol" - ], - "options": ["--optimistic_loop"] - }, - { - "spec": "ERC20Wrapper", - "contract": "ERC20WrapperHarness", - "files": [ - "certora/harnesses/ERC20PermitHarness.sol", - "certora/harnesses/ERC20WrapperHarness.sol" - ], - "options": [ - "--link ERC20WrapperHarness:_underlying=ERC20PermitHarness", - "--optimistic_loop" - ] - }, - { - "spec": "ERC721", - "contract": "ERC721Harness", - "files": ["certora/harnesses/ERC721Harness.sol", "certora/harnesses/ERC721ReceiverHarness.sol"], - "options": ["--optimistic_loop"] - }, - { - "spec": "Initializable", - "contract": "InitializableHarness", - "files": ["certora/harnesses/InitializableHarness.sol"] - }, - { - "spec": "EnumerableSet", - "contract": "EnumerableSetHarness", - "files": ["certora/harnesses/EnumerableSetHarness.sol"] - }, - { - "spec": "EnumerableMap", - "contract": "EnumerableMapHarness", - "files": ["certora/harnesses/EnumerableMapHarness.sol"] - }, - { - "spec": "TimelockController", - "contract": "TimelockControllerHarness", - "files": ["certora/harnesses/TimelockControllerHarness.sol"], - "options": ["--optimistic_hashing", "--optimistic_loop"] - }, - { - "spec": "Nonces", - "contract": "NoncesHarness", - "files": ["certora/harnesses/NoncesHarness.sol"] - } -] diff --git a/lib/openzeppelin-contracts/certora/specs/AccessControl.spec b/lib/openzeppelin-contracts/certora/specs/AccessControl.spec deleted file mode 100644 index 70b0672..0000000 --- a/lib/openzeppelin-contracts/certora/specs/AccessControl.spec +++ /dev/null @@ -1,119 +0,0 @@ -import "helpers/helpers.spec"; -import "methods/IAccessControl.spec"; - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Identify entrypoints: only grantRole, revokeRole and renounceRole can alter permissions │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule onlyGrantCanGrant(env e, method f, bytes32 role, address account) { - calldataarg args; - - bool hasRoleBefore = hasRole(role, account); - f(e, args); - bool hasRoleAfter = hasRole(role, account); - - assert ( - !hasRoleBefore && - hasRoleAfter - ) => ( - f.selector == sig:grantRole(bytes32, address).selector - ); - - assert ( - hasRoleBefore && - !hasRoleAfter - ) => ( - f.selector == sig:revokeRole(bytes32, address).selector || - f.selector == sig:renounceRole(bytes32, address).selector - ); -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Function correctness: grantRole only affects the specified user/role combo │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule grantRoleEffect(env e, bytes32 role) { - require nonpayable(e); - - bytes32 otherRole; - address account; - address otherAccount; - - bool isCallerAdmin = hasRole(getRoleAdmin(role), e.msg.sender); - bool hasOtherRoleBefore = hasRole(otherRole, otherAccount); - - grantRole@withrevert(e, role, account); - bool success = !lastReverted; - - bool hasOtherRoleAfter = hasRole(otherRole, otherAccount); - - // liveness - assert success <=> isCallerAdmin; - - // effect - assert success => hasRole(role, account); - - // no side effect - assert hasOtherRoleBefore != hasOtherRoleAfter => (role == otherRole && account == otherAccount); -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Function correctness: revokeRole only affects the specified user/role combo │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule revokeRoleEffect(env e, bytes32 role) { - require nonpayable(e); - - bytes32 otherRole; - address account; - address otherAccount; - - bool isCallerAdmin = hasRole(getRoleAdmin(role), e.msg.sender); - bool hasOtherRoleBefore = hasRole(otherRole, otherAccount); - - revokeRole@withrevert(e, role, account); - bool success = !lastReverted; - - bool hasOtherRoleAfter = hasRole(otherRole, otherAccount); - - // liveness - assert success <=> isCallerAdmin; - - // effect - assert success => !hasRole(role, account); - - // no side effect - assert hasOtherRoleBefore != hasOtherRoleAfter => (role == otherRole && account == otherAccount); -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Function correctness: renounceRole only affects the specified user/role combo │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule renounceRoleEffect(env e, bytes32 role) { - require nonpayable(e); - - bytes32 otherRole; - address account; - address otherAccount; - - bool hasOtherRoleBefore = hasRole(otherRole, otherAccount); - - renounceRole@withrevert(e, role, account); - bool success = !lastReverted; - - bool hasOtherRoleAfter = hasRole(otherRole, otherAccount); - - // liveness - assert success <=> account == e.msg.sender; - - // effect - assert success => !hasRole(role, account); - - // no side effect - assert hasOtherRoleBefore != hasOtherRoleAfter => (role == otherRole && account == otherAccount); -} diff --git a/lib/openzeppelin-contracts/certora/specs/AccessControlDefaultAdminRules.spec b/lib/openzeppelin-contracts/certora/specs/AccessControlDefaultAdminRules.spec deleted file mode 100644 index 2f5bb9d..0000000 --- a/lib/openzeppelin-contracts/certora/specs/AccessControlDefaultAdminRules.spec +++ /dev/null @@ -1,464 +0,0 @@ -import "helpers/helpers.spec"; -import "methods/IAccessControlDefaultAdminRules.spec"; -import "methods/IAccessControl.spec"; -import "AccessControl.spec"; - -use rule onlyGrantCanGrant filtered { - f -> f.selector != sig:acceptDefaultAdminTransfer().selector -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Definitions │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -definition timeSanity(env e) returns bool = - e.block.timestamp > 0 && e.block.timestamp + defaultAdminDelay(e) < max_uint48; - -definition delayChangeWaitSanity(env e, uint48 newDelay) returns bool = - e.block.timestamp + delayChangeWait_(e, newDelay) < max_uint48; - -definition isSet(uint48 schedule) returns bool = - schedule != 0; - -definition hasPassed(env e, uint48 schedule) returns bool = - assert_uint256(schedule) < e.block.timestamp; - -definition increasingDelaySchedule(env e, uint48 newDelay) returns mathint = - e.block.timestamp + min(newDelay, defaultAdminDelayIncreaseWait()); - -definition decreasingDelaySchedule(env e, uint48 newDelay) returns mathint = - e.block.timestamp + defaultAdminDelay(e) - newDelay; - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariant: defaultAdmin holds the DEFAULT_ADMIN_ROLE │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant defaultAdminConsistency(address account) - (account == defaultAdmin() && account != 0) <=> hasRole(DEFAULT_ADMIN_ROLE(), account) - { - preserved with (env e) { - require nonzerosender(e); - } - } - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariant: Only one account holds the DEFAULT_ADMIN_ROLE │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant singleDefaultAdmin(address account, address another) - hasRole(DEFAULT_ADMIN_ROLE(), account) && hasRole(DEFAULT_ADMIN_ROLE(), another) => another == account - { - preserved { - requireInvariant defaultAdminConsistency(account); - requireInvariant defaultAdminConsistency(another); - } - } - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariant: DEFAULT_ADMIN_ROLE's admin is always DEFAULT_ADMIN_ROLE │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant defaultAdminRoleAdminConsistency() - getRoleAdmin(DEFAULT_ADMIN_ROLE()) == DEFAULT_ADMIN_ROLE(); - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariant: owner is the defaultAdmin │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant ownerConsistency() - defaultAdmin() == owner(); - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Function correctness: revokeRole only affects the specified user/role combo │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule revokeRoleEffect(env e, bytes32 role) { - require nonpayable(e); - - bytes32 otherRole; - address account; - address otherAccount; - - bool isCallerAdmin = hasRole(getRoleAdmin(role), e.msg.sender); - bool hasOtherRoleBefore = hasRole(otherRole, otherAccount); - - revokeRole@withrevert(e, role, account); - bool success = !lastReverted; - - bool hasOtherRoleAfter = hasRole(otherRole, otherAccount); - - // liveness - assert success <=> isCallerAdmin && role != DEFAULT_ADMIN_ROLE(), - "roles can only be revoked by their owner except for the default admin role"; - - // effect - assert success => !hasRole(role, account), - "role is revoked"; - - // no side effect - assert hasOtherRoleBefore != hasOtherRoleAfter => (role == otherRole && account == otherAccount), - "no other role is affected"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Function correctness: renounceRole only affects the specified user/role combo │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule renounceRoleEffect(env e, bytes32 role) { - require nonpayable(e); - - bytes32 otherRole; - address account; - address otherAccount; - - bool hasOtherRoleBefore = hasRole(otherRole, otherAccount); - address adminBefore = defaultAdmin(); - address pendingAdminBefore = pendingDefaultAdmin_(); - uint48 scheduleBefore = pendingDefaultAdminSchedule_(); - - renounceRole@withrevert(e, role, account); - bool success = !lastReverted; - - bool hasOtherRoleAfter = hasRole(otherRole, otherAccount); - address adminAfter = defaultAdmin(); - address pendingAdminAfter = pendingDefaultAdmin_(); - uint48 scheduleAfter = pendingDefaultAdminSchedule_(); - - // liveness - assert success <=> ( - account == e.msg.sender && - ( - role != DEFAULT_ADMIN_ROLE() || - account != adminBefore || - ( - pendingAdminBefore == 0 && - isSet(scheduleBefore) && - hasPassed(e, scheduleBefore) - ) - ) - ), - "an account only can renounce by itself with a delay for the default admin role"; - - // effect - assert success => !hasRole(role, account), - "role is renounced"; - - assert success => ( - ( - role == DEFAULT_ADMIN_ROLE() && - account == adminBefore - ) ? ( - adminAfter == 0 && - pendingAdminAfter == 0 && - scheduleAfter == 0 - ) : ( - adminAfter == adminBefore && - pendingAdminAfter == pendingAdminBefore && - scheduleAfter == scheduleBefore - ) - ), - "renouncing default admin role cleans state iff called by previous admin"; - - // no side effect - assert hasOtherRoleBefore != hasOtherRoleAfter => ( - role == otherRole && - account == otherAccount - ), - "no other role is affected"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: defaultAdmin is only affected by accepting an admin transfer or renoucing │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule noDefaultAdminChange(env e, method f, calldataarg args) { - address adminBefore = defaultAdmin(); - f(e, args); - address adminAfter = defaultAdmin(); - - assert adminBefore != adminAfter => ( - f.selector == sig:acceptDefaultAdminTransfer().selector || - f.selector == sig:renounceRole(bytes32,address).selector - ), - "default admin is only affected by accepting an admin transfer or renoucing"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: pendingDefaultAdmin is only affected by beginning, completing (accept or renounce), or canceling an admin │ -│ transfer │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule noPendingDefaultAdminChange(env e, method f, calldataarg args) { - address pendingAdminBefore = pendingDefaultAdmin_(); - uint48 scheduleBefore = pendingDefaultAdminSchedule_(); - f(e, args); - address pendingAdminAfter = pendingDefaultAdmin_(); - uint48 scheduleAfter = pendingDefaultAdminSchedule_(); - - assert ( - pendingAdminBefore != pendingAdminAfter || - scheduleBefore != scheduleAfter - ) => ( - f.selector == sig:beginDefaultAdminTransfer(address).selector || - f.selector == sig:acceptDefaultAdminTransfer().selector || - f.selector == sig:cancelDefaultAdminTransfer().selector || - f.selector == sig:renounceRole(bytes32,address).selector - ), - "pending admin and its schedule is only affected by beginning, completing, or cancelling an admin transfer"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: defaultAdminDelay can't be changed atomically by any function │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule noDefaultAdminDelayChange(env e, method f, calldataarg args) { - uint48 delayBefore = defaultAdminDelay(e); - f(e, args); - uint48 delayAfter = defaultAdminDelay(e); - - assert delayBefore == delayAfter, - "delay can't be changed atomically by any function"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: pendingDefaultAdminDelay is only affected by changeDefaultAdminDelay or rollbackDefaultAdminDelay │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule noPendingDefaultAdminDelayChange(env e, method f, calldataarg args) { - uint48 pendingDelayBefore = pendingDelay_(e); - f(e, args); - uint48 pendingDelayAfter = pendingDelay_(e); - - assert pendingDelayBefore != pendingDelayAfter => ( - f.selector == sig:changeDefaultAdminDelay(uint48).selector || - f.selector == sig:rollbackDefaultAdminDelay().selector - ), - "pending delay is only affected by changeDefaultAdminDelay or rollbackDefaultAdminDelay"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: defaultAdminDelayIncreaseWait can't be changed atomically by any function │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule noDefaultAdminDelayIncreaseWaitChange(env e, method f, calldataarg args) { - uint48 delayIncreaseWaitBefore = defaultAdminDelayIncreaseWait(); - f(e, args); - uint48 delayIncreaseWaitAfter = defaultAdminDelayIncreaseWait(); - - assert delayIncreaseWaitBefore == delayIncreaseWaitAfter, - "delay increase wait can't be changed atomically by any function"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Function correctness: beginDefaultAdminTransfer sets a pending default admin and its schedule │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule beginDefaultAdminTransfer(env e, address newAdmin) { - require timeSanity(e); - require nonpayable(e); - require nonzerosender(e); - requireInvariant defaultAdminConsistency(e.msg.sender); - - beginDefaultAdminTransfer@withrevert(e, newAdmin); - bool success = !lastReverted; - - // liveness - assert success <=> e.msg.sender == defaultAdmin(), - "only the current default admin can begin a transfer"; - - // effect - assert success => pendingDefaultAdmin_() == newAdmin, - "pending default admin is set"; - assert success => to_mathint(pendingDefaultAdminSchedule_()) == e.block.timestamp + defaultAdminDelay(e), - "pending default admin delay is set"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: A default admin can't change in less than the applied schedule │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule pendingDefaultAdminDelayEnforced(env e1, env e2, method f, calldataarg args, address newAdmin) { - require e1.block.timestamp <= e2.block.timestamp; - - uint48 delayBefore = defaultAdminDelay(e1); - address adminBefore = defaultAdmin(); - - // There might be a better way to generalize this without requiring `beginDefaultAdminTransfer`, but currently - // it's the only way in which we can attest that only `delayBefore` has passed before a change. - beginDefaultAdminTransfer(e1, newAdmin); - f(e2, args); - - address adminAfter = defaultAdmin(); - - // change can only happen towards the newAdmin, with the delay - assert adminAfter != adminBefore => ( - adminAfter == newAdmin && - to_mathint(e2.block.timestamp) >= e1.block.timestamp + delayBefore - ), - "The admin can only change after the enforced delay and to the previously scheduled new admin"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Function correctness: acceptDefaultAdminTransfer updates defaultAdmin resetting the pending admin and its schedule │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule acceptDefaultAdminTransfer(env e) { - require nonpayable(e); - - address pendingAdminBefore = pendingDefaultAdmin_(); - uint48 scheduleBefore = pendingDefaultAdminSchedule_(); - - acceptDefaultAdminTransfer@withrevert(e); - bool success = !lastReverted; - - // liveness - assert success <=> ( - e.msg.sender == pendingAdminBefore && - isSet(scheduleBefore) && - hasPassed(e, scheduleBefore) - ), - "only the pending default admin can accept the role after the schedule has been set and passed"; - - // effect - assert success => defaultAdmin() == pendingAdminBefore, - "Default admin is set to the previous pending default admin"; - assert success => pendingDefaultAdmin_() == 0, - "Pending default admin is reset"; - assert success => pendingDefaultAdminSchedule_() == 0, - "Pending default admin delay is reset"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Function correctness: cancelDefaultAdminTransfer resets pending default admin and its schedule │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule cancelDefaultAdminTransfer(env e) { - require nonpayable(e); - require nonzerosender(e); - requireInvariant defaultAdminConsistency(e.msg.sender); - - cancelDefaultAdminTransfer@withrevert(e); - bool success = !lastReverted; - - // liveness - assert success <=> e.msg.sender == defaultAdmin(), - "only the current default admin can cancel a transfer"; - - // effect - assert success => pendingDefaultAdmin_() == 0, - "Pending default admin is reset"; - assert success => pendingDefaultAdminSchedule_() == 0, - "Pending default admin delay is reset"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Function correctness: changeDefaultAdminDelay sets a pending default admin delay and its schedule │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule changeDefaultAdminDelay(env e, uint48 newDelay) { - require timeSanity(e); - require nonpayable(e); - require nonzerosender(e); - require delayChangeWaitSanity(e, newDelay); - requireInvariant defaultAdminConsistency(e.msg.sender); - - uint48 delayBefore = defaultAdminDelay(e); - - changeDefaultAdminDelay@withrevert(e, newDelay); - bool success = !lastReverted; - - // liveness - assert success <=> e.msg.sender == defaultAdmin(), - "only the current default admin can begin a delay change"; - - // effect - assert success => pendingDelay_(e) == newDelay, - "pending delay is set"; - - assert success => ( - assert_uint256(pendingDelaySchedule_(e)) > e.block.timestamp || - delayBefore == newDelay || // Interpreted as decreasing, x - x = 0 - defaultAdminDelayIncreaseWait() == 0 - ), - "pending delay schedule is set in the future unless accepted edge cases"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: A delay can't change in less than the applied schedule │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule pendingDelayWaitEnforced(env e1, env e2, method f, calldataarg args, uint48 newDelay) { - require e1.block.timestamp <= e2.block.timestamp; - - uint48 delayBefore = defaultAdminDelay(e1); - - changeDefaultAdminDelay(e1, newDelay); - f(e2, args); - - uint48 delayAfter = defaultAdminDelay(e2); - - mathint delayWait = newDelay > delayBefore ? increasingDelaySchedule(e1, newDelay) : decreasingDelaySchedule(e1, newDelay); - - assert delayAfter != delayBefore => ( - delayAfter == newDelay && - to_mathint(e2.block.timestamp) >= delayWait - ), - "A delay can only change after the applied schedule"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: pending delay wait is set depending on increasing or decreasing the delay │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule pendingDelayWait(env e, uint48 newDelay) { - uint48 oldDelay = defaultAdminDelay(e); - changeDefaultAdminDelay(e, newDelay); - - assert newDelay > oldDelay => to_mathint(pendingDelaySchedule_(e)) == increasingDelaySchedule(e, newDelay), - "Delay wait is the minimum between the new delay and a threshold when the delay is increased"; - assert newDelay <= oldDelay => to_mathint(pendingDelaySchedule_(e)) == decreasingDelaySchedule(e, newDelay), - "Delay wait is the difference between the current and the new delay when the delay is decreased"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Function correctness: rollbackDefaultAdminDelay resets the delay and its schedule │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule rollbackDefaultAdminDelay(env e) { - require nonpayable(e); - require nonzerosender(e); - requireInvariant defaultAdminConsistency(e.msg.sender); - - rollbackDefaultAdminDelay@withrevert(e); - bool success = !lastReverted; - - // liveness - assert success <=> e.msg.sender == defaultAdmin(), - "only the current default admin can rollback a delay change"; - - // effect - assert success => pendingDelay_(e) == 0, - "Pending default admin is reset"; - assert success => pendingDelaySchedule_(e) == 0, - "Pending default admin delay is reset"; -} diff --git a/lib/openzeppelin-contracts/certora/specs/AccessManaged.spec b/lib/openzeppelin-contracts/certora/specs/AccessManaged.spec deleted file mode 100644 index adcb859..0000000 --- a/lib/openzeppelin-contracts/certora/specs/AccessManaged.spec +++ /dev/null @@ -1,34 +0,0 @@ -import "helpers/helpers.spec"; -import "methods/IAccessManaged.spec"; - -methods { - // FV - function someFunction() external; - function authority_canCall_immediate(address) external returns (bool); - function authority_canCall_delay(address) external returns (uint32); - function authority_getSchedule(address) external returns (uint48); -} - -invariant isConsumingScheduledOpClean() - isConsumingScheduledOp() == to_bytes4(0); - -rule callRestrictedFunction(env e) { - bool immediate = authority_canCall_immediate(e, e.msg.sender); - uint32 delay = authority_canCall_delay(e, e.msg.sender); - uint48 scheduleBefore = authority_getSchedule(e, e.msg.sender); - - someFunction@withrevert(e); - bool success = !lastReverted; - - uint48 scheduleAfter = authority_getSchedule(e, e.msg.sender); - - // can only call if immediate, or (with delay) by consuming a scheduled op - assert success => ( - immediate || - ( - delay > 0 && - isSetAndPast(e, scheduleBefore) && - scheduleAfter == 0 - ) - ); -} diff --git a/lib/openzeppelin-contracts/certora/specs/AccessManager.spec b/lib/openzeppelin-contracts/certora/specs/AccessManager.spec deleted file mode 100644 index cc4b013..0000000 --- a/lib/openzeppelin-contracts/certora/specs/AccessManager.spec +++ /dev/null @@ -1,826 +0,0 @@ -import "helpers/helpers.spec"; -import "methods/IAccessManager.spec"; - -methods { - // FV - function canCall_immediate(address,address,bytes4) external returns (bool); - function canCall_delay(address,address,bytes4) external returns (uint32); - function canCallExtended(address,address,bytes) external returns (bool,uint32); - function canCallExtended_immediate(address,address,bytes) external returns (bool); - function canCallExtended_delay(address,address,bytes) external returns (uint32); - function getAdminRestrictions_restricted(bytes) external returns (bool); - function getAdminRestrictions_roleAdminId(bytes) external returns (uint64); - function getAdminRestrictions_executionDelay(bytes) external returns (uint32); - function hasRole_isMember(uint64,address) external returns (bool); - function hasRole_executionDelay(uint64,address) external returns (uint32); - function getAccess_since(uint64,address) external returns (uint48); - function getAccess_currentDelay(uint64,address) external returns (uint32); - function getAccess_pendingDelay(uint64,address) external returns (uint32); - function getAccess_effect(uint64,address) external returns (uint48); - function getTargetAdminDelay_after(address target) external returns (uint32); - function getTargetAdminDelay_effect(address target) external returns (uint48); - function getRoleGrantDelay_after(uint64 roleId) external returns (uint32); - function getRoleGrantDelay_effect(uint64 roleId) external returns (uint48); - function hashExecutionId(address,bytes4) external returns (bytes32) envfree; - function executionId() external returns (bytes32) envfree; - function getSelector(bytes) external returns (bytes4) envfree; - function getFirstArgumentAsAddress(bytes) external returns (address) envfree; - function getFirstArgumentAsUint64(bytes) external returns (uint64) envfree; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Helpers │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -definition isOnlyAuthorized(bytes4 selector) returns bool = - selector == to_bytes4(sig:labelRole(uint64,string).selector ) || - selector == to_bytes4(sig:setRoleAdmin(uint64,uint64).selector ) || - selector == to_bytes4(sig:setRoleGuardian(uint64,uint64).selector ) || - selector == to_bytes4(sig:setGrantDelay(uint64,uint32).selector ) || - selector == to_bytes4(sig:setTargetAdminDelay(address,uint32).selector ) || - selector == to_bytes4(sig:updateAuthority(address,address).selector ) || - selector == to_bytes4(sig:setTargetClosed(address,bool).selector ) || - selector == to_bytes4(sig:setTargetFunctionRole(address,bytes4[],uint64).selector) || - selector == to_bytes4(sig:grantRole(uint64,address,uint32).selector ) || - selector == to_bytes4(sig:revokeRole(uint64,address).selector ); - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariant: executionId must be clean when not in the middle of a call │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant cleanExecutionId() - executionId() == to_bytes32(0); - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariant: public role │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant publicRole(env e, address account) - hasRole_isMember(e, PUBLIC_ROLE(), account) && - hasRole_executionDelay(e, PUBLIC_ROLE(), account) == 0 && - getAccess_since(e, PUBLIC_ROLE(), account) == 0 && - getAccess_currentDelay(e, PUBLIC_ROLE(), account) == 0 && - getAccess_pendingDelay(e, PUBLIC_ROLE(), account) == 0 && - getAccess_effect(e, PUBLIC_ROLE(), account) == 0; - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariant: hasRole is consistent with getAccess │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant hasRoleGetAccessConsistency(env e, uint64 roleId, address account) - hasRole_isMember(e, roleId, account) == (roleId == PUBLIC_ROLE() || isSetAndPast(e, getAccess_since(e, roleId, account))) && - hasRole_executionDelay(e, roleId, account) == getAccess_currentDelay(e, roleId, account); - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Functions: canCall, canCallExtended, getAccess, hasRole, isTargetClosed and getTargetFunctionRole do NOT revert │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule noRevert(env e) { - require nonpayable(e); - require sanity(e); - - address caller; - address target; - bytes data; - bytes4 selector; - uint64 roleId; - - canCall@withrevert(e, caller, target, selector); - assert !lastReverted; - - // require data.length <= max_uint64; - // - // canCallExtended@withrevert(e, caller, target, data); - // assert !lastReverted; - - getAccess@withrevert(e, roleId, caller); - assert !lastReverted; - - hasRole@withrevert(e, roleId, caller); - assert !lastReverted; - - isTargetClosed@withrevert(target); - assert !lastReverted; - - getTargetFunctionRole@withrevert(target, selector); - assert !lastReverted; - - // Not covered: - // - getAdminRestrictions (_1, _2 & _3) - // - getSelector -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Functions: admin restrictions are correct │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule getAdminRestrictions(env e, bytes data) { - bool restricted = getAdminRestrictions_restricted(e, data); - uint64 roleId = getAdminRestrictions_roleAdminId(e, data); - uint32 delay = getAdminRestrictions_executionDelay(e, data); - bytes4 selector = getSelector(data); - - if (data.length < 4) { - assert restricted == false; - assert roleId == 0; - assert delay == 0; - } else { - assert restricted == - isOnlyAuthorized(selector); - - assert roleId == ( - (restricted && selector == to_bytes4(sig:grantRole(uint64,address,uint32).selector)) || - (restricted && selector == to_bytes4(sig:revokeRole(uint64,address).selector )) - ? getRoleAdmin(getFirstArgumentAsUint64(data)) - : ADMIN_ROLE() - ); - - assert delay == ( - (restricted && selector == to_bytes4(sig:updateAuthority(address,address).selector )) || - (restricted && selector == to_bytes4(sig:setTargetClosed(address,bool).selector )) || - (restricted && selector == to_bytes4(sig:setTargetFunctionRole(address,bytes4[],uint64).selector)) - ? getTargetAdminDelay(e, getFirstArgumentAsAddress(data)) - : 0 - ); - } -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Functions: canCall │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule canCall(env e) { - address caller; - address target; - bytes4 selector; - - // Get relevant values - bool immediate = canCall_immediate(e, caller, target, selector); - uint32 delay = canCall_delay(e, caller, target, selector); - bool closed = isTargetClosed(target); - uint64 roleId = getTargetFunctionRole(target, selector); - bool isMember = hasRole_isMember(e, roleId, caller); - uint32 currentDelay = hasRole_executionDelay(e, roleId, caller); - - // Can only execute without delay in specific cases: - // - target not closed - // - if self-execution: `executionId` must match - // - if third party execution: must be member with no delay - assert immediate <=> ( - !closed && - ( - (caller == currentContract && executionId() == hashExecutionId(target, selector)) - || - (caller != currentContract && isMember && currentDelay == 0) - ) - ); - - // Can only execute with delay in specific cases: - // - target not closed - // - third party execution - // - caller is a member and has an execution delay - assert delay > 0 <=> ( - !closed && - caller != currentContract && - isMember && - currentDelay > 0 - ); - - // If there is a delay, then it must be the caller's execution delay - assert delay > 0 => delay == currentDelay; - - // Immediate execute means no delayed execution - assert immediate => delay == 0; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Functions: canCallExtended │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule canCallExtended(env e) { - address caller; - address target; - bytes data; - bytes4 selector = getSelector(data); - - bool immediate = canCallExtended_immediate(e, caller, target, data); - uint32 delay = canCallExtended_delay(e, caller, target, data); - bool enabled = getAdminRestrictions_restricted(e, data); - uint64 roleId = getAdminRestrictions_roleAdminId(e, data); - uint32 operationDelay = getAdminRestrictions_executionDelay(e, data); - bool inRole = hasRole_isMember(e, roleId, caller); - uint32 executionDelay = hasRole_executionDelay(e, roleId, caller); - - if (target == currentContract) { - // Can only execute without delay in the specific cases: - // - caller is the AccessManager and the executionId is set - // or - // - data matches an admin restricted function - // - caller has the necessary role - // - operation delay is not set - // - execution delay is not set - assert immediate <=> ( - ( - caller == currentContract && - data.length >= 4 && - executionId() == hashExecutionId(target, selector) - ) || ( - caller != currentContract && - enabled && - inRole && - operationDelay == 0 && - executionDelay == 0 - ) - ); - - // Immediate execute means no delayed execution - // This is equivalent to "delay > 0 => !immediate" - assert immediate => delay == 0; - - // Can only execute with delay in specific cases: - // - caller is a third party - // - data matches an admin restricted function - // - caller has the necessary role - // -operation delay or execution delay is set - assert delay > 0 <=> ( - caller != currentContract && - enabled && - inRole && - (operationDelay > 0 || executionDelay > 0) - ); - - // If there is a delay, then it must be the maximum of caller's execution delay and the operation delay - assert delay > 0 => to_mathint(delay) == max(operationDelay, executionDelay); - } else if (data.length < 4) { - assert immediate == false; - assert delay == 0; - } else { - // results are equivalent when targeting third party contracts - assert immediate == canCall_immediate(e, caller, target, selector); - assert delay == canCall_delay(e, caller, target, selector); - } -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ State transitions: getAccess │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule getAccessChangeTime(uint64 roleId, address account) { - env e1; - env e2; - - // values before - mathint getAccess1Before = getAccess_since(e1, roleId, account); - mathint getAccess2Before = getAccess_currentDelay(e1, roleId, account); - mathint getAccess3Before = getAccess_pendingDelay(e1, roleId, account); - mathint getAccess4Before = getAccess_effect(e1, roleId, account); - - // time pass: e1 → e2 - require clock(e1) <= clock(e2); - - // values after - mathint getAccess1After = getAccess_since(e2, roleId, account); - mathint getAccess2After = getAccess_currentDelay(e2, roleId, account); - mathint getAccess3After = getAccess_pendingDelay(e2, roleId, account); - mathint getAccess4After = getAccess_effect(e2, roleId, account); - - // member "since" cannot change as a consequence of time passing - assert getAccess1Before == getAccess1After; - - // any change of any other value should be a consequence of the effect timepoint being reached - assert ( - getAccess2Before != getAccess2After || - getAccess3Before != getAccess3After || - getAccess4Before != getAccess4After - ) => ( - getAccess4Before != 0 && - getAccess4Before > clock(e1) && - getAccess4Before <= clock(e2) && - getAccess2After == getAccess3Before && - getAccess3After == 0 && - getAccess4After == 0 - ); -} - -rule getAccessChangeCall(uint64 roleId, address account) { - env e; - - // sanity - require sanity(e); - - // values before - mathint getAccess1Before = getAccess_since(e, roleId, account); - mathint getAccess2Before = getAccess_currentDelay(e, roleId, account); - mathint getAccess3Before = getAccess_pendingDelay(e, roleId, account); - mathint getAccess4Before = getAccess_effect(e, roleId, account); - - // arbitrary function call - method f; calldataarg args; f(e, args); - - // values before - mathint getAccess1After = getAccess_since(e, roleId, account); - mathint getAccess2After = getAccess_currentDelay(e, roleId, account); - mathint getAccess3After = getAccess_pendingDelay(e, roleId, account); - mathint getAccess4After = getAccess_effect(e, roleId, account); - - // transitions - assert ( - getAccess1Before != getAccess1After || - getAccess2Before != getAccess2After || - getAccess3Before != getAccess3After || - getAccess4Before != getAccess4After - ) => ( - ( - f.selector == sig:grantRole(uint64,address,uint32).selector && - getAccess1After > 0 - ) || ( - ( - f.selector == sig:revokeRole(uint64,address).selector || - f.selector == sig:renounceRole(uint64,address).selector - ) && - getAccess1After == 0 && - getAccess2After == 0 && - getAccess3After == 0 && - getAccess4After == 0 - ) - ); -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ State transitions: isTargetClosed │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule isTargetClosedChangeTime(address target) { - env e1; - env e2; - - // values before - bool isClosedBefore = isTargetClosed(e1, target); - - // time pass: e1 → e2 - require clock(e1) <= clock(e2); - - // values after - bool isClosedAfter = isTargetClosed(e2, target); - - // transitions - assert isClosedBefore == isClosedAfter; -} - -rule isTargetClosedChangeCall(address target) { - env e; - - // values before - bool isClosedBefore = isTargetClosed(e, target); - - // arbitrary function call - method f; calldataarg args; f(e, args); - - // values after - bool isClosedAfter = isTargetClosed(e, target); - - // transitions - assert isClosedBefore != isClosedAfter => ( - f.selector == sig:setTargetClosed(address,bool).selector - ); -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ State transitions: getTargetFunctionRole │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule getTargetFunctionRoleChangeTime(address target, bytes4 selector) { - env e1; - env e2; - - // values before - mathint roleIdBefore = getTargetFunctionRole(e1, target, selector); - - // time pass: e1 → e2 - require clock(e1) <= clock(e2); - - // values after - mathint roleIdAfter = getTargetFunctionRole(e2, target, selector); - - // transitions - assert roleIdBefore == roleIdAfter; -} - -rule getTargetFunctionRoleChangeCall(address target, bytes4 selector) { - env e; - - // values before - mathint roleIdBefore = getTargetFunctionRole(e, target, selector); - - // arbitrary function call - method f; calldataarg args; f(e, args); - - // values after - mathint roleIdAfter = getTargetFunctionRole(e, target, selector); - - // transitions - assert roleIdBefore != roleIdAfter => ( - f.selector == sig:setTargetFunctionRole(address,bytes4[],uint64).selector - ); -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ State transitions: getTargetAdminDelay │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule getTargetAdminDelayChangeTime(address target) { - env e1; - env e2; - - // values before - mathint delayBefore = getTargetAdminDelay(e1, target); - mathint delayPendingBefore = getTargetAdminDelay_after(e1, target); - mathint delayEffectBefore = getTargetAdminDelay_effect(e1, target); - - // time pass: e1 → e2 - require clock(e1) <= clock(e2); - - // values after - mathint delayAfter = getTargetAdminDelay(e2, target); - mathint delayPendingAfter = getTargetAdminDelay_after(e2, target); - mathint delayEffectAfter = getTargetAdminDelay_effect(e2, target); - - assert ( - delayBefore != delayAfter || - delayPendingBefore != delayPendingAfter || - delayEffectBefore != delayEffectAfter - ) => ( - delayEffectBefore > clock(e1) && - delayEffectBefore <= clock(e2) && - delayAfter == delayPendingBefore && - delayPendingAfter == 0 && - delayEffectAfter == 0 - ); -} - -rule getTargetAdminDelayChangeCall(address target) { - env e; - - // values before - mathint delayBefore = getTargetAdminDelay(e, target); - mathint delayPendingBefore = getTargetAdminDelay_after(e, target); - mathint delayEffectBefore = getTargetAdminDelay_effect(e, target); - - // arbitrary function call - method f; calldataarg args; f(e, args); - - // values after - mathint delayAfter = getTargetAdminDelay(e, target); - mathint delayPendingAfter = getTargetAdminDelay_after(e, target); - mathint delayEffectAfter = getTargetAdminDelay_effect(e, target); - - // if anything changed ... - assert ( - delayBefore != delayAfter || - delayPendingBefore != delayPendingAfter || - delayEffectBefore != delayEffectAfter - ) => ( - ( - // ... it was the consequence of a call to setTargetAdminDelay - f.selector == sig:setTargetAdminDelay(address,uint32).selector - ) && ( - // ... delay cannot decrease instantly - delayAfter >= delayBefore - ) && ( - // ... if setback is not 0, value cannot change instantly - minSetback() > 0 => ( - delayBefore == delayAfter - ) - ) && ( - // ... if the value did not change and there is a minSetback, there must be something scheduled in the future - delayAfter == delayBefore && minSetback() > 0 => ( - delayEffectAfter >= clock(e) + minSetback() - ) - // note: if there is no minSetback, and if the caller "confirms" the current value, - // then this as immediate effect and nothing is scheduled - ) && ( - // ... if the value changed, then no further change should be scheduled - delayAfter != delayBefore => ( - delayPendingAfter == 0 && - delayEffectAfter == 0 - ) - ) - ); -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ State transitions: getRoleGrantDelay │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule getRoleGrantDelayChangeTime(uint64 roleId) { - env e1; - env e2; - - // values before - mathint delayBefore = getRoleGrantDelay(e1, roleId); - mathint delayPendingBefore = getRoleGrantDelay_after(e1, roleId); - mathint delayEffectBefore = getRoleGrantDelay_effect(e1, roleId); - - // time pass: e1 → e2 - require clock(e1) <= clock(e2); - - // values after - mathint delayAfter = getRoleGrantDelay(e2, roleId); - mathint delayPendingAfter = getRoleGrantDelay_after(e2, roleId); - mathint delayEffectAfter = getRoleGrantDelay_effect(e2, roleId); - - assert ( - delayBefore != delayAfter || - delayPendingBefore != delayPendingAfter || - delayEffectBefore != delayEffectAfter - ) => ( - delayEffectBefore > clock(e1) && - delayEffectBefore <= clock(e2) && - delayAfter == delayPendingBefore && - delayPendingAfter == 0 && - delayEffectAfter == 0 - ); -} - -rule getRoleGrantDelayChangeCall(uint64 roleId) { - env e; - - // values before - mathint delayBefore = getRoleGrantDelay(e, roleId); - mathint delayPendingBefore = getRoleGrantDelay_after(e, roleId); - mathint delayEffectBefore = getRoleGrantDelay_effect(e, roleId); - - // arbitrary function call - method f; calldataarg args; f(e, args); - - // values after - mathint delayAfter = getRoleGrantDelay(e, roleId); - mathint delayPendingAfter = getRoleGrantDelay_after(e, roleId); - mathint delayEffectAfter = getRoleGrantDelay_effect(e, roleId); - - // if anything changed ... - assert ( - delayBefore != delayAfter || - delayPendingBefore != delayPendingAfter || - delayEffectBefore != delayEffectAfter - ) => ( - ( - // ... it was the consequence of a call to setTargetAdminDelay - f.selector == sig:setGrantDelay(uint64,uint32).selector - ) && ( - // ... delay cannot decrease instantly - delayAfter >= delayBefore - ) && ( - // ... if setback is not 0, value cannot change instantly - minSetback() > 0 => ( - delayBefore == delayAfter - ) - ) && ( - // ... if the value did not change and there is a minSetback, there must be something scheduled in the future - delayAfter == delayBefore && minSetback() > 0 => ( - delayEffectAfter >= clock(e) + minSetback() - ) - // note: if there is no minSetback, and if the caller "confirms" the current value, - // then this as immediate effect and nothing is scheduled - ) && ( - // ... if the value changed, then no further change should be scheduled - delayAfter != delayBefore => ( - delayPendingAfter == 0 && - delayEffectAfter == 0 - ) - ) - ); -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ State transitions: getRoleAdmin & getRoleGuardian │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule getRoleAdminChangeCall(uint64 roleId) { - // values before - mathint adminIdBefore = getRoleAdmin(roleId); - - // arbitrary function call - env e; method f; calldataarg args; f(e, args); - - // values after - mathint adminIdAfter = getRoleAdmin(roleId); - - // transitions - assert adminIdBefore != adminIdAfter => f.selector == sig:setRoleAdmin(uint64,uint64).selector; -} - -rule getRoleGuardianChangeCall(uint64 roleId) { - // values before - mathint guardianIdBefore = getRoleGuardian(roleId); - - // arbitrary function call - env e; method f; calldataarg args; f(e, args); - - // values after - mathint guardianIdAfter = getRoleGuardian(roleId); - - // transitions - assert guardianIdBefore != guardianIdAfter => ( - f.selector == sig:setRoleGuardian(uint64,uint64).selector - ); -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ State transitions: getNonce │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule getNonceChangeCall(bytes32 operationId) { - // values before - mathint nonceBefore = getNonce(operationId); - - // reasonable assumption - require nonceBefore < max_uint32; - - // arbitrary function call - env e; method f; calldataarg args; f(e, args); - - // values after - mathint nonceAfter = getNonce(operationId); - - // transitions - assert nonceBefore != nonceAfter => ( - f.selector == sig:schedule(address,bytes,uint48).selector && - nonceAfter == nonceBefore + 1 - ); -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ State transitions: getSchedule │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule getScheduleChangeTime(bytes32 operationId) { - env e1; - env e2; - - // values before - mathint scheduleBefore = getSchedule(e1, operationId); - - // time pass: e1 → e2 - require clock(e1) <= clock(e2); - - // values after - mathint scheduleAfter = getSchedule(e2, operationId); - - // transition - assert scheduleBefore != scheduleAfter => ( - scheduleBefore + expiration() > clock(e1) && - scheduleBefore + expiration() <= clock(e2) && - scheduleAfter == 0 - ); -} - -rule getScheduleChangeCall(bytes32 operationId) { - env e; - - // values before - mathint scheduleBefore = getSchedule(e, operationId); - - // arbitrary function call - method f; calldataarg args; f(e, args); - - // values after - mathint scheduleAfter = getSchedule(e, operationId); - - // transitions - assert scheduleBefore != scheduleAfter => ( - (f.selector == sig:schedule(address,bytes,uint48).selector && scheduleAfter >= clock(e)) || - (f.selector == sig:execute(address,bytes).selector && scheduleAfter == 0 ) || - (f.selector == sig:cancel(address,address,bytes).selector && scheduleAfter == 0 ) || - (f.selector == sig:consumeScheduledOp(address,bytes).selector && scheduleAfter == 0 ) || - (isOnlyAuthorized(to_bytes4(f.selector)) && scheduleAfter == 0 ) - ); -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Functions: restricted functions can only be called by owner │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule restrictedFunctions(env e) { - require nonpayable(e); - require sanity(e); - - method f; - calldataarg args; - - f(e,args); - - assert ( - f.selector == sig:labelRole(uint64,string).selector || - f.selector == sig:setRoleAdmin(uint64,uint64).selector || - f.selector == sig:setRoleGuardian(uint64,uint64).selector || - f.selector == sig:setGrantDelay(uint64,uint32).selector || - f.selector == sig:setTargetAdminDelay(address,uint32).selector || - f.selector == sig:updateAuthority(address,address).selector || - f.selector == sig:setTargetClosed(address,bool).selector || - f.selector == sig:setTargetFunctionRole(address,bytes4[],uint64).selector - ) => ( - hasRole_isMember(e, ADMIN_ROLE(), e.msg.sender) || e.msg.sender == currentContract - ); -} - -rule restrictedFunctionsGrantRole(env e) { - require nonpayable(e); - require sanity(e); - - uint64 roleId; - address account; - uint32 executionDelay; - - // We want to check that the caller has the admin role before we possibly grant it. - bool hasAdminRoleBefore = hasRole_isMember(e, getRoleAdmin(roleId), e.msg.sender); - - grantRole(e, roleId, account, executionDelay); - - assert hasAdminRoleBefore || e.msg.sender == currentContract; -} - -rule restrictedFunctionsRevokeRole(env e) { - require nonpayable(e); - require sanity(e); - - uint64 roleId; - address account; - - // This is needed if roleId is self-administered, the `revokeRole` call could target - // e.msg.sender and remove the very role that is necessary for authorizing the call. - bool hasAdminRoleBefore = hasRole_isMember(e, getRoleAdmin(roleId), e.msg.sender); - - revokeRole(e, roleId, account); - - assert hasAdminRoleBefore || e.msg.sender == currentContract; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Functions: canCall delay is enforced for calls to execute (only for others target) │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -// getScheduleChangeCall proves that only {schedule} can set an operation schedule to a non 0 value -rule callDelayEnforce_scheduleInTheFuture(env e) { - address target; - bytes data; - uint48 when; - - // Condition: calling a third party with a delay - mathint delay = canCallExtended_delay(e, e.msg.sender, target, data); - require delay > 0; - - // Schedule - schedule(e, target, data, when); - - // Get operation schedule - mathint timepoint = getSchedule(e, hashOperation(e.msg.sender, target, data)); - - // Schedule is far enough in the future - assert timepoint == max(clock(e) + delay, when); -} - -rule callDelayEnforce_executeAfterDelay(env e) { - address target; - bytes data; - - // Condition: calling a third party with a delay - mathint delay = canCallExtended_delay(e, e.msg.sender, target, data); - - // Get operation schedule before - mathint scheduleBefore = getSchedule(e, hashOperation(e.msg.sender, target, data)); - - // Do call - execute@withrevert(e, target, data); - bool success = !lastReverted; - - // Get operation schedule after - mathint scheduleAfter = getSchedule(e, hashOperation(e.msg.sender, target, data)); - - // Can only execute if delay is set and has passed - assert success => ( - delay > 0 => ( - scheduleBefore != 0 && - scheduleBefore <= clock(e) - ) && - scheduleAfter == 0 - ); -} diff --git a/lib/openzeppelin-contracts/certora/specs/DoubleEndedQueue.spec b/lib/openzeppelin-contracts/certora/specs/DoubleEndedQueue.spec deleted file mode 100644 index 3b71bb4..0000000 --- a/lib/openzeppelin-contracts/certora/specs/DoubleEndedQueue.spec +++ /dev/null @@ -1,300 +0,0 @@ -import "helpers/helpers.spec"; - -methods { - function pushFront(bytes32) external envfree; - function pushBack(bytes32) external envfree; - function popFront() external returns (bytes32) envfree; - function popBack() external returns (bytes32) envfree; - function clear() external envfree; - - // exposed for FV - function begin() external returns (uint128) envfree; - function end() external returns (uint128) envfree; - - // view - function length() external returns (uint256) envfree; - function empty() external returns (bool) envfree; - function front() external returns (bytes32) envfree; - function back() external returns (bytes32) envfree; - function at_(uint256) external returns (bytes32) envfree; // at is a reserved word -} - -definition full() returns bool = length() == max_uint128; - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariant: empty() is length 0 and no element exists │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant emptiness() - empty() <=> length() == 0 - filtered { f -> !f.isView } - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariant: front points to the first index and back points to the last one │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant queueFront() - at_(0) == front() - filtered { f -> !f.isView } - -invariant queueBack() - at_(require_uint256(length() - 1)) == back() - filtered { f -> !f.isView } - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Function correctness: pushFront adds an element at the beginning of the queue │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule pushFront(bytes32 value) { - uint256 lengthBefore = length(); - bool fullBefore = full(); - - pushFront@withrevert(value); - bool success = !lastReverted; - - // liveness - assert success <=> !fullBefore, "never revert if not previously full"; - - // effect - assert success => front() == value, "front set to value"; - assert success => to_mathint(length()) == lengthBefore + 1, "queue extended"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: pushFront preserves the previous values in the queue with a +1 offset │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule pushFrontConsistency(uint256 index) { - bytes32 beforeAt = at_(index); - - bytes32 value; - pushFront(value); - - // try to read value - bytes32 afterAt = at_@withrevert(require_uint256(index + 1)); - - assert !lastReverted, "value still there"; - assert afterAt == beforeAt, "data is preserved"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Function correctness: pushBack adds an element at the end of the queue │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule pushBack(bytes32 value) { - uint256 lengthBefore = length(); - bool fullBefore = full(); - - pushBack@withrevert(value); - bool success = !lastReverted; - - // liveness - assert success <=> !fullBefore, "never revert if not previously full"; - - // effect - assert success => back() == value, "back set to value"; - assert success => to_mathint(length()) == lengthBefore + 1, "queue increased"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: pushBack preserves the previous values in the queue │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule pushBackConsistency(uint256 index) { - bytes32 beforeAt = at_(index); - - bytes32 value; - pushBack(value); - - // try to read value - bytes32 afterAt = at_@withrevert(index); - - assert !lastReverted, "value still there"; - assert afterAt == beforeAt, "data is preserved"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Function correctness: popFront removes an element from the beginning of the queue │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule popFront { - uint256 lengthBefore = length(); - bytes32 frontBefore = front@withrevert(); - - bytes32 popped = popFront@withrevert(); - bool success = !lastReverted; - - // liveness - assert success <=> lengthBefore != 0, "never reverts if not previously empty"; - - // effect - assert success => frontBefore == popped, "previous front is returned"; - assert success => to_mathint(length()) == lengthBefore - 1, "queue decreased"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: at(x) is preserved and offset to at(x - 1) after calling popFront | -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule popFrontConsistency(uint256 index) { - // Read (any) value that is not the front (this asserts the value exists / the queue is long enough) - require index > 1; - bytes32 before = at_(index); - - popFront(); - - // try to read value - bytes32 after = at_@withrevert(require_uint256(index - 1)); - - assert !lastReverted, "value still exists in the queue"; - assert before == after, "values are offset and not modified"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Function correctness: popBack removes an element from the end of the queue │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule popBack { - uint256 lengthBefore = length(); - bytes32 backBefore = back@withrevert(); - - bytes32 popped = popBack@withrevert(); - bool success = !lastReverted; - - // liveness - assert success <=> lengthBefore != 0, "never reverts if not previously empty"; - - // effect - assert success => backBefore == popped, "previous back is returned"; - assert success => to_mathint(length()) == lengthBefore - 1, "queue decreased"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: at(x) is preserved after calling popBack | -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule popBackConsistency(uint256 index) { - // Read (any) value that is not the back (this asserts the value exists / the queue is long enough) - require to_mathint(index) < length() - 1; - bytes32 before = at_(index); - - popBack(); - - // try to read value - bytes32 after = at_@withrevert(index); - - assert !lastReverted, "value still exists in the queue"; - assert before == after, "values are offset and not modified"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Function correctness: clear sets length to 0 │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule clear { - clear@withrevert(); - - // liveness - assert !lastReverted, "never reverts"; - - // effect - assert length() == 0, "sets length to 0"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: front/back access reverts only if the queue is empty or querying out of bounds │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule onlyEmptyOrFullRevert(env e) { - require nonpayable(e); - - method f; - calldataarg args; - - bool emptyBefore = empty(); - bool fullBefore = full(); - - f@withrevert(e, args); - - assert lastReverted => ( - (f.selector == sig:front().selector && emptyBefore) || - (f.selector == sig:back().selector && emptyBefore) || - (f.selector == sig:popFront().selector && emptyBefore) || - (f.selector == sig:popBack().selector && emptyBefore) || - (f.selector == sig:pushFront(bytes32).selector && fullBefore ) || - (f.selector == sig:pushBack(bytes32).selector && fullBefore ) || - f.selector == sig:at_(uint256).selector // revert conditions are verified in onlyOutOfBoundsRevert - ), "only revert if empty or out of bounds"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: at(index) only reverts if index is out of bounds | -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule onlyOutOfBoundsRevert(uint256 index) { - at_@withrevert(index); - - assert lastReverted <=> index >= length(), "only reverts if index is out of bounds"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: only clear/push/pop operations can change the length of the queue │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule noLengthChange(env e) { - method f; - calldataarg args; - - uint256 lengthBefore = length(); - f(e, args); - uint256 lengthAfter = length(); - - assert lengthAfter != lengthBefore => ( - (f.selector == sig:pushFront(bytes32).selector && to_mathint(lengthAfter) == lengthBefore + 1) || - (f.selector == sig:pushBack(bytes32).selector && to_mathint(lengthAfter) == lengthBefore + 1) || - (f.selector == sig:popBack().selector && to_mathint(lengthAfter) == lengthBefore - 1) || - (f.selector == sig:popFront().selector && to_mathint(lengthAfter) == lengthBefore - 1) || - (f.selector == sig:clear().selector && lengthAfter == 0) - ), "length is only affected by clear/pop/push operations"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: only push/pop can change values bounded in the queue (outside values aren't cleared) │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule noDataChange(env e) { - method f; - calldataarg args; - - uint256 index; - bytes32 atBefore = at_(index); - f(e, args); - bytes32 atAfter = at_@withrevert(index); - bool atAfterSuccess = !lastReverted; - - assert !atAfterSuccess <=> ( - (f.selector == sig:clear().selector ) || - (f.selector == sig:popBack().selector && index == length()) || - (f.selector == sig:popFront().selector && index == length()) - ), "indexes of the queue are only removed by clear or pop"; - - assert atAfterSuccess && atAfter != atBefore => ( - f.selector == sig:popFront().selector || - f.selector == sig:pushFront(bytes32).selector - ), "values of the queue are only changed by popFront or pushFront"; -} diff --git a/lib/openzeppelin-contracts/certora/specs/ERC20.spec b/lib/openzeppelin-contracts/certora/specs/ERC20.spec deleted file mode 100644 index 21a0335..0000000 --- a/lib/openzeppelin-contracts/certora/specs/ERC20.spec +++ /dev/null @@ -1,352 +0,0 @@ -import "helpers/helpers.spec"; -import "methods/IERC20.spec"; -import "methods/IERC2612.spec"; - -methods { - // exposed for FV - function mint(address,uint256) external; - function burn(address,uint256) external; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Ghost & hooks: sum of all balances │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -ghost mathint sumOfBalances { - init_state axiom sumOfBalances == 0; -} - -// Because `balance` has a uint256 type, any balance addition in CVL1 behaved as a `require_uint256()` casting, -// leaving out the possibility of overflow. This is not the case in CVL2 where casting became more explicit. -// A counterexample in CVL2 is having an initial state where Alice initial balance is larger than totalSupply, which -// overflows Alice's balance when receiving a transfer. This is not possible unless the contract is deployed into an -// already used address (or upgraded from corrupted state). -// We restrict such behavior by making sure no balance is greater than the sum of balances. -hook Sload uint256 balance _balances[KEY address addr] STORAGE { - require sumOfBalances >= to_mathint(balance); -} - -hook Sstore _balances[KEY address addr] uint256 newValue (uint256 oldValue) STORAGE { - sumOfBalances = sumOfBalances - oldValue + newValue; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariant: totalSupply is the sum of all balances │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant totalSupplyIsSumOfBalances() - to_mathint(totalSupply()) == sumOfBalances; - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariant: balance of address(0) is 0 │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant zeroAddressNoBalance() - balanceOf(0) == 0; - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rules: only mint and burn can change total supply │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule noChangeTotalSupply(env e) { - requireInvariant totalSupplyIsSumOfBalances(); - - method f; - calldataarg args; - - uint256 totalSupplyBefore = totalSupply(); - f(e, args); - uint256 totalSupplyAfter = totalSupply(); - - assert totalSupplyAfter > totalSupplyBefore => f.selector == sig:mint(address,uint256).selector; - assert totalSupplyAfter < totalSupplyBefore => f.selector == sig:burn(address,uint256).selector; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rules: only the token holder or an approved third party can reduce an account's balance │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule onlyAuthorizedCanTransfer(env e) { - requireInvariant totalSupplyIsSumOfBalances(); - - method f; - calldataarg args; - address account; - - uint256 allowanceBefore = allowance(account, e.msg.sender); - uint256 balanceBefore = balanceOf(account); - f(e, args); - uint256 balanceAfter = balanceOf(account); - - assert ( - balanceAfter < balanceBefore - ) => ( - f.selector == sig:burn(address,uint256).selector || - e.msg.sender == account || - balanceBefore - balanceAfter <= to_mathint(allowanceBefore) - ); -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rules: only the token holder (or a permit) can increase allowance. The spender can decrease it by using it │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule onlyHolderOfSpenderCanChangeAllowance(env e) { - requireInvariant totalSupplyIsSumOfBalances(); - - method f; - calldataarg args; - address holder; - address spender; - - uint256 allowanceBefore = allowance(holder, spender); - f(e, args); - uint256 allowanceAfter = allowance(holder, spender); - - assert ( - allowanceAfter > allowanceBefore - ) => ( - (f.selector == sig:approve(address,uint256).selector && e.msg.sender == holder) || - (f.selector == sig:permit(address,address,uint256,uint256,uint8,bytes32,bytes32).selector) - ); - - assert ( - allowanceAfter < allowanceBefore - ) => ( - (f.selector == sig:transferFrom(address,address,uint256).selector && e.msg.sender == spender) || - (f.selector == sig:approve(address,uint256).selector && e.msg.sender == holder ) || - (f.selector == sig:permit(address,address,uint256,uint256,uint8,bytes32,bytes32).selector) - ); -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rules: mint behavior and side effects │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule mint(env e) { - requireInvariant totalSupplyIsSumOfBalances(); - require nonpayable(e); - - address to; - address other; - uint256 amount; - - // cache state - uint256 toBalanceBefore = balanceOf(to); - uint256 otherBalanceBefore = balanceOf(other); - uint256 totalSupplyBefore = totalSupply(); - - // run transaction - mint@withrevert(e, to, amount); - - // check outcome - if (lastReverted) { - assert to == 0 || totalSupplyBefore + amount > max_uint256; - } else { - // updates balance and totalSupply - assert to_mathint(balanceOf(to)) == toBalanceBefore + amount; - assert to_mathint(totalSupply()) == totalSupplyBefore + amount; - - // no other balance is modified - assert balanceOf(other) != otherBalanceBefore => other == to; - } -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rules: burn behavior and side effects │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule burn(env e) { - requireInvariant totalSupplyIsSumOfBalances(); - require nonpayable(e); - - address from; - address other; - uint256 amount; - - // cache state - uint256 fromBalanceBefore = balanceOf(from); - uint256 otherBalanceBefore = balanceOf(other); - uint256 totalSupplyBefore = totalSupply(); - - // run transaction - burn@withrevert(e, from, amount); - - // check outcome - if (lastReverted) { - assert from == 0 || fromBalanceBefore < amount; - } else { - // updates balance and totalSupply - assert to_mathint(balanceOf(from)) == fromBalanceBefore - amount; - assert to_mathint(totalSupply()) == totalSupplyBefore - amount; - - // no other balance is modified - assert balanceOf(other) != otherBalanceBefore => other == from; - } -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: transfer behavior and side effects │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule transfer(env e) { - requireInvariant totalSupplyIsSumOfBalances(); - require nonpayable(e); - - address holder = e.msg.sender; - address recipient; - address other; - uint256 amount; - - // cache state - uint256 holderBalanceBefore = balanceOf(holder); - uint256 recipientBalanceBefore = balanceOf(recipient); - uint256 otherBalanceBefore = balanceOf(other); - - // run transaction - transfer@withrevert(e, recipient, amount); - - // check outcome - if (lastReverted) { - assert holder == 0 || recipient == 0 || amount > holderBalanceBefore; - } else { - // balances of holder and recipient are updated - assert to_mathint(balanceOf(holder)) == holderBalanceBefore - (holder == recipient ? 0 : amount); - assert to_mathint(balanceOf(recipient)) == recipientBalanceBefore + (holder == recipient ? 0 : amount); - - // no other balance is modified - assert balanceOf(other) != otherBalanceBefore => (other == holder || other == recipient); - } -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: transferFrom behavior and side effects │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule transferFrom(env e) { - requireInvariant totalSupplyIsSumOfBalances(); - require nonpayable(e); - - address spender = e.msg.sender; - address holder; - address recipient; - address other; - uint256 amount; - - // cache state - uint256 allowanceBefore = allowance(holder, spender); - uint256 holderBalanceBefore = balanceOf(holder); - uint256 recipientBalanceBefore = balanceOf(recipient); - uint256 otherBalanceBefore = balanceOf(other); - - // run transaction - transferFrom@withrevert(e, holder, recipient, amount); - - // check outcome - if (lastReverted) { - assert holder == 0 || recipient == 0 || spender == 0 || amount > holderBalanceBefore || amount > allowanceBefore; - } else { - // allowance is valid & updated - assert allowanceBefore >= amount; - assert to_mathint(allowance(holder, spender)) == (allowanceBefore == max_uint256 ? max_uint256 : allowanceBefore - amount); - - // balances of holder and recipient are updated - assert to_mathint(balanceOf(holder)) == holderBalanceBefore - (holder == recipient ? 0 : amount); - assert to_mathint(balanceOf(recipient)) == recipientBalanceBefore + (holder == recipient ? 0 : amount); - - // no other balance is modified - assert balanceOf(other) != otherBalanceBefore => (other == holder || other == recipient); - } -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: approve behavior and side effects │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule approve(env e) { - require nonpayable(e); - - address holder = e.msg.sender; - address spender; - address otherHolder; - address otherSpender; - uint256 amount; - - // cache state - uint256 otherAllowanceBefore = allowance(otherHolder, otherSpender); - - // run transaction - approve@withrevert(e, spender, amount); - - // check outcome - if (lastReverted) { - assert holder == 0 || spender == 0; - } else { - // allowance is updated - assert allowance(holder, spender) == amount; - - // other allowances are untouched - assert allowance(otherHolder, otherSpender) != otherAllowanceBefore => (otherHolder == holder && otherSpender == spender); - } -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: permit behavior and side effects │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule permit(env e) { - require nonpayable(e); - - address holder; - address spender; - uint256 amount; - uint256 deadline; - uint8 v; - bytes32 r; - bytes32 s; - - address account1; - address account2; - address account3; - - // cache state - uint256 nonceBefore = nonces(holder); - uint256 otherNonceBefore = nonces(account1); - uint256 otherAllowanceBefore = allowance(account2, account3); - - // sanity: nonce overflow, which possible in theory, is assumed to be impossible in practice - require nonceBefore < max_uint256; - require otherNonceBefore < max_uint256; - - // run transaction - permit@withrevert(e, holder, spender, amount, deadline, v, r, s); - - // check outcome - if (lastReverted) { - // Without formally checking the signature, we can't verify exactly the revert causes - assert true; - } else { - // allowance and nonce are updated - assert allowance(holder, spender) == amount; - assert to_mathint(nonces(holder)) == nonceBefore + 1; - - // deadline was respected - assert deadline >= e.block.timestamp; - - // no other allowance or nonce is modified - assert nonces(account1) != otherNonceBefore => account1 == holder; - assert allowance(account2, account3) != otherAllowanceBefore => (account2 == holder && account3 == spender); - } -} diff --git a/lib/openzeppelin-contracts/certora/specs/ERC20FlashMint.spec b/lib/openzeppelin-contracts/certora/specs/ERC20FlashMint.spec deleted file mode 100644 index 4071052..0000000 --- a/lib/openzeppelin-contracts/certora/specs/ERC20FlashMint.spec +++ /dev/null @@ -1,55 +0,0 @@ -import "helpers/helpers.spec"; -import "methods/IERC20.spec"; -import "methods/IERC3156FlashLender.spec"; -import "methods/IERC3156FlashBorrower.spec"; - -methods { - // non standard ERC-3156 functions - function flashFeeReceiver() external returns (address) envfree; - - // function summaries below - function _._update(address from, address to, uint256 amount) internal => specUpdate(from, to, amount) expect void ALL; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Ghost: track mint and burns in the CVL │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -ghost mapping(address => mathint) trackedMintAmount; -ghost mapping(address => mathint) trackedBurnAmount; -ghost mapping(address => mapping(address => mathint)) trackedTransferedAmount; - -function specUpdate(address from, address to, uint256 amount) { - if (from == 0 && to == 0) { assert(false); } // defensive - - if (from == 0) { - trackedMintAmount[to] = amount; - } else if (to == 0) { - trackedBurnAmount[from] = amount; - } else { - trackedTransferedAmount[from][to] = amount; - } -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: When doing a flashLoan, "amount" is minted and burnt, additionally, the fee is either burnt │ -│ (if the fee recipient is 0) or transferred (if the fee recipient is not 0) │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule checkMintAndBurn(env e) { - address receiver; - address token; - uint256 amount; - bytes data; - - uint256 fees = flashFee(token, amount); - address recipient = flashFeeReceiver(); - - flashLoan(e, receiver, token, amount, data); - - assert trackedMintAmount[receiver] == to_mathint(amount); - assert trackedBurnAmount[receiver] == amount + to_mathint(recipient == 0 ? fees : 0); - assert (fees > 0 && recipient != 0) => trackedTransferedAmount[receiver][recipient] == to_mathint(fees); -} diff --git a/lib/openzeppelin-contracts/certora/specs/ERC20Wrapper.spec b/lib/openzeppelin-contracts/certora/specs/ERC20Wrapper.spec deleted file mode 100644 index 04e6704..0000000 --- a/lib/openzeppelin-contracts/certora/specs/ERC20Wrapper.spec +++ /dev/null @@ -1,198 +0,0 @@ -import "helpers/helpers.spec"; -import "ERC20.spec"; - -methods { - function underlying() external returns(address) envfree; - function underlyingTotalSupply() external returns(uint256) envfree; - function underlyingBalanceOf(address) external returns(uint256) envfree; - function underlyingAllowanceToThis(address) external returns(uint256) envfree; - - function depositFor(address, uint256) external returns(bool); - function withdrawTo(address, uint256) external returns(bool); - function recover(address) external returns(uint256); -} - -use invariant totalSupplyIsSumOfBalances; - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Helper: consequence of `totalSupplyIsSumOfBalances` applied to underlying │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -definition underlyingBalancesLowerThanUnderlyingSupply(address a) returns bool = - underlyingBalanceOf(a) <= underlyingTotalSupply(); - -definition sumOfUnderlyingBalancesLowerThanUnderlyingSupply(address a, address b) returns bool = - a != b => underlyingBalanceOf(a) + underlyingBalanceOf(b) <= to_mathint(underlyingTotalSupply()); - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariant: wrapped token can't be undercollateralized (solvency of the wrapper) │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant totalSupplyIsSmallerThanUnderlyingBalance() - totalSupply() <= underlyingBalanceOf(currentContract) && - underlyingBalanceOf(currentContract) <= underlyingTotalSupply() && - underlyingTotalSupply() <= max_uint256 - { - preserved { - requireInvariant totalSupplyIsSumOfBalances; - require underlyingBalancesLowerThanUnderlyingSupply(currentContract); - } - preserved depositFor(address account, uint256 amount) with (env e) { - require sumOfUnderlyingBalancesLowerThanUnderlyingSupply(e.msg.sender, currentContract); - } - } - -invariant noSelfWrap() - currentContract != underlying(); - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: depositFor liveness and effects │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule depositFor(env e) { - require nonpayable(e); - - address sender = e.msg.sender; - address receiver; - address other; - uint256 amount; - - // sanity - requireInvariant noSelfWrap; - requireInvariant totalSupplyIsSumOfBalances; - requireInvariant totalSupplyIsSmallerThanUnderlyingBalance; - require sumOfUnderlyingBalancesLowerThanUnderlyingSupply(currentContract, sender); - - uint256 balanceBefore = balanceOf(receiver); - uint256 supplyBefore = totalSupply(); - uint256 senderUnderlyingBalanceBefore = underlyingBalanceOf(sender); - uint256 senderUnderlyingAllowanceBefore = underlyingAllowanceToThis(sender); - uint256 wrapperUnderlyingBalanceBefore = underlyingBalanceOf(currentContract); - uint256 underlyingSupplyBefore = underlyingTotalSupply(); - - uint256 otherBalanceBefore = balanceOf(other); - uint256 otherUnderlyingBalanceBefore = underlyingBalanceOf(other); - - depositFor@withrevert(e, receiver, amount); - bool success = !lastReverted; - - // liveness - assert success <=> ( - sender != currentContract && // invalid sender - sender != 0 && // invalid sender - receiver != currentContract && // invalid receiver - receiver != 0 && // invalid receiver - amount <= senderUnderlyingBalanceBefore && // deposit doesn't exceed balance - amount <= senderUnderlyingAllowanceBefore // deposit doesn't exceed allowance - ); - - // effects - assert success => ( - to_mathint(balanceOf(receiver)) == balanceBefore + amount && - to_mathint(totalSupply()) == supplyBefore + amount && - to_mathint(underlyingBalanceOf(currentContract)) == wrapperUnderlyingBalanceBefore + amount && - to_mathint(underlyingBalanceOf(sender)) == senderUnderlyingBalanceBefore - amount - ); - - // no side effect - assert underlyingTotalSupply() == underlyingSupplyBefore; - assert balanceOf(other) != otherBalanceBefore => other == receiver; - assert underlyingBalanceOf(other) != otherUnderlyingBalanceBefore => (other == sender || other == currentContract); -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: withdrawTo liveness and effects │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule withdrawTo(env e) { - require nonpayable(e); - - address sender = e.msg.sender; - address receiver; - address other; - uint256 amount; - - // sanity - requireInvariant noSelfWrap; - requireInvariant totalSupplyIsSumOfBalances; - requireInvariant totalSupplyIsSmallerThanUnderlyingBalance; - require sumOfUnderlyingBalancesLowerThanUnderlyingSupply(currentContract, receiver); - - uint256 balanceBefore = balanceOf(sender); - uint256 supplyBefore = totalSupply(); - uint256 receiverUnderlyingBalanceBefore = underlyingBalanceOf(receiver); - uint256 wrapperUnderlyingBalanceBefore = underlyingBalanceOf(currentContract); - uint256 underlyingSupplyBefore = underlyingTotalSupply(); - - uint256 otherBalanceBefore = balanceOf(other); - uint256 otherUnderlyingBalanceBefore = underlyingBalanceOf(other); - - withdrawTo@withrevert(e, receiver, amount); - bool success = !lastReverted; - - // liveness - assert success <=> ( - sender != 0 && // invalid sender - receiver != currentContract && // invalid receiver - receiver != 0 && // invalid receiver - amount <= balanceBefore // withdraw doesn't exceed balance - ); - - // effects - assert success => ( - to_mathint(balanceOf(sender)) == balanceBefore - amount && - to_mathint(totalSupply()) == supplyBefore - amount && - to_mathint(underlyingBalanceOf(currentContract)) == wrapperUnderlyingBalanceBefore - (currentContract != receiver ? amount : 0) && - to_mathint(underlyingBalanceOf(receiver)) == receiverUnderlyingBalanceBefore + (currentContract != receiver ? amount : 0) - ); - - // no side effect - assert underlyingTotalSupply() == underlyingSupplyBefore; - assert balanceOf(other) != otherBalanceBefore => other == sender; - assert underlyingBalanceOf(other) != otherUnderlyingBalanceBefore => (other == receiver || other == currentContract); -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: recover liveness and effects │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule recover(env e) { - require nonpayable(e); - - address receiver; - address other; - - // sanity - requireInvariant noSelfWrap; - requireInvariant totalSupplyIsSumOfBalances; - requireInvariant totalSupplyIsSmallerThanUnderlyingBalance; - - mathint value = underlyingBalanceOf(currentContract) - totalSupply(); - uint256 supplyBefore = totalSupply(); - uint256 balanceBefore = balanceOf(receiver); - - uint256 otherBalanceBefore = balanceOf(other); - uint256 otherUnderlyingBalanceBefore = underlyingBalanceOf(other); - - recover@withrevert(e, receiver); - bool success = !lastReverted; - - // liveness - assert success <=> receiver != 0; - - // effect - assert success => ( - to_mathint(balanceOf(receiver)) == balanceBefore + value && - to_mathint(totalSupply()) == supplyBefore + value && - totalSupply() == underlyingBalanceOf(currentContract) - ); - - // no side effect - assert underlyingBalanceOf(other) == otherUnderlyingBalanceBefore; - assert balanceOf(other) != otherBalanceBefore => other == receiver; -} diff --git a/lib/openzeppelin-contracts/certora/specs/ERC721.spec b/lib/openzeppelin-contracts/certora/specs/ERC721.spec deleted file mode 100644 index bad4c47..0000000 --- a/lib/openzeppelin-contracts/certora/specs/ERC721.spec +++ /dev/null @@ -1,679 +0,0 @@ -import "helpers/helpers.spec"; -import "methods/IERC721.spec"; -import "methods/IERC721Receiver.spec"; - -methods { - // exposed for FV - function mint(address,uint256) external; - function safeMint(address,uint256) external; - function safeMint(address,uint256,bytes) external; - function burn(uint256) external; - - function unsafeOwnerOf(uint256) external returns (address) envfree; - function unsafeGetApproved(uint256) external returns (address) envfree; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Helpers │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ - -definition authSanity(env e) returns bool = e.msg.sender != 0; - -// Could be broken in theory, but not in practice -definition balanceLimited(address account) returns bool = balanceOf(account) < max_uint256; - -function helperTransferWithRevert(env e, method f, address from, address to, uint256 tokenId) { - if (f.selector == sig:transferFrom(address,address,uint256).selector) { - transferFrom@withrevert(e, from, to, tokenId); - } else if (f.selector == sig:safeTransferFrom(address,address,uint256).selector) { - safeTransferFrom@withrevert(e, from, to, tokenId); - } else if (f.selector == sig:safeTransferFrom(address,address,uint256,bytes).selector) { - bytes params; - require params.length < 0xffff; - safeTransferFrom@withrevert(e, from, to, tokenId, params); - } else { - calldataarg args; - f@withrevert(e, args); - } -} - -function helperMintWithRevert(env e, method f, address to, uint256 tokenId) { - if (f.selector == sig:mint(address,uint256).selector) { - mint@withrevert(e, to, tokenId); - } else if (f.selector == sig:safeMint(address,uint256).selector) { - safeMint@withrevert(e, to, tokenId); - } else if (f.selector == sig:safeMint(address,uint256,bytes).selector) { - bytes params; - require params.length < 0xffff; - safeMint@withrevert(e, to, tokenId, params); - } else { - require false; - } -} - -function helperSoundFnCall(env e, method f) { - if (f.selector == sig:mint(address,uint256).selector) { - address to; uint256 tokenId; - require balanceLimited(to); - requireInvariant notMintedUnset(tokenId); - mint(e, to, tokenId); - } else if (f.selector == sig:safeMint(address,uint256).selector) { - address to; uint256 tokenId; - require balanceLimited(to); - requireInvariant notMintedUnset(tokenId); - safeMint(e, to, tokenId); - } else if (f.selector == sig:safeMint(address,uint256,bytes).selector) { - address to; uint256 tokenId; bytes data; - require data.length < 0xffff; - require balanceLimited(to); - requireInvariant notMintedUnset(tokenId); - safeMint(e, to, tokenId, data); - } else if (f.selector == sig:burn(uint256).selector) { - uint256 tokenId; - requireInvariant ownerHasBalance(tokenId); - requireInvariant notMintedUnset(tokenId); - burn(e, tokenId); - } else if (f.selector == sig:transferFrom(address,address,uint256).selector) { - address from; address to; uint256 tokenId; - require balanceLimited(to); - requireInvariant ownerHasBalance(tokenId); - requireInvariant notMintedUnset(tokenId); - transferFrom(e, from, to, tokenId); - } else if (f.selector == sig:safeTransferFrom(address,address,uint256).selector) { - address from; address to; uint256 tokenId; - require balanceLimited(to); - requireInvariant ownerHasBalance(tokenId); - requireInvariant notMintedUnset(tokenId); - safeTransferFrom(e, from, to, tokenId); - } else if (f.selector == sig:safeTransferFrom(address,address,uint256,bytes).selector) { - address from; address to; uint256 tokenId; bytes data; - require data.length < 0xffff; - require balanceLimited(to); - requireInvariant ownerHasBalance(tokenId); - requireInvariant notMintedUnset(tokenId); - safeTransferFrom(e, from, to, tokenId, data); - } else { - calldataarg args; - f(e, args); - } -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Ghost & hooks: ownership count │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -ghost mathint _ownedTotal { - init_state axiom _ownedTotal == 0; -} - -ghost mapping(address => mathint) _ownedByUser { - init_state axiom forall address a. _ownedByUser[a] == 0; -} - -hook Sstore _owners[KEY uint256 tokenId] address newOwner (address oldOwner) STORAGE { - _ownedByUser[newOwner] = _ownedByUser[newOwner] + to_mathint(newOwner != 0 ? 1 : 0); - _ownedByUser[oldOwner] = _ownedByUser[oldOwner] - to_mathint(oldOwner != 0 ? 1 : 0); - _ownedTotal = _ownedTotal + to_mathint(newOwner != 0 ? 1 : 0) - to_mathint(oldOwner != 0 ? 1 : 0); -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Ghost & hooks: sum of all balances │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -ghost mathint _supply { - init_state axiom _supply == 0; -} - -ghost mapping(address => mathint) _balances { - init_state axiom forall address a. _balances[a] == 0; -} - -hook Sstore _balances[KEY address addr] uint256 newValue (uint256 oldValue) STORAGE { - _supply = _supply - oldValue + newValue; -} - -// TODO: This used to not be necessary. We should try to remove it. In order to do so, we will probably need to add -// many "preserved" directive that require the "balanceOfConsistency" invariant on the accounts involved. -hook Sload uint256 value _balances[KEY address user] STORAGE { - require _balances[user] == to_mathint(value); -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariant: number of owned tokens is the sum of all balances │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant ownedTotalIsSumOfBalances() - _ownedTotal == _supply - { - preserved mint(address to, uint256 tokenId) with (env e) { - require balanceLimited(to); - } - preserved safeMint(address to, uint256 tokenId) with (env e) { - require balanceLimited(to); - } - preserved safeMint(address to, uint256 tokenId, bytes data) with (env e) { - require balanceLimited(to); - } - preserved burn(uint256 tokenId) with (env e) { - requireInvariant ownerHasBalance(tokenId); - requireInvariant balanceOfConsistency(ownerOf(tokenId)); - } - preserved transferFrom(address from, address to, uint256 tokenId) with (env e) { - require balanceLimited(to); - requireInvariant ownerHasBalance(tokenId); - requireInvariant balanceOfConsistency(from); - requireInvariant balanceOfConsistency(to); - } - preserved safeTransferFrom(address from, address to, uint256 tokenId) with (env e) { - require balanceLimited(to); - requireInvariant ownerHasBalance(tokenId); - requireInvariant balanceOfConsistency(from); - requireInvariant balanceOfConsistency(to); - } - preserved safeTransferFrom(address from, address to, uint256 tokenId, bytes data) with (env e) { - require balanceLimited(to); - requireInvariant ownerHasBalance(tokenId); - requireInvariant balanceOfConsistency(from); - requireInvariant balanceOfConsistency(to); - } - } - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariant: balanceOf is the number of tokens owned │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant balanceOfConsistency(address user) - to_mathint(balanceOf(user)) == _ownedByUser[user] && - to_mathint(balanceOf(user)) == _balances[user] - { - preserved { - require balanceLimited(user); - } - } - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariant: owner of a token must have some balance │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant ownerHasBalance(uint256 tokenId) - balanceOf(ownerOf(tokenId)) > 0 - { - preserved { - requireInvariant balanceOfConsistency(ownerOf(tokenId)); - require balanceLimited(ownerOf(tokenId)); - } - } - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: balance of address(0) is 0 │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule zeroAddressBalanceRevert() { - balanceOf@withrevert(0); - assert lastReverted; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariant: address(0) has no authorized operator │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant zeroAddressHasNoApprovedOperator(address a) - !isApprovedForAll(0, a) - { - preserved with (env e) { - require nonzerosender(e); - } - } - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariant: tokens that do not exist are not owned and not approved │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant notMintedUnset(uint256 tokenId) - unsafeOwnerOf(tokenId) == 0 => unsafeGetApproved(tokenId) == 0; - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: unsafeOwnerOf and unsafeGetApproved don't revert + ownerOf and getApproved revert if token does not exist │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule notMintedRevert(uint256 tokenId) { - requireInvariant notMintedUnset(tokenId); - - address _owner = unsafeOwnerOf@withrevert(tokenId); - assert !lastReverted; - - address _approved = unsafeGetApproved@withrevert(tokenId); - assert !lastReverted; - - address owner = ownerOf@withrevert(tokenId); - assert lastReverted <=> _owner == 0; - assert !lastReverted => _owner == owner; - - address approved = getApproved@withrevert(tokenId); - assert lastReverted <=> _owner == 0; - assert !lastReverted => _approved == approved; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rules: total supply can only change through mint and burn │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule supplyChange(env e) { - require nonzerosender(e); - requireInvariant zeroAddressHasNoApprovedOperator(e.msg.sender); - - mathint supplyBefore = _supply; - method f; helperSoundFnCall(e, f); - mathint supplyAfter = _supply; - - assert supplyAfter > supplyBefore => ( - supplyAfter == supplyBefore + 1 && - ( - f.selector == sig:mint(address,uint256).selector || - f.selector == sig:safeMint(address,uint256).selector || - f.selector == sig:safeMint(address,uint256,bytes).selector - ) - ); - assert supplyAfter < supplyBefore => ( - supplyAfter == supplyBefore - 1 && - f.selector == sig:burn(uint256).selector - ); -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rules: balanceOf can only change through mint, burn or transfers. balanceOf cannot change by more than 1. │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule balanceChange(env e, address account) { - requireInvariant balanceOfConsistency(account); - require balanceLimited(account); - - mathint balanceBefore = balanceOf(account); - method f; helperSoundFnCall(e, f); - mathint balanceAfter = balanceOf(account); - - // balance can change by at most 1 - assert balanceBefore != balanceAfter => ( - balanceAfter == balanceBefore - 1 || - balanceAfter == balanceBefore + 1 - ); - - // only selected function can change balances - assert balanceBefore != balanceAfter => ( - f.selector == sig:transferFrom(address,address,uint256).selector || - f.selector == sig:safeTransferFrom(address,address,uint256).selector || - f.selector == sig:safeTransferFrom(address,address,uint256,bytes).selector || - f.selector == sig:mint(address,uint256).selector || - f.selector == sig:safeMint(address,uint256).selector || - f.selector == sig:safeMint(address,uint256,bytes).selector || - f.selector == sig:burn(uint256).selector - ); -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rules: ownership can only change through mint, burn or transfers. │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule ownershipChange(env e, uint256 tokenId) { - require nonzerosender(e); - requireInvariant zeroAddressHasNoApprovedOperator(e.msg.sender); - - address ownerBefore = unsafeOwnerOf(tokenId); - method f; helperSoundFnCall(e, f); - address ownerAfter = unsafeOwnerOf(tokenId); - - assert ownerBefore == 0 && ownerAfter != 0 => ( - f.selector == sig:mint(address,uint256).selector || - f.selector == sig:safeMint(address,uint256).selector || - f.selector == sig:safeMint(address,uint256,bytes).selector - ); - - assert ownerBefore != 0 && ownerAfter == 0 => ( - f.selector == sig:burn(uint256).selector - ); - - assert (ownerBefore != ownerAfter && ownerBefore != 0 && ownerAfter != 0) => ( - f.selector == sig:transferFrom(address,address,uint256).selector || - f.selector == sig:safeTransferFrom(address,address,uint256).selector || - f.selector == sig:safeTransferFrom(address,address,uint256,bytes).selector - ); -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rules: token approval can only change through approve or transfers (implicitly). │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule approvalChange(env e, uint256 tokenId) { - address approvalBefore = unsafeGetApproved(tokenId); - method f; helperSoundFnCall(e, f); - address approvalAfter = unsafeGetApproved(tokenId); - - // approve can set any value, other functions reset - assert approvalBefore != approvalAfter => ( - f.selector == sig:approve(address,uint256).selector || - ( - ( - f.selector == sig:transferFrom(address,address,uint256).selector || - f.selector == sig:safeTransferFrom(address,address,uint256).selector || - f.selector == sig:safeTransferFrom(address,address,uint256,bytes).selector || - f.selector == sig:burn(uint256).selector - ) && approvalAfter == 0 - ) - ); -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rules: approval for all tokens can only change through isApprovedForAll. │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule approvedForAllChange(env e, address owner, address spender) { - bool approvedForAllBefore = isApprovedForAll(owner, spender); - method f; helperSoundFnCall(e, f); - bool approvedForAllAfter = isApprovedForAll(owner, spender); - - assert approvedForAllBefore != approvedForAllAfter => f.selector == sig:setApprovalForAll(address,bool).selector; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: transferFrom behavior and side effects │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule transferFrom(env e, address from, address to, uint256 tokenId) { - require nonpayable(e); - require authSanity(e); - - address operator = e.msg.sender; - uint256 otherTokenId; - address otherAccount; - - requireInvariant ownerHasBalance(tokenId); - require balanceLimited(to); - - uint256 balanceOfFromBefore = balanceOf(from); - uint256 balanceOfToBefore = balanceOf(to); - uint256 balanceOfOtherBefore = balanceOf(otherAccount); - address ownerBefore = unsafeOwnerOf(tokenId); - address otherOwnerBefore = unsafeOwnerOf(otherTokenId); - address approvalBefore = unsafeGetApproved(tokenId); - address otherApprovalBefore = unsafeGetApproved(otherTokenId); - - transferFrom@withrevert(e, from, to, tokenId); - bool success = !lastReverted; - - // liveness - assert success <=> ( - from == ownerBefore && - from != 0 && - to != 0 && - (operator == from || operator == approvalBefore || isApprovedForAll(ownerBefore, operator)) - ); - - // effect - assert success => ( - to_mathint(balanceOf(from)) == balanceOfFromBefore - assert_uint256(from != to ? 1 : 0) && - to_mathint(balanceOf(to)) == balanceOfToBefore + assert_uint256(from != to ? 1 : 0) && - unsafeOwnerOf(tokenId) == to && - unsafeGetApproved(tokenId) == 0 - ); - - // no side effect - assert balanceOf(otherAccount) != balanceOfOtherBefore => (otherAccount == from || otherAccount == to); - assert unsafeOwnerOf(otherTokenId) != otherOwnerBefore => otherTokenId == tokenId; - assert unsafeGetApproved(otherTokenId) != otherApprovalBefore => otherTokenId == tokenId; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: safeTransferFrom behavior and side effects │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule safeTransferFrom(env e, method f, address from, address to, uint256 tokenId) filtered { f -> - f.selector == sig:safeTransferFrom(address,address,uint256).selector || - f.selector == sig:safeTransferFrom(address,address,uint256,bytes).selector -} { - require nonpayable(e); - require authSanity(e); - - address operator = e.msg.sender; - uint256 otherTokenId; - address otherAccount; - - requireInvariant ownerHasBalance(tokenId); - require balanceLimited(to); - - uint256 balanceOfFromBefore = balanceOf(from); - uint256 balanceOfToBefore = balanceOf(to); - uint256 balanceOfOtherBefore = balanceOf(otherAccount); - address ownerBefore = unsafeOwnerOf(tokenId); - address otherOwnerBefore = unsafeOwnerOf(otherTokenId); - address approvalBefore = unsafeGetApproved(tokenId); - address otherApprovalBefore = unsafeGetApproved(otherTokenId); - - helperTransferWithRevert(e, f, from, to, tokenId); - bool success = !lastReverted; - - assert success <=> ( - from == ownerBefore && - from != 0 && - to != 0 && - (operator == from || operator == approvalBefore || isApprovedForAll(ownerBefore, operator)) - ); - - // effect - assert success => ( - to_mathint(balanceOf(from)) == balanceOfFromBefore - assert_uint256(from != to ? 1: 0) && - to_mathint(balanceOf(to)) == balanceOfToBefore + assert_uint256(from != to ? 1: 0) && - unsafeOwnerOf(tokenId) == to && - unsafeGetApproved(tokenId) == 0 - ); - - // no side effect - assert balanceOf(otherAccount) != balanceOfOtherBefore => (otherAccount == from || otherAccount == to); - assert unsafeOwnerOf(otherTokenId) != otherOwnerBefore => otherTokenId == tokenId; - assert unsafeGetApproved(otherTokenId) != otherApprovalBefore => otherTokenId == tokenId; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: mint behavior and side effects │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule mint(env e, address to, uint256 tokenId) { - require nonpayable(e); - requireInvariant notMintedUnset(tokenId); - - uint256 otherTokenId; - address otherAccount; - - require balanceLimited(to); - - mathint supplyBefore = _supply; - uint256 balanceOfToBefore = balanceOf(to); - uint256 balanceOfOtherBefore = balanceOf(otherAccount); - address ownerBefore = unsafeOwnerOf(tokenId); - address otherOwnerBefore = unsafeOwnerOf(otherTokenId); - - mint@withrevert(e, to, tokenId); - bool success = !lastReverted; - - // liveness - assert success <=> ( - ownerBefore == 0 && - to != 0 - ); - - // effect - assert success => ( - _supply == supplyBefore + 1 && - to_mathint(balanceOf(to)) == balanceOfToBefore + 1 && - unsafeOwnerOf(tokenId) == to - ); - - // no side effect - assert balanceOf(otherAccount) != balanceOfOtherBefore => otherAccount == to; - assert unsafeOwnerOf(otherTokenId) != otherOwnerBefore => otherTokenId == tokenId; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: safeMint behavior and side effects │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule safeMint(env e, method f, address to, uint256 tokenId) filtered { f -> - f.selector == sig:safeMint(address,uint256).selector || - f.selector == sig:safeMint(address,uint256,bytes).selector -} { - require nonpayable(e); - requireInvariant notMintedUnset(tokenId); - - uint256 otherTokenId; - address otherAccount; - - require balanceLimited(to); - - mathint supplyBefore = _supply; - uint256 balanceOfToBefore = balanceOf(to); - uint256 balanceOfOtherBefore = balanceOf(otherAccount); - address ownerBefore = unsafeOwnerOf(tokenId); - address otherOwnerBefore = unsafeOwnerOf(otherTokenId); - - helperMintWithRevert(e, f, to, tokenId); - bool success = !lastReverted; - - assert success <=> ( - ownerBefore == 0 && - to != 0 - ); - - // effect - assert success => ( - _supply == supplyBefore + 1 && - to_mathint(balanceOf(to)) == balanceOfToBefore + 1 && - unsafeOwnerOf(tokenId) == to - ); - - // no side effect - assert balanceOf(otherAccount) != balanceOfOtherBefore => otherAccount == to; - assert unsafeOwnerOf(otherTokenId) != otherOwnerBefore => otherTokenId == tokenId; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: burn behavior and side effects │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule burn(env e, uint256 tokenId) { - require nonpayable(e); - - address from = unsafeOwnerOf(tokenId); - uint256 otherTokenId; - address otherAccount; - - requireInvariant ownerHasBalance(tokenId); - - mathint supplyBefore = _supply; - uint256 balanceOfFromBefore = balanceOf(from); - uint256 balanceOfOtherBefore = balanceOf(otherAccount); - address ownerBefore = unsafeOwnerOf(tokenId); - address otherOwnerBefore = unsafeOwnerOf(otherTokenId); - address otherApprovalBefore = unsafeGetApproved(otherTokenId); - - burn@withrevert(e, tokenId); - bool success = !lastReverted; - - // liveness - assert success <=> ( - ownerBefore != 0 - ); - - // effect - assert success => ( - _supply == supplyBefore - 1 && - to_mathint(balanceOf(from)) == balanceOfFromBefore - 1 && - unsafeOwnerOf(tokenId) == 0 && - unsafeGetApproved(tokenId) == 0 - ); - - // no side effect - assert balanceOf(otherAccount) != balanceOfOtherBefore => otherAccount == from; - assert unsafeOwnerOf(otherTokenId) != otherOwnerBefore => otherTokenId == tokenId; - assert unsafeGetApproved(otherTokenId) != otherApprovalBefore => otherTokenId == tokenId; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: approve behavior and side effects │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule approve(env e, address spender, uint256 tokenId) { - require nonpayable(e); - require authSanity(e); - - address caller = e.msg.sender; - address owner = unsafeOwnerOf(tokenId); - uint256 otherTokenId; - - address otherApprovalBefore = unsafeGetApproved(otherTokenId); - - approve@withrevert(e, spender, tokenId); - bool success = !lastReverted; - - // liveness - assert success <=> ( - owner != 0 && - (owner == caller || isApprovedForAll(owner, caller)) - ); - - // effect - assert success => unsafeGetApproved(tokenId) == spender; - - // no side effect - assert unsafeGetApproved(otherTokenId) != otherApprovalBefore => otherTokenId == tokenId; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: setApprovalForAll behavior and side effects │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule setApprovalForAll(env e, address operator, bool approved) { - require nonpayable(e); - - address owner = e.msg.sender; - address otherOwner; - address otherOperator; - - bool otherIsApprovedForAllBefore = isApprovedForAll(otherOwner, otherOperator); - - setApprovalForAll@withrevert(e, operator, approved); - bool success = !lastReverted; - - // liveness - assert success <=> operator != 0; - - // effect - assert success => isApprovedForAll(owner, operator) == approved; - - // no side effect - assert isApprovedForAll(otherOwner, otherOperator) != otherIsApprovedForAllBefore => ( - otherOwner == owner && - otherOperator == operator - ); -} diff --git a/lib/openzeppelin-contracts/certora/specs/EnumerableMap.spec b/lib/openzeppelin-contracts/certora/specs/EnumerableMap.spec deleted file mode 100644 index 1801d99..0000000 --- a/lib/openzeppelin-contracts/certora/specs/EnumerableMap.spec +++ /dev/null @@ -1,333 +0,0 @@ -import "helpers/helpers.spec"; - -methods { - // library - function set(bytes32,bytes32) external returns (bool) envfree; - function remove(bytes32) external returns (bool) envfree; - function contains(bytes32) external returns (bool) envfree; - function length() external returns (uint256) envfree; - function key_at(uint256) external returns (bytes32) envfree; - function value_at(uint256) external returns (bytes32) envfree; - function tryGet_contains(bytes32) external returns (bool) envfree; - function tryGet_value(bytes32) external returns (bytes32) envfree; - function get(bytes32) external returns (bytes32) envfree; - - // FV - function _positionOf(bytes32) external returns (uint256) envfree; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Helpers │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -definition sanity() returns bool = - length() < max_uint256; - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariant: the value mapping is empty for keys that are not in the EnumerableMap. │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant noValueIfNotContained(bytes32 key) - !contains(key) => tryGet_value(key) == to_bytes32(0) - { - preserved set(bytes32 otherKey, bytes32 someValue) { - require sanity(); - } - } - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariant: All indexed keys are contained │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant indexedContained(uint256 index) - index < length() => contains(key_at(index)) - { - preserved { - requireInvariant consistencyIndex(index); - requireInvariant consistencyIndex(require_uint256(length() - 1)); - } - } - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariant: A value can only be stored at a single location │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant atUniqueness(uint256 index1, uint256 index2) - index1 == index2 <=> key_at(index1) == key_at(index2) - { - preserved remove(bytes32 key) { - requireInvariant atUniqueness(index1, require_uint256(length() - 1)); - requireInvariant atUniqueness(index2, require_uint256(length() - 1)); - } - } - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariant: index <> value relationship is consistent │ -│ │ -│ Note that the two consistencyXxx invariants, put together, prove that at_ and _positionOf are inverse of one │ -│ another. This proves that we have a bijection between indices (the enumerability part) and keys (the entries that │ -│ are set and removed from the EnumerableMap). │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant consistencyIndex(uint256 index) - index < length() => to_mathint(_positionOf(key_at(index))) == index + 1 - { - preserved remove(bytes32 key) { - requireInvariant consistencyIndex(require_uint256(length() - 1)); - } - } - -invariant consistencyKey(bytes32 key) - contains(key) => ( - _positionOf(key) > 0 && - _positionOf(key) <= length() && - key_at(require_uint256(_positionOf(key) - 1)) == key - ) - { - preserved remove(bytes32 otherKey) { - requireInvariant consistencyKey(otherKey); - requireInvariant atUniqueness( - require_uint256(_positionOf(key) - 1), - require_uint256(_positionOf(otherKey) - 1) - ); - } - } - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: state only changes by setting or removing elements │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule stateChange(env e, bytes32 key) { - require sanity(); - requireInvariant consistencyKey(key); - - uint256 lengthBefore = length(); - bool containsBefore = contains(key); - bytes32 valueBefore = tryGet_value(key); - - method f; - calldataarg args; - f(e, args); - - uint256 lengthAfter = length(); - bool containsAfter = contains(key); - bytes32 valueAfter = tryGet_value(key); - - assert lengthBefore != lengthAfter => ( - (f.selector == sig:set(bytes32,bytes32).selector && to_mathint(lengthAfter) == lengthBefore + 1) || - (f.selector == sig:remove(bytes32).selector && to_mathint(lengthAfter) == lengthBefore - 1) - ); - - assert containsBefore != containsAfter => ( - (f.selector == sig:set(bytes32,bytes32).selector && containsAfter) || - (f.selector == sig:remove(bytes32).selector && !containsAfter) - ); - - assert valueBefore != valueAfter => ( - (f.selector == sig:set(bytes32,bytes32).selector && containsAfter) || - (f.selector == sig:remove(bytes32).selector && !containsAfter && valueAfter == to_bytes32(0)) - ); -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: check liveness of view functions. │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule liveness_1(bytes32 key) { - requireInvariant consistencyKey(key); - - // contains never revert - bool contains = contains@withrevert(key); - assert !lastReverted; - - // tryGet never reverts (key) - tryGet_contains@withrevert(key); - assert !lastReverted; - - // tryGet never reverts (value) - tryGet_value@withrevert(key); - assert !lastReverted; - - // get reverts iff the key is not in the map - get@withrevert(key); - assert !lastReverted <=> contains; -} - -rule liveness_2(uint256 index) { - requireInvariant consistencyIndex(index); - - // length never revert - uint256 length = length@withrevert(); - assert !lastReverted; - - // key_at reverts iff the index is out of bound - key_at@withrevert(index); - assert !lastReverted <=> index < length; - - // value_at reverts iff the index is out of bound - value_at@withrevert(index); - assert !lastReverted <=> index < length; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: get and tryGet return the expected values. │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule getAndTryGet(bytes32 key) { - requireInvariant noValueIfNotContained(key); - - bool contained = contains(key); - bool tryContained = tryGet_contains(key); - bytes32 tryValue = tryGet_value(key); - bytes32 value = get@withrevert(key); // revert is not contained - - assert contained == tryContained; - assert contained => tryValue == value; - assert !contained => tryValue == to_bytes32(0); -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: set key-value in EnumerableMap │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule set(bytes32 key, bytes32 value, bytes32 otherKey) { - require sanity(); - - uint256 lengthBefore = length(); - bool containsBefore = contains(key); - bool containsOtherBefore = contains(otherKey); - bytes32 otherValueBefore = tryGet_value(otherKey); - - bool added = set@withrevert(key, value); - bool success = !lastReverted; - - assert success && contains(key) && get(key) == value, - "liveness & immediate effect"; - - assert added <=> !containsBefore, - "return value: added iff not contained"; - - assert to_mathint(length()) == lengthBefore + to_mathint(added ? 1 : 0), - "effect: length increases iff added"; - - assert added => (key_at(lengthBefore) == key && value_at(lengthBefore) == value), - "effect: add at the end"; - - assert containsOtherBefore != contains(otherKey) => (added && key == otherKey), - "side effect: other keys are not affected"; - - assert otherValueBefore != tryGet_value(otherKey) => key == otherKey, - "side effect: values attached to other keys are not affected"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: remove key from EnumerableMap │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule remove(bytes32 key, bytes32 otherKey) { - requireInvariant consistencyKey(key); - requireInvariant consistencyKey(otherKey); - - uint256 lengthBefore = length(); - bool containsBefore = contains(key); - bool containsOtherBefore = contains(otherKey); - bytes32 otherValueBefore = tryGet_value(otherKey); - - bool removed = remove@withrevert(key); - bool success = !lastReverted; - - assert success && !contains(key), - "liveness & immediate effect"; - - assert removed <=> containsBefore, - "return value: removed iff contained"; - - assert to_mathint(length()) == lengthBefore - to_mathint(removed ? 1 : 0), - "effect: length decreases iff removed"; - - assert containsOtherBefore != contains(otherKey) => (removed && key == otherKey), - "side effect: other keys are not affected"; - - assert otherValueBefore != tryGet_value(otherKey) => key == otherKey, - "side effect: values attached to other keys are not affected"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: when adding a new key, the other keys remain in set, at the same index. │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule setEnumerability(bytes32 key, bytes32 value, uint256 index) { - require sanity(); - - bytes32 atKeyBefore = key_at(index); - bytes32 atValueBefore = value_at(index); - - set(key, value); - - bytes32 atKeyAfter = key_at@withrevert(index); - assert !lastReverted; - - bytes32 atValueAfter = value_at@withrevert(index); - assert !lastReverted; - - assert atKeyAfter == atKeyBefore; - assert atValueAfter != atValueBefore => ( - key == atKeyBefore && - value == atValueAfter - ); -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: when removing a existing key, the other keys remain in set, at the same index (except for the last one). │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule removeEnumerability(bytes32 key, uint256 index) { - uint256 last = require_uint256(length() - 1); - - requireInvariant consistencyKey(key); - requireInvariant consistencyIndex(index); - requireInvariant consistencyIndex(last); - - bytes32 atKeyBefore = key_at(index); - bytes32 atValueBefore = value_at(index); - bytes32 lastKeyBefore = key_at(last); - bytes32 lastValueBefore = value_at(last); - - remove(key); - - // can't read last value & keys (length decreased) - bytes32 atKeyAfter = key_at@withrevert(index); - assert lastReverted <=> index == last; - - bytes32 atValueAfter = value_at@withrevert(index); - assert lastReverted <=> index == last; - - // One value that is allowed to change is if previous value was removed, - // in that case the last value before took its place. - assert ( - index != last && - atKeyBefore != atKeyAfter - ) => ( - atKeyBefore == key && - atKeyAfter == lastKeyBefore - ); - - assert ( - index != last && - atValueBefore != atValueAfter - ) => ( - atValueAfter == lastValueBefore - ); -} diff --git a/lib/openzeppelin-contracts/certora/specs/EnumerableSet.spec b/lib/openzeppelin-contracts/certora/specs/EnumerableSet.spec deleted file mode 100644 index 94d0a91..0000000 --- a/lib/openzeppelin-contracts/certora/specs/EnumerableSet.spec +++ /dev/null @@ -1,246 +0,0 @@ -import "helpers/helpers.spec"; - -methods { - // library - function add(bytes32) external returns (bool) envfree; - function remove(bytes32) external returns (bool) envfree; - function contains(bytes32) external returns (bool) envfree; - function length() external returns (uint256) envfree; - function at_(uint256) external returns (bytes32) envfree; - - // FV - function _positionOf(bytes32) external returns (uint256) envfree; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Helpers │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -definition sanity() returns bool = - length() < max_uint256; - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariant: All indexed keys are contained │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant indexedContained(uint256 index) - index < length() => contains(at_(index)) - { - preserved { - requireInvariant consistencyIndex(index); - requireInvariant consistencyIndex(require_uint256(length() - 1)); - } - } - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariant: A value can only be stored at a single location │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant atUniqueness(uint256 index1, uint256 index2) - index1 == index2 <=> at_(index1) == at_(index2) - { - preserved remove(bytes32 key) { - requireInvariant atUniqueness(index1, require_uint256(length() - 1)); - requireInvariant atUniqueness(index2, require_uint256(length() - 1)); - } - } - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariant: index <> key relationship is consistent │ -│ │ -│ Note that the two consistencyXxx invariants, put together, prove that at_ and _positionOf are inverse of one │ -│ another. This proves that we have a bijection between indices (the enumerability part) and keys (the entries that │ -│ are added and removed from the EnumerableSet). │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant consistencyIndex(uint256 index) - index < length() => _positionOf(at_(index)) == require_uint256(index + 1) - { - preserved remove(bytes32 key) { - requireInvariant consistencyIndex(require_uint256(length() - 1)); - } - } - -invariant consistencyKey(bytes32 key) - contains(key) => ( - _positionOf(key) > 0 && - _positionOf(key) <= length() && - at_(require_uint256(_positionOf(key) - 1)) == key - ) - { - preserved remove(bytes32 otherKey) { - requireInvariant consistencyKey(otherKey); - requireInvariant atUniqueness( - require_uint256(_positionOf(key) - 1), - require_uint256(_positionOf(otherKey) - 1) - ); - } - } - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: state only changes by adding or removing elements │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule stateChange(env e, bytes32 key) { - require sanity(); - requireInvariant consistencyKey(key); - - uint256 lengthBefore = length(); - bool containsBefore = contains(key); - - method f; - calldataarg args; - f(e, args); - - uint256 lengthAfter = length(); - bool containsAfter = contains(key); - - assert lengthBefore != lengthAfter => ( - (f.selector == sig:add(bytes32).selector && lengthAfter == require_uint256(lengthBefore + 1)) || - (f.selector == sig:remove(bytes32).selector && lengthAfter == require_uint256(lengthBefore - 1)) - ); - - assert containsBefore != containsAfter => ( - (f.selector == sig:add(bytes32).selector && containsAfter) || - (f.selector == sig:remove(bytes32).selector && containsBefore) - ); -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: check liveness of view functions. │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule liveness_1(bytes32 key) { - requireInvariant consistencyKey(key); - - // contains never revert - contains@withrevert(key); - assert !lastReverted; -} - -rule liveness_2(uint256 index) { - requireInvariant consistencyIndex(index); - - // length never revert - uint256 length = length@withrevert(); - assert !lastReverted; - - // at reverts iff the index is out of bound - at_@withrevert(index); - assert !lastReverted <=> index < length; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: add key to EnumerableSet if not already contained │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule add(bytes32 key, bytes32 otherKey) { - require sanity(); - - uint256 lengthBefore = length(); - bool containsBefore = contains(key); - bool containsOtherBefore = contains(otherKey); - - bool added = add@withrevert(key); - bool success = !lastReverted; - - assert success && contains(key), - "liveness & immediate effect"; - - assert added <=> !containsBefore, - "return value: added iff not contained"; - - assert length() == require_uint256(lengthBefore + to_mathint(added ? 1 : 0)), - "effect: length increases iff added"; - - assert added => at_(lengthBefore) == key, - "effect: add at the end"; - - assert containsOtherBefore != contains(otherKey) => (added && key == otherKey), - "side effect: other keys are not affected"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: remove key from EnumerableSet if already contained │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule remove(bytes32 key, bytes32 otherKey) { - requireInvariant consistencyKey(key); - requireInvariant consistencyKey(otherKey); - - uint256 lengthBefore = length(); - bool containsBefore = contains(key); - bool containsOtherBefore = contains(otherKey); - - bool removed = remove@withrevert(key); - bool success = !lastReverted; - - assert success && !contains(key), - "liveness & immediate effect"; - - assert removed <=> containsBefore, - "return value: removed iff contained"; - - assert length() == require_uint256(lengthBefore - to_mathint(removed ? 1 : 0)), - "effect: length decreases iff removed"; - - assert containsOtherBefore != contains(otherKey) => (removed && key == otherKey), - "side effect: other keys are not affected"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: when adding a new key, the other keys remain in set, at the same index. │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule addEnumerability(bytes32 key, uint256 index) { - require sanity(); - - bytes32 atBefore = at_(index); - add(key); - bytes32 atAfter = at_@withrevert(index); - bool atAfterSuccess = !lastReverted; - - assert atAfterSuccess; - assert atBefore == atAfter; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: when removing a existing key, the other keys remain in set, at the same index (except for the last one). │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule removeEnumerability(bytes32 key, uint256 index) { - uint256 last = require_uint256(length() - 1); - - requireInvariant consistencyKey(key); - requireInvariant consistencyIndex(index); - requireInvariant consistencyIndex(last); - - bytes32 atBefore = at_(index); - bytes32 lastBefore = at_(last); - - remove(key); - - // can't read last value (length decreased) - bytes32 atAfter = at_@withrevert(index); - assert lastReverted <=> index == last; - - // One value that is allowed to change is if previous value was removed, - // in that case the last value before took its place. - assert ( - index != last && - atBefore != atAfter - ) => ( - atBefore == key && - atAfter == lastBefore - ); -} diff --git a/lib/openzeppelin-contracts/certora/specs/Initializable.spec b/lib/openzeppelin-contracts/certora/specs/Initializable.spec deleted file mode 100644 index 07c2930..0000000 --- a/lib/openzeppelin-contracts/certora/specs/Initializable.spec +++ /dev/null @@ -1,165 +0,0 @@ -import "helpers/helpers.spec"; - -methods { - // initialize, reinitialize, disable - function initialize() external envfree; - function reinitialize(uint64) external envfree; - function disable() external envfree; - - function nested_init_init() external envfree; - function nested_init_reinit(uint64) external envfree; - function nested_reinit_init(uint64) external envfree; - function nested_reinit_reinit(uint64,uint64) external envfree; - - // view - function version() external returns uint64 envfree; - function initializing() external returns bool envfree; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Definitions │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -definition isUninitialized() returns bool = version() == 0; -definition isInitialized() returns bool = version() > 0; -definition isDisabled() returns bool = version() == max_uint64; - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariant: A contract must only ever be in an initializing state while in the middle of a transaction execution. │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant notInitializing() - !initializing(); - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: The version cannot decrease & disable state is irrevocable. │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule increasingVersion(env e) { - uint64 versionBefore = version(); - bool disabledBefore = isDisabled(); - - method f; calldataarg args; - f(e, args); - - assert versionBefore <= version(), "_initialized must only increase"; - assert disabledBefore => isDisabled(), "a disabled initializer must stay disabled"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: Cannot initialize a contract that is already initialized. │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule cannotInitializeTwice() { - require isInitialized(); - - initialize@withrevert(); - - assert lastReverted, "contract must only be initialized once"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: Cannot initialize once disabled. │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule cannotInitializeOnceDisabled() { - require isDisabled(); - - initialize@withrevert(); - - assert lastReverted, "contract is disabled"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: Cannot reinitialize once disabled. │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule cannotReinitializeOnceDisabled() { - require isDisabled(); - - uint64 n; - reinitialize@withrevert(n); - - assert lastReverted, "contract is disabled"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: Cannot nest initializers (after construction). │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule cannotNestInitializers_init_init() { - nested_init_init@withrevert(); - assert lastReverted, "nested initializers"; -} - -rule cannotNestInitializers_init_reinit(uint64 m) { - nested_init_reinit@withrevert(m); - assert lastReverted, "nested initializers"; -} - -rule cannotNestInitializers_reinit_init(uint64 n) { - nested_reinit_init@withrevert(n); - assert lastReverted, "nested initializers"; -} - -rule cannotNestInitializers_reinit_reinit(uint64 n, uint64 m) { - nested_reinit_reinit@withrevert(n, m); - assert lastReverted, "nested initializers"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: Initialize correctly sets the version. │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule initializeEffects() { - requireInvariant notInitializing(); - - bool isUninitializedBefore = isUninitialized(); - - initialize@withrevert(); - bool success = !lastReverted; - - assert success <=> isUninitializedBefore, "can only initialize uninitialized contracts"; - assert success => version() == 1, "initialize must set version() to 1"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: Reinitialize correctly sets the version. │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule reinitializeEffects() { - requireInvariant notInitializing(); - - uint64 versionBefore = version(); - - uint64 n; - reinitialize@withrevert(n); - bool success = !lastReverted; - - assert success <=> versionBefore < n, "can only reinitialize to a latter versions"; - assert success => version() == n, "reinitialize must set version() to n"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: Can disable. │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule disableEffect() { - requireInvariant notInitializing(); - - disable@withrevert(); - bool success = !lastReverted; - - assert success, "call to _disableInitializers failed"; - assert isDisabled(), "disable state not set"; -} diff --git a/lib/openzeppelin-contracts/certora/specs/Nonces.spec b/lib/openzeppelin-contracts/certora/specs/Nonces.spec deleted file mode 100644 index 4647c5c..0000000 --- a/lib/openzeppelin-contracts/certora/specs/Nonces.spec +++ /dev/null @@ -1,92 +0,0 @@ -import "helpers/helpers.spec"; - -methods { - function nonces(address) external returns (uint256) envfree; - function useNonce(address) external returns (uint256) envfree; - function useCheckedNonce(address,uint256) external envfree; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Helpers │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -function nonceSanity(address account) returns bool { - return nonces(account) < max_uint256; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Function correctness: useNonce uses nonce │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule useNonce(address account) { - require nonceSanity(account); - - address other; - - mathint nonceBefore = nonces(account); - mathint otherNonceBefore = nonces(other); - - mathint nonceUsed = useNonce@withrevert(account); - bool success = !lastReverted; - - mathint nonceAfter = nonces(account); - mathint otherNonceAfter = nonces(other); - - // liveness - assert success, "doesn't revert"; - - // effect - assert nonceAfter == nonceBefore + 1 && nonceBefore == nonceUsed, "nonce is used"; - - // no side effect - assert otherNonceBefore != otherNonceAfter => other == account, "no other nonce is used"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Function correctness: useCheckedNonce uses only the current nonce │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule useCheckedNonce(address account, uint256 currentNonce) { - require nonceSanity(account); - - address other; - - mathint nonceBefore = nonces(account); - mathint otherNonceBefore = nonces(other); - - useCheckedNonce@withrevert(account, currentNonce); - bool success = !lastReverted; - - mathint nonceAfter = nonces(account); - mathint otherNonceAfter = nonces(other); - - // liveness - assert success <=> to_mathint(currentNonce) == nonceBefore, "works iff current nonce is correct"; - - // effect - assert success => nonceAfter == nonceBefore + 1, "nonce is used"; - - // no side effect - assert otherNonceBefore != otherNonceAfter => other == account, "no other nonce is used"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: nonce only increments │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule nonceOnlyIncrements(address account) { - require nonceSanity(account); - - mathint nonceBefore = nonces(account); - - env e; method f; calldataarg args; - f(e, args); - - mathint nonceAfter = nonces(account); - - assert nonceAfter == nonceBefore || nonceAfter == nonceBefore + 1, "nonce only increments"; -} diff --git a/lib/openzeppelin-contracts/certora/specs/Ownable.spec b/lib/openzeppelin-contracts/certora/specs/Ownable.spec deleted file mode 100644 index 0d50813..0000000 --- a/lib/openzeppelin-contracts/certora/specs/Ownable.spec +++ /dev/null @@ -1,77 +0,0 @@ -import "helpers/helpers.spec"; -import "methods/IOwnable.spec"; - -methods { - function restricted() external; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Function correctness: transferOwnership changes ownership │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule transferOwnership(env e) { - require nonpayable(e); - - address newOwner; - address current = owner(); - - transferOwnership@withrevert(e, newOwner); - bool success = !lastReverted; - - assert success <=> (e.msg.sender == current && newOwner != 0), "unauthorized caller or invalid arg"; - assert success => owner() == newOwner, "current owner changed"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Function correctness: renounceOwnership removes the owner │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule renounceOwnership(env e) { - require nonpayable(e); - - address current = owner(); - - renounceOwnership@withrevert(e); - bool success = !lastReverted; - - assert success <=> e.msg.sender == current, "unauthorized caller"; - assert success => owner() == 0, "owner not cleared"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Access control: only current owner can call restricted functions │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule onlyCurrentOwnerCanCallOnlyOwner(env e) { - require nonpayable(e); - - address current = owner(); - - calldataarg args; - restricted@withrevert(e, args); - - assert !lastReverted <=> e.msg.sender == current, "access control failed"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: ownership can only change in specific ways │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule onlyOwnerOrPendingOwnerCanChangeOwnership(env e) { - address oldCurrent = owner(); - - method f; calldataarg args; - f(e, args); - - address newCurrent = owner(); - - // If owner changes, must be either transferOwnership or renounceOwnership - assert oldCurrent != newCurrent => ( - (e.msg.sender == oldCurrent && newCurrent != 0 && f.selector == sig:transferOwnership(address).selector) || - (e.msg.sender == oldCurrent && newCurrent == 0 && f.selector == sig:renounceOwnership().selector) - ); -} diff --git a/lib/openzeppelin-contracts/certora/specs/Ownable2Step.spec b/lib/openzeppelin-contracts/certora/specs/Ownable2Step.spec deleted file mode 100644 index d13c6d3..0000000 --- a/lib/openzeppelin-contracts/certora/specs/Ownable2Step.spec +++ /dev/null @@ -1,108 +0,0 @@ -import "helpers/helpers.spec"; -import "methods/IOwnable2Step.spec"; - -methods { - function restricted() external; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Function correctness: transferOwnership sets the pending owner │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule transferOwnership(env e) { - require nonpayable(e); - - address newOwner; - address current = owner(); - - transferOwnership@withrevert(e, newOwner); - bool success = !lastReverted; - - assert success <=> e.msg.sender == current, "unauthorized caller"; - assert success => pendingOwner() == newOwner, "pending owner not set"; - assert success => owner() == current, "current owner changed"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Function correctness: renounceOwnership removes the owner and the pendingOwner │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule renounceOwnership(env e) { - require nonpayable(e); - - address current = owner(); - - renounceOwnership@withrevert(e); - bool success = !lastReverted; - - assert success <=> e.msg.sender == current, "unauthorized caller"; - assert success => pendingOwner() == 0, "pending owner not cleared"; - assert success => owner() == 0, "owner not cleared"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Function correctness: acceptOwnership changes owner and reset pending owner │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule acceptOwnership(env e) { - - require nonpayable(e); - - address current = owner(); - address pending = pendingOwner(); - - acceptOwnership@withrevert(e); - bool success = !lastReverted; - - assert success <=> e.msg.sender == pending, "unauthorized caller"; - assert success => pendingOwner() == 0, "pending owner not cleared"; - assert success => owner() == pending, "owner not transferred"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Access control: only current owner can call restricted functions │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule onlyCurrentOwnerCanCallOnlyOwner(env e) { - require nonpayable(e); - - address current = owner(); - - calldataarg args; - restricted@withrevert(e, args); - - assert !lastReverted <=> e.msg.sender == current, "access control failed"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: ownership and pending ownership can only change in specific ways │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule ownerOrPendingOwnerChange(env e, method f) { - address oldCurrent = owner(); - address oldPending = pendingOwner(); - - calldataarg args; - f(e, args); - - address newCurrent = owner(); - address newPending = pendingOwner(); - - // If owner changes, must be either acceptOwnership or renounceOwnership - assert oldCurrent != newCurrent => ( - (e.msg.sender == oldPending && newCurrent == oldPending && newPending == 0 && f.selector == sig:acceptOwnership().selector) || - (e.msg.sender == oldCurrent && newCurrent == 0 && newPending == 0 && f.selector == sig:renounceOwnership().selector) - ); - - // If pending changes, must be either acceptance or reset - assert oldPending != newPending => ( - (e.msg.sender == oldCurrent && newCurrent == oldCurrent && f.selector == sig:transferOwnership(address).selector) || - (e.msg.sender == oldPending && newCurrent == oldPending && newPending == 0 && f.selector == sig:acceptOwnership().selector) || - (e.msg.sender == oldCurrent && newCurrent == 0 && newPending == 0 && f.selector == sig:renounceOwnership().selector) - ); -} diff --git a/lib/openzeppelin-contracts/certora/specs/Pausable.spec b/lib/openzeppelin-contracts/certora/specs/Pausable.spec deleted file mode 100644 index a7aff9c..0000000 --- a/lib/openzeppelin-contracts/certora/specs/Pausable.spec +++ /dev/null @@ -1,96 +0,0 @@ -import "helpers/helpers.spec"; - -methods { - function paused() external returns (bool) envfree; - function pause() external; - function unpause() external; - function onlyWhenPaused() external; - function onlyWhenNotPaused() external; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Function correctness: _pause pauses the contract │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule pause(env e) { - require nonpayable(e); - - bool pausedBefore = paused(); - - pause@withrevert(e); - bool success = !lastReverted; - - bool pausedAfter = paused(); - - // liveness - assert success <=> !pausedBefore, "works if and only if the contract was not paused before"; - - // effect - assert success => pausedAfter, "contract must be paused after a successful call"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Function correctness: _unpause unpauses the contract │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule unpause(env e) { - require nonpayable(e); - - bool pausedBefore = paused(); - - unpause@withrevert(e); - bool success = !lastReverted; - - bool pausedAfter = paused(); - - // liveness - assert success <=> pausedBefore, "works if and only if the contract was paused before"; - - // effect - assert success => !pausedAfter, "contract must be unpaused after a successful call"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Function correctness: whenPaused modifier can only be called if the contract is paused │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule whenPaused(env e) { - require nonpayable(e); - - onlyWhenPaused@withrevert(e); - assert !lastReverted <=> paused(), "works if and only if the contract is paused"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Function correctness: whenNotPaused modifier can only be called if the contract is not paused │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule whenNotPaused(env e) { - require nonpayable(e); - - onlyWhenNotPaused@withrevert(e); - assert !lastReverted <=> !paused(), "works if and only if the contract is not paused"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rules: only _pause and _unpause can change paused status │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule noPauseChange(env e) { - method f; - calldataarg args; - - bool pausedBefore = paused(); - f(e, args); - bool pausedAfter = paused(); - - assert pausedBefore != pausedAfter => ( - (!pausedAfter && f.selector == sig:unpause().selector) || - (pausedAfter && f.selector == sig:pause().selector) - ), "contract's paused status can only be changed by _pause() or _unpause()"; -} diff --git a/lib/openzeppelin-contracts/certora/specs/TimelockController.spec b/lib/openzeppelin-contracts/certora/specs/TimelockController.spec deleted file mode 100644 index 5123768..0000000 --- a/lib/openzeppelin-contracts/certora/specs/TimelockController.spec +++ /dev/null @@ -1,274 +0,0 @@ -import "helpers/helpers.spec"; -import "methods/IAccessControl.spec"; - -methods { - function PROPOSER_ROLE() external returns (bytes32) envfree; - function EXECUTOR_ROLE() external returns (bytes32) envfree; - function CANCELLER_ROLE() external returns (bytes32) envfree; - function isOperation(bytes32) external returns (bool); - function isOperationPending(bytes32) external returns (bool); - function isOperationReady(bytes32) external returns (bool); - function isOperationDone(bytes32) external returns (bool); - function getTimestamp(bytes32) external returns (uint256) envfree; - function getMinDelay() external returns (uint256) envfree; - - function hashOperation(address, uint256, bytes, bytes32, bytes32) external returns(bytes32) envfree; - function hashOperationBatch(address[], uint256[], bytes[], bytes32, bytes32) external returns(bytes32) envfree; - - function schedule(address, uint256, bytes, bytes32, bytes32, uint256) external; - function scheduleBatch(address[], uint256[], bytes[], bytes32, bytes32, uint256) external; - function execute(address, uint256, bytes, bytes32, bytes32) external; - function executeBatch(address[], uint256[], bytes[], bytes32, bytes32) external; - function cancel(bytes32) external; - - function updateDelay(uint256) external; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Helpers │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -// Uniformly handle scheduling of batched and non-batched operations. -function helperScheduleWithRevert(env e, method f, bytes32 id, uint256 delay) { - if (f.selector == sig:schedule(address, uint256, bytes, bytes32, bytes32, uint256).selector) { - address target; uint256 value; bytes data; bytes32 predecessor; bytes32 salt; - require hashOperation(target, value, data, predecessor, salt) == id; // Correlation - schedule@withrevert(e, target, value, data, predecessor, salt, delay); - } else if (f.selector == sig:scheduleBatch(address[], uint256[], bytes[], bytes32, bytes32, uint256).selector) { - address[] targets; uint256[] values; bytes[] payloads; bytes32 predecessor; bytes32 salt; - require hashOperationBatch(targets, values, payloads, predecessor, salt) == id; // Correlation - scheduleBatch@withrevert(e, targets, values, payloads, predecessor, salt, delay); - } else { - calldataarg args; - f@withrevert(e, args); - } -} - -// Uniformly handle execution of batched and non-batched operations. -function helperExecuteWithRevert(env e, method f, bytes32 id, bytes32 predecessor) { - if (f.selector == sig:execute(address, uint256, bytes, bytes32, bytes32).selector) { - address target; uint256 value; bytes data; bytes32 salt; - require hashOperation(target, value, data, predecessor, salt) == id; // Correlation - execute@withrevert(e, target, value, data, predecessor, salt); - } else if (f.selector == sig:executeBatch(address[], uint256[], bytes[], bytes32, bytes32).selector) { - address[] targets; uint256[] values; bytes[] payloads; bytes32 salt; - require hashOperationBatch(targets, values, payloads, predecessor, salt) == id; // Correlation - executeBatch@withrevert(e, targets, values, payloads, predecessor, salt); - } else { - calldataarg args; - f@withrevert(e, args); - } -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Definitions │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -definition DONE_TIMESTAMP() returns uint256 = 1; -definition UNSET() returns uint8 = 0x1; -definition PENDING() returns uint8 = 0x2; -definition DONE() returns uint8 = 0x4; - -definition isUnset(env e, bytes32 id) returns bool = !isOperation(e, id); -definition isPending(env e, bytes32 id) returns bool = isOperationPending(e, id); -definition isDone(env e, bytes32 id) returns bool = isOperationDone(e, id); -definition state(env e, bytes32 id) returns uint8 = (isUnset(e, id) ? UNSET() : 0) | (isPending(e, id) ? PENDING() : 0) | (isDone(e, id) ? DONE() : 0); - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariants: consistency of accessors │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant isOperationCheck(env e, bytes32 id) - isOperation(e, id) <=> getTimestamp(id) > 0 - filtered { f -> !f.isView } - -invariant isOperationPendingCheck(env e, bytes32 id) - isOperationPending(e, id) <=> getTimestamp(id) > DONE_TIMESTAMP() - filtered { f -> !f.isView } - -invariant isOperationDoneCheck(env e, bytes32 id) - isOperationDone(e, id) <=> getTimestamp(id) == DONE_TIMESTAMP() - filtered { f -> !f.isView } - -invariant isOperationReadyCheck(env e, bytes32 id) - isOperationReady(e, id) <=> (isOperationPending(e, id) && getTimestamp(id) <= e.block.timestamp) - filtered { f -> !f.isView } - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Invariant: a proposal id is either unset, pending or done │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -invariant stateConsistency(bytes32 id, env e) - // Check states are mutually exclusive - (isUnset(e, id) <=> (!isPending(e, id) && !isDone(e, id) )) && - (isPending(e, id) <=> (!isUnset(e, id) && !isDone(e, id) )) && - (isDone(e, id) <=> (!isUnset(e, id) && !isPending(e, id))) && - // Check that the state helper behaves as expected: - (isUnset(e, id) <=> state(e, id) == UNSET() ) && - (isPending(e, id) <=> state(e, id) == PENDING() ) && - (isDone(e, id) <=> state(e, id) == DONE() ) && - // Check substate - isOperationReady(e, id) => isPending(e, id) - filtered { f -> !f.isView } - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: state transition rules │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule stateTransition(bytes32 id, env e, method f, calldataarg args) { - require e.block.timestamp > 1; // Sanity - - uint8 stateBefore = state(e, id); - f(e, args); - uint8 stateAfter = state(e, id); - - // Cannot jump from UNSET to DONE - assert stateBefore == UNSET() => stateAfter != DONE(); - - // UNSET → PENDING: schedule or scheduleBatch - assert stateBefore == UNSET() && stateAfter == PENDING() => ( - f.selector == sig:schedule(address, uint256, bytes, bytes32, bytes32, uint256).selector || - f.selector == sig:scheduleBatch(address[], uint256[], bytes[], bytes32, bytes32, uint256).selector - ); - - // PENDING → UNSET: cancel - assert stateBefore == PENDING() && stateAfter == UNSET() => ( - f.selector == sig:cancel(bytes32).selector - ); - - // PENDING → DONE: execute or executeBatch - assert stateBefore == PENDING() && stateAfter == DONE() => ( - f.selector == sig:execute(address, uint256, bytes, bytes32, bytes32).selector || - f.selector == sig:executeBatch(address[], uint256[], bytes[], bytes32, bytes32).selector - ); - - // DONE is final - assert stateBefore == DONE() => stateAfter == DONE(); -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: minimum delay can only be updated through a timelock execution │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule minDelayOnlyChange(env e) { - uint256 delayBefore = getMinDelay(); - - method f; calldataarg args; - f(e, args); - - assert delayBefore != getMinDelay() => (e.msg.sender == currentContract && f.selector == sig:updateDelay(uint256).selector), "Unauthorized delay update"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: schedule liveness and effects │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule schedule(env e, method f, bytes32 id, uint256 delay) filtered { f -> - f.selector == sig:schedule(address, uint256, bytes, bytes32, bytes32, uint256).selector || - f.selector == sig:scheduleBatch(address[], uint256[], bytes[], bytes32, bytes32, uint256).selector -} { - require nonpayable(e); - - // Basic timestamp assumptions - require e.block.timestamp > 1; - require e.block.timestamp + delay < max_uint256; - require e.block.timestamp + getMinDelay() < max_uint256; - - bytes32 otherId; uint256 otherTimestamp = getTimestamp(otherId); - - uint8 stateBefore = state(e, id); - bool isDelaySufficient = delay >= getMinDelay(); - bool isProposerBefore = hasRole(PROPOSER_ROLE(), e.msg.sender); - - helperScheduleWithRevert(e, f, id, delay); - bool success = !lastReverted; - - // liveness - assert success <=> ( - stateBefore == UNSET() && - isDelaySufficient && - isProposerBefore - ); - - // effect - assert success => state(e, id) == PENDING(), "State transition violation"; - assert success => getTimestamp(id) == require_uint256(e.block.timestamp + delay), "Proposal timestamp not correctly set"; - - // no side effect - assert otherTimestamp != getTimestamp(otherId) => id == otherId, "Other proposal affected"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: execute liveness and effects │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule execute(env e, method f, bytes32 id, bytes32 predecessor) filtered { f -> - f.selector == sig:execute(address, uint256, bytes, bytes32, bytes32).selector || - f.selector == sig:executeBatch(address[], uint256[], bytes[], bytes32, bytes32).selector -} { - bytes32 otherId; uint256 otherTimestamp = getTimestamp(otherId); - - uint8 stateBefore = state(e, id); - bool isOperationReadyBefore = isOperationReady(e, id); - bool isExecutorOrOpen = hasRole(EXECUTOR_ROLE(), e.msg.sender) || hasRole(EXECUTOR_ROLE(), 0); - bool predecessorDependency = predecessor == to_bytes32(0) || isDone(e, predecessor); - - helperExecuteWithRevert(e, f, id, predecessor); - bool success = !lastReverted; - - // The underlying transaction can revert, and that would cause the execution to revert. We can check that all non - // reverting calls meet the requirements in terms of proposal readiness, access control and predecessor dependency. - // We can't however guarantee that these requirements being meet ensure liveness of the proposal, because the - // proposal can revert for reasons beyond our control. - - // liveness, should be `<=>` but can only check `=>` (see comment above) - assert success => ( - stateBefore == PENDING() && - isOperationReadyBefore && - predecessorDependency && - isExecutorOrOpen - ); - - // effect - assert success => state(e, id) == DONE(), "State transition violation"; - - // no side effect - assert otherTimestamp != getTimestamp(otherId) => id == otherId, "Other proposal affected"; -} - -/* -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Rule: cancel liveness and effects │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -*/ -rule cancel(env e, bytes32 id) { - require nonpayable(e); - - bytes32 otherId; uint256 otherTimestamp = getTimestamp(otherId); - - uint8 stateBefore = state(e, id); - bool isCanceller = hasRole(CANCELLER_ROLE(), e.msg.sender); - - cancel@withrevert(e, id); - bool success = !lastReverted; - - // liveness - assert success <=> ( - stateBefore == PENDING() && - isCanceller - ); - - // effect - assert success => state(e, id) == UNSET(), "State transition violation"; - - // no side effect - assert otherTimestamp != getTimestamp(otherId) => id == otherId, "Other proposal affected"; -} diff --git a/lib/openzeppelin-contracts/certora/specs/helpers/helpers.spec b/lib/openzeppelin-contracts/certora/specs/helpers/helpers.spec deleted file mode 100644 index 7125ce2..0000000 --- a/lib/openzeppelin-contracts/certora/specs/helpers/helpers.spec +++ /dev/null @@ -1,12 +0,0 @@ -// environment -definition nonpayable(env e) returns bool = e.msg.value == 0; -definition nonzerosender(env e) returns bool = e.msg.sender != 0; -definition sanity(env e) returns bool = clock(e) > 0 && clock(e) <= max_uint48; - -// math -definition min(mathint a, mathint b) returns mathint = a < b ? a : b; -definition max(mathint a, mathint b) returns mathint = a > b ? a : b; - -// time -definition clock(env e) returns mathint = to_mathint(e.block.timestamp); -definition isSetAndPast(env e, uint48 timepoint) returns bool = timepoint != 0 && to_mathint(timepoint) <= clock(e); diff --git a/lib/openzeppelin-contracts/certora/specs/methods/IAccessControl.spec b/lib/openzeppelin-contracts/certora/specs/methods/IAccessControl.spec deleted file mode 100644 index 5c395b0..0000000 --- a/lib/openzeppelin-contracts/certora/specs/methods/IAccessControl.spec +++ /dev/null @@ -1,8 +0,0 @@ -methods { - function DEFAULT_ADMIN_ROLE() external returns (bytes32) envfree; - function hasRole(bytes32, address) external returns(bool) envfree; - function getRoleAdmin(bytes32) external returns(bytes32) envfree; - function grantRole(bytes32, address) external; - function revokeRole(bytes32, address) external; - function renounceRole(bytes32, address) external; -} diff --git a/lib/openzeppelin-contracts/certora/specs/methods/IAccessControlDefaultAdminRules.spec b/lib/openzeppelin-contracts/certora/specs/methods/IAccessControlDefaultAdminRules.spec deleted file mode 100644 index d02db18..0000000 --- a/lib/openzeppelin-contracts/certora/specs/methods/IAccessControlDefaultAdminRules.spec +++ /dev/null @@ -1,36 +0,0 @@ -import "./IERC5313.spec"; - -methods { - // === View == - - // Default Admin - function defaultAdmin() external returns(address) envfree; - function pendingDefaultAdmin() external returns(address, uint48) envfree; - - // Default Admin Delay - function defaultAdminDelay() external returns(uint48); - function pendingDefaultAdminDelay() external returns(uint48, uint48); - function defaultAdminDelayIncreaseWait() external returns(uint48) envfree; - - // === Mutations == - - // Default Admin - function beginDefaultAdminTransfer(address) external; - function cancelDefaultAdminTransfer() external; - function acceptDefaultAdminTransfer() external; - - // Default Admin Delay - function changeDefaultAdminDelay(uint48) external; - function rollbackDefaultAdminDelay() external; - - // == FV == - - // Default Admin - function pendingDefaultAdmin_() external returns (address) envfree; - function pendingDefaultAdminSchedule_() external returns (uint48) envfree; - - // Default Admin Delay - function pendingDelay_() external returns (uint48); - function pendingDelaySchedule_() external returns (uint48); - function delayChangeWait_(uint48) external returns (uint48); -} diff --git a/lib/openzeppelin-contracts/certora/specs/methods/IAccessManaged.spec b/lib/openzeppelin-contracts/certora/specs/methods/IAccessManaged.spec deleted file mode 100644 index 886d917..0000000 --- a/lib/openzeppelin-contracts/certora/specs/methods/IAccessManaged.spec +++ /dev/null @@ -1,5 +0,0 @@ -methods { - function authority() external returns (address) envfree; - function isConsumingScheduledOp() external returns (bytes4) envfree; - function setAuthority(address) external; -} diff --git a/lib/openzeppelin-contracts/certora/specs/methods/IAccessManager.spec b/lib/openzeppelin-contracts/certora/specs/methods/IAccessManager.spec deleted file mode 100644 index 5d305f7..0000000 --- a/lib/openzeppelin-contracts/certora/specs/methods/IAccessManager.spec +++ /dev/null @@ -1,33 +0,0 @@ -methods { - function ADMIN_ROLE() external returns (uint64) envfree; - function PUBLIC_ROLE() external returns (uint64) envfree; - function canCall(address,address,bytes4) external returns (bool,uint32); - function expiration() external returns (uint32) envfree; - function minSetback() external returns (uint32) envfree; - function isTargetClosed(address) external returns (bool) envfree; - function getTargetFunctionRole(address,bytes4) external returns (uint64) envfree; - function getTargetAdminDelay(address) external returns (uint32); - function getRoleAdmin(uint64) external returns (uint64) envfree; - function getRoleGuardian(uint64) external returns (uint64) envfree; - function getRoleGrantDelay(uint64) external returns (uint32); - function getAccess(uint64,address) external returns (uint48,uint32,uint32,uint48); - function hasRole(uint64,address) external returns (bool,uint32); - function labelRole(uint64,string) external; - function grantRole(uint64,address,uint32) external; - function revokeRole(uint64,address) external; - function renounceRole(uint64,address) external; - function setRoleAdmin(uint64,uint64) external; - function setRoleGuardian(uint64,uint64) external; - function setGrantDelay(uint64,uint32) external; - function setTargetFunctionRole(address,bytes4[],uint64) external; - function setTargetAdminDelay(address,uint32) external; - function setTargetClosed(address,bool) external; - function hashOperation(address,address,bytes) external returns (bytes32) envfree; - function getNonce(bytes32) external returns (uint32) envfree; - function getSchedule(bytes32) external returns (uint48); - function schedule(address,bytes,uint48) external returns (bytes32,uint32); - function execute(address,bytes) external returns (uint32); - function cancel(address,address,bytes) external returns (uint32); - function consumeScheduledOp(address,bytes) external; - function updateAuthority(address,address) external; -} diff --git a/lib/openzeppelin-contracts/certora/specs/methods/IERC20.spec b/lib/openzeppelin-contracts/certora/specs/methods/IERC20.spec deleted file mode 100644 index 100901a..0000000 --- a/lib/openzeppelin-contracts/certora/specs/methods/IERC20.spec +++ /dev/null @@ -1,11 +0,0 @@ -methods { - function name() external returns (string) envfree; - function symbol() external returns (string) envfree; - function decimals() external returns (uint8) envfree; - function totalSupply() external returns (uint256) envfree; - function balanceOf(address) external returns (uint256) envfree; - function allowance(address,address) external returns (uint256) envfree; - function approve(address,uint256) external returns (bool); - function transfer(address,uint256) external returns (bool); - function transferFrom(address,address,uint256) external returns (bool); -} diff --git a/lib/openzeppelin-contracts/certora/specs/methods/IERC2612.spec b/lib/openzeppelin-contracts/certora/specs/methods/IERC2612.spec deleted file mode 100644 index 4ecc17b..0000000 --- a/lib/openzeppelin-contracts/certora/specs/methods/IERC2612.spec +++ /dev/null @@ -1,5 +0,0 @@ -methods { - function permit(address,address,uint256,uint256,uint8,bytes32,bytes32) external; - function nonces(address) external returns (uint256) envfree; - function DOMAIN_SEPARATOR() external returns (bytes32) envfree; -} diff --git a/lib/openzeppelin-contracts/certora/specs/methods/IERC3156FlashBorrower.spec b/lib/openzeppelin-contracts/certora/specs/methods/IERC3156FlashBorrower.spec deleted file mode 100644 index 733c168..0000000 --- a/lib/openzeppelin-contracts/certora/specs/methods/IERC3156FlashBorrower.spec +++ /dev/null @@ -1,3 +0,0 @@ -methods { - function _.onFlashLoan(address,address,uint256,uint256,bytes) external => DISPATCHER(true); -} diff --git a/lib/openzeppelin-contracts/certora/specs/methods/IERC3156FlashLender.spec b/lib/openzeppelin-contracts/certora/specs/methods/IERC3156FlashLender.spec deleted file mode 100644 index 66ed14c..0000000 --- a/lib/openzeppelin-contracts/certora/specs/methods/IERC3156FlashLender.spec +++ /dev/null @@ -1,5 +0,0 @@ -methods { - function maxFlashLoan(address) external returns (uint256) envfree; - function flashFee(address,uint256) external returns (uint256) envfree; - function flashLoan(address,address,uint256,bytes) external returns (bool); -} diff --git a/lib/openzeppelin-contracts/certora/specs/methods/IERC5313.spec b/lib/openzeppelin-contracts/certora/specs/methods/IERC5313.spec deleted file mode 100644 index f1d469f..0000000 --- a/lib/openzeppelin-contracts/certora/specs/methods/IERC5313.spec +++ /dev/null @@ -1,3 +0,0 @@ -methods { - function owner() external returns (address) envfree; -} diff --git a/lib/openzeppelin-contracts/certora/specs/methods/IERC721.spec b/lib/openzeppelin-contracts/certora/specs/methods/IERC721.spec deleted file mode 100644 index 34ff50b..0000000 --- a/lib/openzeppelin-contracts/certora/specs/methods/IERC721.spec +++ /dev/null @@ -1,17 +0,0 @@ -methods { - // IERC721 - function balanceOf(address) external returns (uint256) envfree; - function ownerOf(uint256) external returns (address) envfree; - function getApproved(uint256) external returns (address) envfree; - function isApprovedForAll(address,address) external returns (bool) envfree; - function safeTransferFrom(address,address,uint256,bytes) external; - function safeTransferFrom(address,address,uint256) external; - function transferFrom(address,address,uint256) external; - function approve(address,uint256) external; - function setApprovalForAll(address,bool) external; - - // IERC721Metadata - function name() external returns (string); - function symbol() external returns (string); - function tokenURI(uint256) external returns (string); -} diff --git a/lib/openzeppelin-contracts/certora/specs/methods/IERC721Receiver.spec b/lib/openzeppelin-contracts/certora/specs/methods/IERC721Receiver.spec deleted file mode 100644 index e6bdf42..0000000 --- a/lib/openzeppelin-contracts/certora/specs/methods/IERC721Receiver.spec +++ /dev/null @@ -1,3 +0,0 @@ -methods { - function _.onERC721Received(address,address,uint256,bytes) external => DISPATCHER(true); -} diff --git a/lib/openzeppelin-contracts/certora/specs/methods/IOwnable.spec b/lib/openzeppelin-contracts/certora/specs/methods/IOwnable.spec deleted file mode 100644 index 4d7c925..0000000 --- a/lib/openzeppelin-contracts/certora/specs/methods/IOwnable.spec +++ /dev/null @@ -1,5 +0,0 @@ -methods { - function owner() external returns (address) envfree; - function transferOwnership(address) external; - function renounceOwnership() external; -} diff --git a/lib/openzeppelin-contracts/certora/specs/methods/IOwnable2Step.spec b/lib/openzeppelin-contracts/certora/specs/methods/IOwnable2Step.spec deleted file mode 100644 index e6a9957..0000000 --- a/lib/openzeppelin-contracts/certora/specs/methods/IOwnable2Step.spec +++ /dev/null @@ -1,7 +0,0 @@ -methods { - function owner() external returns (address) envfree; - function pendingOwner() external returns (address) envfree; - function transferOwnership(address) external; - function acceptOwnership() external; - function renounceOwnership() external; -} diff --git a/lib/openzeppelin-contracts/contracts/access/AccessControl.sol b/lib/openzeppelin-contracts/contracts/access/AccessControl.sol deleted file mode 100644 index 3e3341e..0000000 --- a/lib/openzeppelin-contracts/contracts/access/AccessControl.sol +++ /dev/null @@ -1,209 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol) - -pragma solidity ^0.8.20; - -import {IAccessControl} from "./IAccessControl.sol"; -import {Context} from "../utils/Context.sol"; -import {ERC165} from "../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: - * - * ```solidity - * 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}: - * - * ```solidity - * 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. We recommend using {AccessControlDefaultAdminRules} - * to enforce additional security measures for this role. - */ -abstract contract AccessControl is Context, IAccessControl, ERC165 { - struct RoleData { - mapping(address account => bool) hasRole; - bytes32 adminRole; - } - - mapping(bytes32 role => RoleData) private _roles; - - bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; - - /** - * @dev Modifier that checks that an account has a specific role. Reverts - * with an {AccessControlUnauthorizedAccount} error including the required role. - */ - 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 returns (bool) { - return _roles[role].hasRole[account]; - } - - /** - * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()` - * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier. - */ - function _checkRole(bytes32 role) internal view virtual { - _checkRole(role, _msgSender()); - } - - /** - * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account` - * is missing `role`. - */ - function _checkRole(bytes32 role, address account) internal view virtual { - if (!hasRole(role, account)) { - revert AccessControlUnauthorizedAccount(account, role); - } - } - - /** - * @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 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 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 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 `callerConfirmation`. - * - * May emit a {RoleRevoked} event. - */ - function renounceRole(bytes32 role, address callerConfirmation) public virtual { - if (callerConfirmation != _msgSender()) { - revert AccessControlBadConfirmation(); - } - - _revokeRole(role, callerConfirmation); - } - - /** - * @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 Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted. - * - * Internal function without access restriction. - * - * May emit a {RoleGranted} event. - */ - function _grantRole(bytes32 role, address account) internal virtual returns (bool) { - if (!hasRole(role, account)) { - _roles[role].hasRole[account] = true; - emit RoleGranted(role, account, _msgSender()); - return true; - } else { - return false; - } - } - - /** - * @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked. - * - * Internal function without access restriction. - * - * May emit a {RoleRevoked} event. - */ - function _revokeRole(bytes32 role, address account) internal virtual returns (bool) { - if (hasRole(role, account)) { - _roles[role].hasRole[account] = false; - emit RoleRevoked(role, account, _msgSender()); - return true; - } else { - return false; - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/access/IAccessControl.sol b/lib/openzeppelin-contracts/contracts/access/IAccessControl.sol deleted file mode 100644 index 67ea537..0000000 --- a/lib/openzeppelin-contracts/contracts/access/IAccessControl.sol +++ /dev/null @@ -1,98 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (access/IAccessControl.sol) - -pragma solidity ^0.8.20; - -/** - * @dev External interface of AccessControl declared to support ERC-165 detection. - */ -interface IAccessControl { - /** - * @dev The `account` is missing a role. - */ - error AccessControlUnauthorizedAccount(address account, bytes32 neededRole); - - /** - * @dev The caller of a function is not the expected one. - * - * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}. - */ - error AccessControlBadConfirmation(); - - /** - * @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. - */ - 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. This account bears the admin role (for the granted role). - * Expected in cases where the role was granted using the internal {AccessControl-_grantRole}. - */ - 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 `callerConfirmation`. - */ - function renounceRole(bytes32 role, address callerConfirmation) external; -} diff --git a/lib/openzeppelin-contracts/contracts/access/Ownable.sol b/lib/openzeppelin-contracts/contracts/access/Ownable.sol deleted file mode 100644 index bd96f66..0000000 --- a/lib/openzeppelin-contracts/contracts/access/Ownable.sol +++ /dev/null @@ -1,100 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) - -pragma solidity ^0.8.20; - -import {Context} from "../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. - * - * The initial owner is set to the address provided by the deployer. 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; - - /** - * @dev The caller account is not authorized to perform an operation. - */ - error OwnableUnauthorizedAccount(address account); - - /** - * @dev The owner is not a valid owner account. (eg. `address(0)`) - */ - error OwnableInvalidOwner(address owner); - - event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); - - /** - * @dev Initializes the contract setting the address provided by the deployer as the initial owner. - */ - constructor(address initialOwner) { - if (initialOwner == address(0)) { - revert OwnableInvalidOwner(address(0)); - } - _transferOwnership(initialOwner); - } - - /** - * @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 { - if (owner() != _msgSender()) { - revert OwnableUnauthorizedAccount(_msgSender()); - } - } - - /** - * @dev Leaves the contract without owner. It will not be possible to call - * `onlyOwner` functions. Can only be called by the current owner. - * - * NOTE: Renouncing ownership will leave the contract without an owner, - * thereby disabling 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 { - if (newOwner == address(0)) { - revert OwnableInvalidOwner(address(0)); - } - _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/openzeppelin-contracts/contracts/access/Ownable2Step.sol b/lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol deleted file mode 100644 index 46765c4..0000000 --- a/lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable2Step.sol) - -pragma solidity ^0.8.20; - -import {Ownable} from "./Ownable.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. - * - * This extension of the {Ownable} contract includes a two-step mechanism to transfer - * ownership, where the new owner must call {acceptOwnership} in order to replace the - * old one. This can help prevent common mistakes, such as transfers of ownership to - * incorrect accounts, or to contracts that are unable to interact with the - * permission system. - * - * The initial owner is specified at deployment time in the constructor for `Ownable`. 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 Ownable2Step is Ownable { - 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() public virtual { - address sender = _msgSender(); - if (pendingOwner() != sender) { - revert OwnableUnauthorizedAccount(sender); - } - _transferOwnership(sender); - } -} diff --git a/lib/openzeppelin-contracts/contracts/access/README.adoc b/lib/openzeppelin-contracts/contracts/access/README.adoc deleted file mode 100644 index b89865b..0000000 --- a/lib/openzeppelin-contracts/contracts/access/README.adoc +++ /dev/null @@ -1,45 +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. - -- {AccessManager} is a full-fledged access control solution for smart contract systems. Allows creating and assigning multiple hierarchical roles with execution delays for each account across various contracts. -- {AccessManaged} delegates its access control to an authority that dictates the permissions of the managed contract. It's compatible with an AccessManager as an authority. -- {AccessControl} provides a per-contract role based access control mechanism. Multiple hierarchical roles can be created and assigned each to multiple accounts within the same instance. -- {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. - -== Core - -{{Ownable}} - -{{Ownable2Step}} - -{{IAccessControl}} - -{{AccessControl}} - -== Extensions - -{{IAccessControlEnumerable}} - -{{AccessControlEnumerable}} - -{{IAccessControlDefaultAdminRules}} - -{{AccessControlDefaultAdminRules}} - -== AccessManager - -{{IAuthority}} - -{{IAccessManager}} - -{{AccessManager}} - -{{IAccessManaged}} - -{{AccessManaged}} - -{{AuthorityUtils}} diff --git a/lib/openzeppelin-contracts/contracts/access/extensions/AccessControlDefaultAdminRules.sol b/lib/openzeppelin-contracts/contracts/access/extensions/AccessControlDefaultAdminRules.sol deleted file mode 100644 index ef71a64..0000000 --- a/lib/openzeppelin-contracts/contracts/access/extensions/AccessControlDefaultAdminRules.sol +++ /dev/null @@ -1,396 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (access/extensions/AccessControlDefaultAdminRules.sol) - -pragma solidity ^0.8.20; - -import {IAccessControlDefaultAdminRules} from "./IAccessControlDefaultAdminRules.sol"; -import {AccessControl, IAccessControl} from "../AccessControl.sol"; -import {SafeCast} from "../../utils/math/SafeCast.sol"; -import {Math} from "../../utils/math/Math.sol"; -import {IERC5313} from "../../interfaces/IERC5313.sol"; - -/** - * @dev Extension of {AccessControl} that allows specifying special rules to manage - * the `DEFAULT_ADMIN_ROLE` holder, which is a sensitive role with special permissions - * over other roles that may potentially have privileged rights in the system. - * - * If a specific role doesn't have an admin role assigned, the holder of the - * `DEFAULT_ADMIN_ROLE` will have the ability to grant it and revoke it. - * - * This contract implements the following risk mitigations on top of {AccessControl}: - * - * * Only one account holds the `DEFAULT_ADMIN_ROLE` since deployment until it's potentially renounced. - * * Enforces a 2-step process to transfer the `DEFAULT_ADMIN_ROLE` to another account. - * * Enforces a configurable delay between the two steps, with the ability to cancel before the transfer is accepted. - * * The delay can be changed by scheduling, see {changeDefaultAdminDelay}. - * * It is not possible to use another role to manage the `DEFAULT_ADMIN_ROLE`. - * - * Example usage: - * - * ```solidity - * contract MyToken is AccessControlDefaultAdminRules { - * constructor() AccessControlDefaultAdminRules( - * 3 days, - * msg.sender // Explicit initial `DEFAULT_ADMIN_ROLE` holder - * ) {} - * } - * ``` - */ -abstract contract AccessControlDefaultAdminRules is IAccessControlDefaultAdminRules, IERC5313, AccessControl { - // pending admin pair read/written together frequently - address private _pendingDefaultAdmin; - uint48 private _pendingDefaultAdminSchedule; // 0 == unset - - uint48 private _currentDelay; - address private _currentDefaultAdmin; - - // pending delay pair read/written together frequently - uint48 private _pendingDelay; - uint48 private _pendingDelaySchedule; // 0 == unset - - /** - * @dev Sets the initial values for {defaultAdminDelay} and {defaultAdmin} address. - */ - constructor(uint48 initialDelay, address initialDefaultAdmin) { - if (initialDefaultAdmin == address(0)) { - revert AccessControlInvalidDefaultAdmin(address(0)); - } - _currentDelay = initialDelay; - _grantRole(DEFAULT_ADMIN_ROLE, initialDefaultAdmin); - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { - return interfaceId == type(IAccessControlDefaultAdminRules).interfaceId || super.supportsInterface(interfaceId); - } - - /** - * @dev See {IERC5313-owner}. - */ - function owner() public view virtual returns (address) { - return defaultAdmin(); - } - - /// - /// Override AccessControl role management - /// - - /** - * @dev See {AccessControl-grantRole}. Reverts for `DEFAULT_ADMIN_ROLE`. - */ - function grantRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) { - if (role == DEFAULT_ADMIN_ROLE) { - revert AccessControlEnforcedDefaultAdminRules(); - } - super.grantRole(role, account); - } - - /** - * @dev See {AccessControl-revokeRole}. Reverts for `DEFAULT_ADMIN_ROLE`. - */ - function revokeRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) { - if (role == DEFAULT_ADMIN_ROLE) { - revert AccessControlEnforcedDefaultAdminRules(); - } - super.revokeRole(role, account); - } - - /** - * @dev See {AccessControl-renounceRole}. - * - * For the `DEFAULT_ADMIN_ROLE`, it only allows renouncing in two steps by first calling - * {beginDefaultAdminTransfer} to the `address(0)`, so it's required that the {pendingDefaultAdmin} schedule - * has also passed when calling this function. - * - * After its execution, it will not be possible to call `onlyRole(DEFAULT_ADMIN_ROLE)` functions. - * - * NOTE: Renouncing `DEFAULT_ADMIN_ROLE` will leave the contract without a {defaultAdmin}, - * thereby disabling any functionality that is only available for it, and the possibility of reassigning a - * non-administrated role. - */ - function renounceRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) { - if (role == DEFAULT_ADMIN_ROLE && account == defaultAdmin()) { - (address newDefaultAdmin, uint48 schedule) = pendingDefaultAdmin(); - if (newDefaultAdmin != address(0) || !_isScheduleSet(schedule) || !_hasSchedulePassed(schedule)) { - revert AccessControlEnforcedDefaultAdminDelay(schedule); - } - delete _pendingDefaultAdminSchedule; - } - super.renounceRole(role, account); - } - - /** - * @dev See {AccessControl-_grantRole}. - * - * For `DEFAULT_ADMIN_ROLE`, it only allows granting if there isn't already a {defaultAdmin} or if the - * role has been previously renounced. - * - * NOTE: Exposing this function through another mechanism may make the `DEFAULT_ADMIN_ROLE` - * assignable again. Make sure to guarantee this is the expected behavior in your implementation. - */ - function _grantRole(bytes32 role, address account) internal virtual override returns (bool) { - if (role == DEFAULT_ADMIN_ROLE) { - if (defaultAdmin() != address(0)) { - revert AccessControlEnforcedDefaultAdminRules(); - } - _currentDefaultAdmin = account; - } - return super._grantRole(role, account); - } - - /** - * @dev See {AccessControl-_revokeRole}. - */ - function _revokeRole(bytes32 role, address account) internal virtual override returns (bool) { - if (role == DEFAULT_ADMIN_ROLE && account == defaultAdmin()) { - delete _currentDefaultAdmin; - } - return super._revokeRole(role, account); - } - - /** - * @dev See {AccessControl-_setRoleAdmin}. Reverts for `DEFAULT_ADMIN_ROLE`. - */ - function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual override { - if (role == DEFAULT_ADMIN_ROLE) { - revert AccessControlEnforcedDefaultAdminRules(); - } - super._setRoleAdmin(role, adminRole); - } - - /// - /// AccessControlDefaultAdminRules accessors - /// - - /** - * @inheritdoc IAccessControlDefaultAdminRules - */ - function defaultAdmin() public view virtual returns (address) { - return _currentDefaultAdmin; - } - - /** - * @inheritdoc IAccessControlDefaultAdminRules - */ - function pendingDefaultAdmin() public view virtual returns (address newAdmin, uint48 schedule) { - return (_pendingDefaultAdmin, _pendingDefaultAdminSchedule); - } - - /** - * @inheritdoc IAccessControlDefaultAdminRules - */ - function defaultAdminDelay() public view virtual returns (uint48) { - uint48 schedule = _pendingDelaySchedule; - return (_isScheduleSet(schedule) && _hasSchedulePassed(schedule)) ? _pendingDelay : _currentDelay; - } - - /** - * @inheritdoc IAccessControlDefaultAdminRules - */ - function pendingDefaultAdminDelay() public view virtual returns (uint48 newDelay, uint48 schedule) { - schedule = _pendingDelaySchedule; - return (_isScheduleSet(schedule) && !_hasSchedulePassed(schedule)) ? (_pendingDelay, schedule) : (0, 0); - } - - /** - * @inheritdoc IAccessControlDefaultAdminRules - */ - function defaultAdminDelayIncreaseWait() public view virtual returns (uint48) { - return 5 days; - } - - /// - /// AccessControlDefaultAdminRules public and internal setters for defaultAdmin/pendingDefaultAdmin - /// - - /** - * @inheritdoc IAccessControlDefaultAdminRules - */ - function beginDefaultAdminTransfer(address newAdmin) public virtual onlyRole(DEFAULT_ADMIN_ROLE) { - _beginDefaultAdminTransfer(newAdmin); - } - - /** - * @dev See {beginDefaultAdminTransfer}. - * - * Internal function without access restriction. - */ - function _beginDefaultAdminTransfer(address newAdmin) internal virtual { - uint48 newSchedule = SafeCast.toUint48(block.timestamp) + defaultAdminDelay(); - _setPendingDefaultAdmin(newAdmin, newSchedule); - emit DefaultAdminTransferScheduled(newAdmin, newSchedule); - } - - /** - * @inheritdoc IAccessControlDefaultAdminRules - */ - function cancelDefaultAdminTransfer() public virtual onlyRole(DEFAULT_ADMIN_ROLE) { - _cancelDefaultAdminTransfer(); - } - - /** - * @dev See {cancelDefaultAdminTransfer}. - * - * Internal function without access restriction. - */ - function _cancelDefaultAdminTransfer() internal virtual { - _setPendingDefaultAdmin(address(0), 0); - } - - /** - * @inheritdoc IAccessControlDefaultAdminRules - */ - function acceptDefaultAdminTransfer() public virtual { - (address newDefaultAdmin, ) = pendingDefaultAdmin(); - if (_msgSender() != newDefaultAdmin) { - // Enforce newDefaultAdmin explicit acceptance. - revert AccessControlInvalidDefaultAdmin(_msgSender()); - } - _acceptDefaultAdminTransfer(); - } - - /** - * @dev See {acceptDefaultAdminTransfer}. - * - * Internal function without access restriction. - */ - function _acceptDefaultAdminTransfer() internal virtual { - (address newAdmin, uint48 schedule) = pendingDefaultAdmin(); - if (!_isScheduleSet(schedule) || !_hasSchedulePassed(schedule)) { - revert AccessControlEnforcedDefaultAdminDelay(schedule); - } - _revokeRole(DEFAULT_ADMIN_ROLE, defaultAdmin()); - _grantRole(DEFAULT_ADMIN_ROLE, newAdmin); - delete _pendingDefaultAdmin; - delete _pendingDefaultAdminSchedule; - } - - /// - /// AccessControlDefaultAdminRules public and internal setters for defaultAdminDelay/pendingDefaultAdminDelay - /// - - /** - * @inheritdoc IAccessControlDefaultAdminRules - */ - function changeDefaultAdminDelay(uint48 newDelay) public virtual onlyRole(DEFAULT_ADMIN_ROLE) { - _changeDefaultAdminDelay(newDelay); - } - - /** - * @dev See {changeDefaultAdminDelay}. - * - * Internal function without access restriction. - */ - function _changeDefaultAdminDelay(uint48 newDelay) internal virtual { - uint48 newSchedule = SafeCast.toUint48(block.timestamp) + _delayChangeWait(newDelay); - _setPendingDelay(newDelay, newSchedule); - emit DefaultAdminDelayChangeScheduled(newDelay, newSchedule); - } - - /** - * @inheritdoc IAccessControlDefaultAdminRules - */ - function rollbackDefaultAdminDelay() public virtual onlyRole(DEFAULT_ADMIN_ROLE) { - _rollbackDefaultAdminDelay(); - } - - /** - * @dev See {rollbackDefaultAdminDelay}. - * - * Internal function without access restriction. - */ - function _rollbackDefaultAdminDelay() internal virtual { - _setPendingDelay(0, 0); - } - - /** - * @dev Returns the amount of seconds to wait after the `newDelay` will - * become the new {defaultAdminDelay}. - * - * The value returned guarantees that if the delay is reduced, it will go into effect - * after a wait that honors the previously set delay. - * - * See {defaultAdminDelayIncreaseWait}. - */ - function _delayChangeWait(uint48 newDelay) internal view virtual returns (uint48) { - uint48 currentDelay = defaultAdminDelay(); - - // When increasing the delay, we schedule the delay change to occur after a period of "new delay" has passed, up - // to a maximum given by defaultAdminDelayIncreaseWait, by default 5 days. For example, if increasing from 1 day - // to 3 days, the new delay will come into effect after 3 days. If increasing from 1 day to 10 days, the new - // delay will come into effect after 5 days. The 5 day wait period is intended to be able to fix an error like - // using milliseconds instead of seconds. - // - // When decreasing the delay, we wait the difference between "current delay" and "new delay". This guarantees - // that an admin transfer cannot be made faster than "current delay" at the time the delay change is scheduled. - // For example, if decreasing from 10 days to 3 days, the new delay will come into effect after 7 days. - return - newDelay > currentDelay - ? uint48(Math.min(newDelay, defaultAdminDelayIncreaseWait())) // no need to safecast, both inputs are uint48 - : currentDelay - newDelay; - } - - /// - /// Private setters - /// - - /** - * @dev Setter of the tuple for pending admin and its schedule. - * - * May emit a DefaultAdminTransferCanceled event. - */ - function _setPendingDefaultAdmin(address newAdmin, uint48 newSchedule) private { - (, uint48 oldSchedule) = pendingDefaultAdmin(); - - _pendingDefaultAdmin = newAdmin; - _pendingDefaultAdminSchedule = newSchedule; - - // An `oldSchedule` from `pendingDefaultAdmin()` is only set if it hasn't been accepted. - if (_isScheduleSet(oldSchedule)) { - // Emit for implicit cancellations when another default admin was scheduled. - emit DefaultAdminTransferCanceled(); - } - } - - /** - * @dev Setter of the tuple for pending delay and its schedule. - * - * May emit a DefaultAdminDelayChangeCanceled event. - */ - function _setPendingDelay(uint48 newDelay, uint48 newSchedule) private { - uint48 oldSchedule = _pendingDelaySchedule; - - if (_isScheduleSet(oldSchedule)) { - if (_hasSchedulePassed(oldSchedule)) { - // Materialize a virtual delay - _currentDelay = _pendingDelay; - } else { - // Emit for implicit cancellations when another delay was scheduled. - emit DefaultAdminDelayChangeCanceled(); - } - } - - _pendingDelay = newDelay; - _pendingDelaySchedule = newSchedule; - } - - /// - /// Private helpers - /// - - /** - * @dev Defines if an `schedule` is considered set. For consistency purposes. - */ - function _isScheduleSet(uint48 schedule) private pure returns (bool) { - return schedule != 0; - } - - /** - * @dev Defines if an `schedule` is considered passed. For consistency purposes. - */ - function _hasSchedulePassed(uint48 schedule) private view returns (bool) { - return schedule < block.timestamp; - } -} diff --git a/lib/openzeppelin-contracts/contracts/access/extensions/AccessControlEnumerable.sol b/lib/openzeppelin-contracts/contracts/access/extensions/AccessControlEnumerable.sol deleted file mode 100644 index 222490c..0000000 --- a/lib/openzeppelin-contracts/contracts/access/extensions/AccessControlEnumerable.sol +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (access/extensions/AccessControlEnumerable.sol) - -pragma solidity ^0.8.20; - -import {IAccessControlEnumerable} from "./IAccessControlEnumerable.sol"; -import {AccessControl} from "../AccessControl.sol"; -import {EnumerableSet} from "../../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 role => 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 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 returns (uint256) { - return _roleMembers[role].length(); - } - - /** - * @dev Return all accounts that have `role` - * - * 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 getRoleMembers(bytes32 role) public view virtual returns (address[] memory) { - return _roleMembers[role].values(); - } - - /** - * @dev Overload {AccessControl-_grantRole} to track enumerable memberships - */ - function _grantRole(bytes32 role, address account) internal virtual override returns (bool) { - bool granted = super._grantRole(role, account); - if (granted) { - _roleMembers[role].add(account); - } - return granted; - } - - /** - * @dev Overload {AccessControl-_revokeRole} to track enumerable memberships - */ - function _revokeRole(bytes32 role, address account) internal virtual override returns (bool) { - bool revoked = super._revokeRole(role, account); - if (revoked) { - _roleMembers[role].remove(account); - } - return revoked; - } -} diff --git a/lib/openzeppelin-contracts/contracts/access/extensions/IAccessControlDefaultAdminRules.sol b/lib/openzeppelin-contracts/contracts/access/extensions/IAccessControlDefaultAdminRules.sol deleted file mode 100644 index b74355a..0000000 --- a/lib/openzeppelin-contracts/contracts/access/extensions/IAccessControlDefaultAdminRules.sol +++ /dev/null @@ -1,192 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (access/extensions/IAccessControlDefaultAdminRules.sol) - -pragma solidity ^0.8.20; - -import {IAccessControl} from "../IAccessControl.sol"; - -/** - * @dev External interface of AccessControlDefaultAdminRules declared to support ERC-165 detection. - */ -interface IAccessControlDefaultAdminRules is IAccessControl { - /** - * @dev The new default admin is not a valid default admin. - */ - error AccessControlInvalidDefaultAdmin(address defaultAdmin); - - /** - * @dev At least one of the following rules was violated: - * - * - The `DEFAULT_ADMIN_ROLE` must only be managed by itself. - * - The `DEFAULT_ADMIN_ROLE` must only be held by one account at the time. - * - Any `DEFAULT_ADMIN_ROLE` transfer must be in two delayed steps. - */ - error AccessControlEnforcedDefaultAdminRules(); - - /** - * @dev The delay for transferring the default admin delay is enforced and - * the operation must wait until `schedule`. - * - * NOTE: `schedule` can be 0 indicating there's no transfer scheduled. - */ - error AccessControlEnforcedDefaultAdminDelay(uint48 schedule); - - /** - * @dev Emitted when a {defaultAdmin} transfer is started, setting `newAdmin` as the next - * address to become the {defaultAdmin} by calling {acceptDefaultAdminTransfer} only after `acceptSchedule` - * passes. - */ - event DefaultAdminTransferScheduled(address indexed newAdmin, uint48 acceptSchedule); - - /** - * @dev Emitted when a {pendingDefaultAdmin} is reset if it was never accepted, regardless of its schedule. - */ - event DefaultAdminTransferCanceled(); - - /** - * @dev Emitted when a {defaultAdminDelay} change is started, setting `newDelay` as the next - * delay to be applied between default admin transfer after `effectSchedule` has passed. - */ - event DefaultAdminDelayChangeScheduled(uint48 newDelay, uint48 effectSchedule); - - /** - * @dev Emitted when a {pendingDefaultAdminDelay} is reset if its schedule didn't pass. - */ - event DefaultAdminDelayChangeCanceled(); - - /** - * @dev Returns the address of the current `DEFAULT_ADMIN_ROLE` holder. - */ - function defaultAdmin() external view returns (address); - - /** - * @dev Returns a tuple of a `newAdmin` and an accept schedule. - * - * After the `schedule` passes, the `newAdmin` will be able to accept the {defaultAdmin} role - * by calling {acceptDefaultAdminTransfer}, completing the role transfer. - * - * A zero value only in `acceptSchedule` indicates no pending admin transfer. - * - * NOTE: A zero address `newAdmin` means that {defaultAdmin} is being renounced. - */ - function pendingDefaultAdmin() external view returns (address newAdmin, uint48 acceptSchedule); - - /** - * @dev Returns the delay required to schedule the acceptance of a {defaultAdmin} transfer started. - * - * This delay will be added to the current timestamp when calling {beginDefaultAdminTransfer} to set - * the acceptance schedule. - * - * NOTE: If a delay change has been scheduled, it will take effect as soon as the schedule passes, making this - * function returns the new delay. See {changeDefaultAdminDelay}. - */ - function defaultAdminDelay() external view returns (uint48); - - /** - * @dev Returns a tuple of `newDelay` and an effect schedule. - * - * After the `schedule` passes, the `newDelay` will get into effect immediately for every - * new {defaultAdmin} transfer started with {beginDefaultAdminTransfer}. - * - * A zero value only in `effectSchedule` indicates no pending delay change. - * - * NOTE: A zero value only for `newDelay` means that the next {defaultAdminDelay} - * will be zero after the effect schedule. - */ - function pendingDefaultAdminDelay() external view returns (uint48 newDelay, uint48 effectSchedule); - - /** - * @dev Starts a {defaultAdmin} transfer by setting a {pendingDefaultAdmin} scheduled for acceptance - * after the current timestamp plus a {defaultAdminDelay}. - * - * Requirements: - * - * - Only can be called by the current {defaultAdmin}. - * - * Emits a DefaultAdminRoleChangeStarted event. - */ - function beginDefaultAdminTransfer(address newAdmin) external; - - /** - * @dev Cancels a {defaultAdmin} transfer previously started with {beginDefaultAdminTransfer}. - * - * A {pendingDefaultAdmin} not yet accepted can also be cancelled with this function. - * - * Requirements: - * - * - Only can be called by the current {defaultAdmin}. - * - * May emit a DefaultAdminTransferCanceled event. - */ - function cancelDefaultAdminTransfer() external; - - /** - * @dev Completes a {defaultAdmin} transfer previously started with {beginDefaultAdminTransfer}. - * - * After calling the function: - * - * - `DEFAULT_ADMIN_ROLE` should be granted to the caller. - * - `DEFAULT_ADMIN_ROLE` should be revoked from the previous holder. - * - {pendingDefaultAdmin} should be reset to zero values. - * - * Requirements: - * - * - Only can be called by the {pendingDefaultAdmin}'s `newAdmin`. - * - The {pendingDefaultAdmin}'s `acceptSchedule` should've passed. - */ - function acceptDefaultAdminTransfer() external; - - /** - * @dev Initiates a {defaultAdminDelay} update by setting a {pendingDefaultAdminDelay} scheduled for getting - * into effect after the current timestamp plus a {defaultAdminDelay}. - * - * This function guarantees that any call to {beginDefaultAdminTransfer} done between the timestamp this - * method is called and the {pendingDefaultAdminDelay} effect schedule will use the current {defaultAdminDelay} - * set before calling. - * - * The {pendingDefaultAdminDelay}'s effect schedule is defined in a way that waiting until the schedule and then - * calling {beginDefaultAdminTransfer} with the new delay will take at least the same as another {defaultAdmin} - * complete transfer (including acceptance). - * - * The schedule is designed for two scenarios: - * - * - When the delay is changed for a larger one the schedule is `block.timestamp + newDelay` capped by - * {defaultAdminDelayIncreaseWait}. - * - When the delay is changed for a shorter one, the schedule is `block.timestamp + (current delay - new delay)`. - * - * A {pendingDefaultAdminDelay} that never got into effect will be canceled in favor of a new scheduled change. - * - * Requirements: - * - * - Only can be called by the current {defaultAdmin}. - * - * Emits a DefaultAdminDelayChangeScheduled event and may emit a DefaultAdminDelayChangeCanceled event. - */ - function changeDefaultAdminDelay(uint48 newDelay) external; - - /** - * @dev Cancels a scheduled {defaultAdminDelay} change. - * - * Requirements: - * - * - Only can be called by the current {defaultAdmin}. - * - * May emit a DefaultAdminDelayChangeCanceled event. - */ - function rollbackDefaultAdminDelay() external; - - /** - * @dev Maximum time in seconds for an increase to {defaultAdminDelay} (that is scheduled using {changeDefaultAdminDelay}) - * to take effect. Default to 5 days. - * - * When the {defaultAdminDelay} is scheduled to be increased, it goes into effect after the new delay has passed with - * the purpose of giving enough time for reverting any accidental change (i.e. using milliseconds instead of seconds) - * that may lock the contract. However, to avoid excessive schedules, the wait is capped by this function and it can - * be overrode for a custom {defaultAdminDelay} increase scheduling. - * - * IMPORTANT: Make sure to add a reasonable amount of time while overriding this value, otherwise, - * there's a risk of setting a high new delay that goes into effect almost immediately without the - * possibility of human intervention in the case of an input error (eg. set milliseconds instead of seconds). - */ - function defaultAdminDelayIncreaseWait() external view returns (uint48); -} diff --git a/lib/openzeppelin-contracts/contracts/access/extensions/IAccessControlEnumerable.sol b/lib/openzeppelin-contracts/contracts/access/extensions/IAccessControlEnumerable.sol deleted file mode 100644 index 1142968..0000000 --- a/lib/openzeppelin-contracts/contracts/access/extensions/IAccessControlEnumerable.sol +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (access/extensions/IAccessControlEnumerable.sol) - -pragma solidity ^0.8.20; - -import {IAccessControl} from "../IAccessControl.sol"; - -/** - * @dev External interface of AccessControlEnumerable declared to support ERC-165 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/openzeppelin-contracts/contracts/access/manager/AccessManaged.sol b/lib/openzeppelin-contracts/contracts/access/manager/AccessManaged.sol deleted file mode 100644 index 41b21b0..0000000 --- a/lib/openzeppelin-contracts/contracts/access/manager/AccessManaged.sol +++ /dev/null @@ -1,113 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (access/manager/AccessManaged.sol) - -pragma solidity ^0.8.20; - -import {IAuthority} from "./IAuthority.sol"; -import {AuthorityUtils} from "./AuthorityUtils.sol"; -import {IAccessManager} from "./IAccessManager.sol"; -import {IAccessManaged} from "./IAccessManaged.sol"; -import {Context} from "../../utils/Context.sol"; - -/** - * @dev This contract module makes available a {restricted} modifier. Functions decorated with this modifier will be - * permissioned according to an "authority": a contract like {AccessManager} that follows the {IAuthority} interface, - * implementing a policy that allows certain callers to access certain functions. - * - * IMPORTANT: The `restricted` modifier should never be used on `internal` functions, judiciously used in `public` - * functions, and ideally only used in `external` functions. See {restricted}. - */ -abstract contract AccessManaged is Context, IAccessManaged { - address private _authority; - - bool private _consumingSchedule; - - /** - * @dev Initializes the contract connected to an initial authority. - */ - constructor(address initialAuthority) { - _setAuthority(initialAuthority); - } - - /** - * @dev Restricts access to a function as defined by the connected Authority for this contract and the - * caller and selector of the function that entered the contract. - * - * [IMPORTANT] - * ==== - * In general, this modifier should only be used on `external` functions. It is okay to use it on `public` - * functions that are used as external entry points and are not called internally. Unless you know what you're - * doing, it should never be used on `internal` functions. Failure to follow these rules can have critical security - * implications! This is because the permissions are determined by the function that entered the contract, i.e. the - * function at the bottom of the call stack, and not the function where the modifier is visible in the source code. - * ==== - * - * [WARNING] - * ==== - * Avoid adding this modifier to the https://docs.soliditylang.org/en/v0.8.20/contracts.html#receive-ether-function[`receive()`] - * function or the https://docs.soliditylang.org/en/v0.8.20/contracts.html#fallback-function[`fallback()`]. These - * functions are the only execution paths where a function selector cannot be unambiguously determined from the calldata - * since the selector defaults to `0x00000000` in the `receive()` function and similarly in the `fallback()` function - * if no calldata is provided. (See {_checkCanCall}). - * - * The `receive()` function will always panic whereas the `fallback()` may panic depending on the calldata length. - * ==== - */ - modifier restricted() { - _checkCanCall(_msgSender(), _msgData()); - _; - } - - /// @inheritdoc IAccessManaged - function authority() public view virtual returns (address) { - return _authority; - } - - /// @inheritdoc IAccessManaged - function setAuthority(address newAuthority) public virtual { - address caller = _msgSender(); - if (caller != authority()) { - revert AccessManagedUnauthorized(caller); - } - if (newAuthority.code.length == 0) { - revert AccessManagedInvalidAuthority(newAuthority); - } - _setAuthority(newAuthority); - } - - /// @inheritdoc IAccessManaged - function isConsumingScheduledOp() public view returns (bytes4) { - return _consumingSchedule ? this.isConsumingScheduledOp.selector : bytes4(0); - } - - /** - * @dev Transfers control to a new authority. Internal function with no access restriction. Allows bypassing the - * permissions set by the current authority. - */ - function _setAuthority(address newAuthority) internal virtual { - _authority = newAuthority; - emit AuthorityUpdated(newAuthority); - } - - /** - * @dev Reverts if the caller is not allowed to call the function identified by a selector. Panics if the calldata - * is less than 4 bytes long. - */ - function _checkCanCall(address caller, bytes calldata data) internal virtual { - (bool immediate, uint32 delay) = AuthorityUtils.canCallWithDelay( - authority(), - caller, - address(this), - bytes4(data[0:4]) - ); - if (!immediate) { - if (delay > 0) { - _consumingSchedule = true; - IAccessManager(authority()).consumeScheduledOp(caller, data); - _consumingSchedule = false; - } else { - revert AccessManagedUnauthorized(caller); - } - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/access/manager/AccessManager.sol b/lib/openzeppelin-contracts/contracts/access/manager/AccessManager.sol deleted file mode 100644 index 76abea4..0000000 --- a/lib/openzeppelin-contracts/contracts/access/manager/AccessManager.sol +++ /dev/null @@ -1,732 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (access/manager/AccessManager.sol) - -pragma solidity ^0.8.20; - -import {IAccessManager} from "./IAccessManager.sol"; -import {IAccessManaged} from "./IAccessManaged.sol"; -import {Address} from "../../utils/Address.sol"; -import {Context} from "../../utils/Context.sol"; -import {Multicall} from "../../utils/Multicall.sol"; -import {Math} from "../../utils/math/Math.sol"; -import {Time} from "../../utils/types/Time.sol"; - -/** - * @dev AccessManager is a central contract to store the permissions of a system. - * - * A smart contract under the control of an AccessManager instance is known as a target, and will inherit from the - * {AccessManaged} contract, be connected to this contract as its manager and implement the {AccessManaged-restricted} - * modifier on a set of functions selected to be permissioned. Note that any function without this setup won't be - * effectively restricted. - * - * The restriction rules for such functions are defined in terms of "roles" identified by an `uint64` and scoped - * by target (`address`) and function selectors (`bytes4`). These roles are stored in this contract and can be - * configured by admins (`ADMIN_ROLE` members) after a delay (see {getTargetAdminDelay}). - * - * For each target contract, admins can configure the following without any delay: - * - * * The target's {AccessManaged-authority} via {updateAuthority}. - * * Close or open a target via {setTargetClosed} keeping the permissions intact. - * * The roles that are allowed (or disallowed) to call a given function (identified by its selector) through {setTargetFunctionRole}. - * - * By default every address is member of the `PUBLIC_ROLE` and every target function is restricted to the `ADMIN_ROLE` until configured otherwise. - * Additionally, each role has the following configuration options restricted to this manager's admins: - * - * * A role's admin role via {setRoleAdmin} who can grant or revoke roles. - * * A role's guardian role via {setRoleGuardian} who's allowed to cancel operations. - * * A delay in which a role takes effect after being granted through {setGrantDelay}. - * * A delay of any target's admin action via {setTargetAdminDelay}. - * * A role label for discoverability purposes with {labelRole}. - * - * Any account can be added and removed into any number of these roles by using the {grantRole} and {revokeRole} functions - * restricted to each role's admin (see {getRoleAdmin}). - * - * Since all the permissions of the managed system can be modified by the admins of this instance, it is expected that - * they will be highly secured (e.g., a multisig or a well-configured DAO). - * - * NOTE: This contract implements a form of the {IAuthority} interface, but {canCall} has additional return data so it - * doesn't inherit `IAuthority`. It is however compatible with the `IAuthority` interface since the first 32 bytes of - * the return data are a boolean as expected by that interface. - * - * NOTE: Systems that implement other access control mechanisms (for example using {Ownable}) can be paired with an - * {AccessManager} by transferring permissions (ownership in the case of {Ownable}) directly to the {AccessManager}. - * Users will be able to interact with these contracts through the {execute} function, following the access rules - * registered in the {AccessManager}. Keep in mind that in that context, the msg.sender seen by restricted functions - * will be {AccessManager} itself. - * - * WARNING: When granting permissions over an {Ownable} or {AccessControl} contract to an {AccessManager}, be very - * mindful of the danger associated with functions such as {Ownable-renounceOwnership} or - * {AccessControl-renounceRole}. - */ -contract AccessManager is Context, Multicall, IAccessManager { - using Time for *; - - // Structure that stores the details for a target contract. - struct TargetConfig { - mapping(bytes4 selector => uint64 roleId) allowedRoles; - Time.Delay adminDelay; - bool closed; - } - - // Structure that stores the details for a role/account pair. This structures fit into a single slot. - struct Access { - // Timepoint at which the user gets the permission. - // If this is either 0 or in the future, then the role permission is not available. - uint48 since; - // Delay for execution. Only applies to restricted() / execute() calls. - Time.Delay delay; - } - - // Structure that stores the details of a role. - struct Role { - // Members of the role. - mapping(address user => Access access) members; - // Admin who can grant or revoke permissions. - uint64 admin; - // Guardian who can cancel operations targeting functions that need this role. - uint64 guardian; - // Delay in which the role takes effect after being granted. - Time.Delay grantDelay; - } - - // Structure that stores the details for a scheduled operation. This structure fits into a single slot. - struct Schedule { - // Moment at which the operation can be executed. - uint48 timepoint; - // Operation nonce to allow third-party contracts to identify the operation. - uint32 nonce; - } - - uint64 public constant ADMIN_ROLE = type(uint64).min; // 0 - uint64 public constant PUBLIC_ROLE = type(uint64).max; // 2**64-1 - - mapping(address target => TargetConfig mode) private _targets; - mapping(uint64 roleId => Role) private _roles; - mapping(bytes32 operationId => Schedule) private _schedules; - - // Used to identify operations that are currently being executed via {execute}. - // This should be transient storage when supported by the EVM. - bytes32 private _executionId; - - /** - * @dev Check that the caller is authorized to perform the operation. - * See {AccessManager} description for a detailed breakdown of the authorization logic. - */ - modifier onlyAuthorized() { - _checkAuthorized(); - _; - } - - constructor(address initialAdmin) { - if (initialAdmin == address(0)) { - revert AccessManagerInvalidInitialAdmin(address(0)); - } - - // admin is active immediately and without any execution delay. - _grantRole(ADMIN_ROLE, initialAdmin, 0, 0); - } - - // =================================================== GETTERS ==================================================== - /// @inheritdoc IAccessManager - function canCall( - address caller, - address target, - bytes4 selector - ) public view virtual returns (bool immediate, uint32 delay) { - if (isTargetClosed(target)) { - return (false, 0); - } else if (caller == address(this)) { - // Caller is AccessManager, this means the call was sent through {execute} and it already checked - // permissions. We verify that the call "identifier", which is set during {execute}, is correct. - return (_isExecuting(target, selector), 0); - } else { - uint64 roleId = getTargetFunctionRole(target, selector); - (bool isMember, uint32 currentDelay) = hasRole(roleId, caller); - return isMember ? (currentDelay == 0, currentDelay) : (false, 0); - } - } - - /// @inheritdoc IAccessManager - function expiration() public view virtual returns (uint32) { - return 1 weeks; - } - - /// @inheritdoc IAccessManager - function minSetback() public view virtual returns (uint32) { - return 5 days; - } - - /// @inheritdoc IAccessManager - function isTargetClosed(address target) public view virtual returns (bool) { - return _targets[target].closed; - } - - /// @inheritdoc IAccessManager - function getTargetFunctionRole(address target, bytes4 selector) public view virtual returns (uint64) { - return _targets[target].allowedRoles[selector]; - } - - /// @inheritdoc IAccessManager - function getTargetAdminDelay(address target) public view virtual returns (uint32) { - return _targets[target].adminDelay.get(); - } - - /// @inheritdoc IAccessManager - function getRoleAdmin(uint64 roleId) public view virtual returns (uint64) { - return _roles[roleId].admin; - } - - /// @inheritdoc IAccessManager - function getRoleGuardian(uint64 roleId) public view virtual returns (uint64) { - return _roles[roleId].guardian; - } - - /// @inheritdoc IAccessManager - function getRoleGrantDelay(uint64 roleId) public view virtual returns (uint32) { - return _roles[roleId].grantDelay.get(); - } - - /// @inheritdoc IAccessManager - function getAccess( - uint64 roleId, - address account - ) public view virtual returns (uint48 since, uint32 currentDelay, uint32 pendingDelay, uint48 effect) { - Access storage access = _roles[roleId].members[account]; - - since = access.since; - (currentDelay, pendingDelay, effect) = access.delay.getFull(); - - return (since, currentDelay, pendingDelay, effect); - } - - /// @inheritdoc IAccessManager - function hasRole( - uint64 roleId, - address account - ) public view virtual returns (bool isMember, uint32 executionDelay) { - if (roleId == PUBLIC_ROLE) { - return (true, 0); - } else { - (uint48 hasRoleSince, uint32 currentDelay, , ) = getAccess(roleId, account); - return (hasRoleSince != 0 && hasRoleSince <= Time.timestamp(), currentDelay); - } - } - - // =============================================== ROLE MANAGEMENT =============================================== - /// @inheritdoc IAccessManager - function labelRole(uint64 roleId, string calldata label) public virtual onlyAuthorized { - if (roleId == ADMIN_ROLE || roleId == PUBLIC_ROLE) { - revert AccessManagerLockedRole(roleId); - } - emit RoleLabel(roleId, label); - } - - /// @inheritdoc IAccessManager - function grantRole(uint64 roleId, address account, uint32 executionDelay) public virtual onlyAuthorized { - _grantRole(roleId, account, getRoleGrantDelay(roleId), executionDelay); - } - - /// @inheritdoc IAccessManager - function revokeRole(uint64 roleId, address account) public virtual onlyAuthorized { - _revokeRole(roleId, account); - } - - /// @inheritdoc IAccessManager - function renounceRole(uint64 roleId, address callerConfirmation) public virtual { - if (callerConfirmation != _msgSender()) { - revert AccessManagerBadConfirmation(); - } - _revokeRole(roleId, callerConfirmation); - } - - /// @inheritdoc IAccessManager - function setRoleAdmin(uint64 roleId, uint64 admin) public virtual onlyAuthorized { - _setRoleAdmin(roleId, admin); - } - - /// @inheritdoc IAccessManager - function setRoleGuardian(uint64 roleId, uint64 guardian) public virtual onlyAuthorized { - _setRoleGuardian(roleId, guardian); - } - - /// @inheritdoc IAccessManager - function setGrantDelay(uint64 roleId, uint32 newDelay) public virtual onlyAuthorized { - _setGrantDelay(roleId, newDelay); - } - - /** - * @dev Internal version of {grantRole} without access control. Returns true if the role was newly granted. - * - * Emits a {RoleGranted} event. - */ - function _grantRole( - uint64 roleId, - address account, - uint32 grantDelay, - uint32 executionDelay - ) internal virtual returns (bool) { - if (roleId == PUBLIC_ROLE) { - revert AccessManagerLockedRole(roleId); - } - - bool newMember = _roles[roleId].members[account].since == 0; - uint48 since; - - if (newMember) { - since = Time.timestamp() + grantDelay; - _roles[roleId].members[account] = Access({since: since, delay: executionDelay.toDelay()}); - } else { - // No setback here. Value can be reset by doing revoke + grant, effectively allowing the admin to perform - // any change to the execution delay within the duration of the role admin delay. - (_roles[roleId].members[account].delay, since) = _roles[roleId].members[account].delay.withUpdate( - executionDelay, - 0 - ); - } - - emit RoleGranted(roleId, account, executionDelay, since, newMember); - return newMember; - } - - /** - * @dev Internal version of {revokeRole} without access control. This logic is also used by {renounceRole}. - * Returns true if the role was previously granted. - * - * Emits a {RoleRevoked} event if the account had the role. - */ - function _revokeRole(uint64 roleId, address account) internal virtual returns (bool) { - if (roleId == PUBLIC_ROLE) { - revert AccessManagerLockedRole(roleId); - } - - if (_roles[roleId].members[account].since == 0) { - return false; - } - - delete _roles[roleId].members[account]; - - emit RoleRevoked(roleId, account); - return true; - } - - /** - * @dev Internal version of {setRoleAdmin} without access control. - * - * Emits a {RoleAdminChanged} event. - * - * NOTE: Setting the admin role as the `PUBLIC_ROLE` is allowed, but it will effectively allow - * anyone to set grant or revoke such role. - */ - function _setRoleAdmin(uint64 roleId, uint64 admin) internal virtual { - if (roleId == ADMIN_ROLE || roleId == PUBLIC_ROLE) { - revert AccessManagerLockedRole(roleId); - } - - _roles[roleId].admin = admin; - - emit RoleAdminChanged(roleId, admin); - } - - /** - * @dev Internal version of {setRoleGuardian} without access control. - * - * Emits a {RoleGuardianChanged} event. - * - * NOTE: Setting the guardian role as the `PUBLIC_ROLE` is allowed, but it will effectively allow - * anyone to cancel any scheduled operation for such role. - */ - function _setRoleGuardian(uint64 roleId, uint64 guardian) internal virtual { - if (roleId == ADMIN_ROLE || roleId == PUBLIC_ROLE) { - revert AccessManagerLockedRole(roleId); - } - - _roles[roleId].guardian = guardian; - - emit RoleGuardianChanged(roleId, guardian); - } - - /** - * @dev Internal version of {setGrantDelay} without access control. - * - * Emits a {RoleGrantDelayChanged} event. - */ - function _setGrantDelay(uint64 roleId, uint32 newDelay) internal virtual { - if (roleId == PUBLIC_ROLE) { - revert AccessManagerLockedRole(roleId); - } - - uint48 effect; - (_roles[roleId].grantDelay, effect) = _roles[roleId].grantDelay.withUpdate(newDelay, minSetback()); - - emit RoleGrantDelayChanged(roleId, newDelay, effect); - } - - // ============================================= FUNCTION MANAGEMENT ============================================== - /// @inheritdoc IAccessManager - function setTargetFunctionRole( - address target, - bytes4[] calldata selectors, - uint64 roleId - ) public virtual onlyAuthorized { - for (uint256 i = 0; i < selectors.length; ++i) { - _setTargetFunctionRole(target, selectors[i], roleId); - } - } - - /** - * @dev Internal version of {setTargetFunctionRole} without access control. - * - * Emits a {TargetFunctionRoleUpdated} event. - */ - function _setTargetFunctionRole(address target, bytes4 selector, uint64 roleId) internal virtual { - _targets[target].allowedRoles[selector] = roleId; - emit TargetFunctionRoleUpdated(target, selector, roleId); - } - - /// @inheritdoc IAccessManager - function setTargetAdminDelay(address target, uint32 newDelay) public virtual onlyAuthorized { - _setTargetAdminDelay(target, newDelay); - } - - /** - * @dev Internal version of {setTargetAdminDelay} without access control. - * - * Emits a {TargetAdminDelayUpdated} event. - */ - function _setTargetAdminDelay(address target, uint32 newDelay) internal virtual { - uint48 effect; - (_targets[target].adminDelay, effect) = _targets[target].adminDelay.withUpdate(newDelay, minSetback()); - - emit TargetAdminDelayUpdated(target, newDelay, effect); - } - - // =============================================== MODE MANAGEMENT ================================================ - /// @inheritdoc IAccessManager - function setTargetClosed(address target, bool closed) public virtual onlyAuthorized { - _setTargetClosed(target, closed); - } - - /** - * @dev Set the closed flag for a contract. This is an internal setter with no access restrictions. - * - * Emits a {TargetClosed} event. - */ - function _setTargetClosed(address target, bool closed) internal virtual { - _targets[target].closed = closed; - emit TargetClosed(target, closed); - } - - // ============================================== DELAYED OPERATIONS ============================================== - /// @inheritdoc IAccessManager - function getSchedule(bytes32 id) public view virtual returns (uint48) { - uint48 timepoint = _schedules[id].timepoint; - return _isExpired(timepoint) ? 0 : timepoint; - } - - /// @inheritdoc IAccessManager - function getNonce(bytes32 id) public view virtual returns (uint32) { - return _schedules[id].nonce; - } - - /// @inheritdoc IAccessManager - function schedule( - address target, - bytes calldata data, - uint48 when - ) public virtual returns (bytes32 operationId, uint32 nonce) { - address caller = _msgSender(); - - // Fetch restrictions that apply to the caller on the targeted function - (, uint32 setback) = _canCallExtended(caller, target, data); - - uint48 minWhen = Time.timestamp() + setback; - - // If call with delay is not authorized, or if requested timing is too soon, revert - if (setback == 0 || (when > 0 && when < minWhen)) { - revert AccessManagerUnauthorizedCall(caller, target, _checkSelector(data)); - } - - // Reuse variable due to stack too deep - when = uint48(Math.max(when, minWhen)); // cast is safe: both inputs are uint48 - - // If caller is authorised, schedule operation - operationId = hashOperation(caller, target, data); - - _checkNotScheduled(operationId); - - unchecked { - // It's not feasible to overflow the nonce in less than 1000 years - nonce = _schedules[operationId].nonce + 1; - } - _schedules[operationId].timepoint = when; - _schedules[operationId].nonce = nonce; - emit OperationScheduled(operationId, nonce, when, caller, target, data); - - // Using named return values because otherwise we get stack too deep - } - - /** - * @dev Reverts if the operation is currently scheduled and has not expired. - * - * NOTE: This function was introduced due to stack too deep errors in schedule. - */ - function _checkNotScheduled(bytes32 operationId) private view { - uint48 prevTimepoint = _schedules[operationId].timepoint; - if (prevTimepoint != 0 && !_isExpired(prevTimepoint)) { - revert AccessManagerAlreadyScheduled(operationId); - } - } - - /// @inheritdoc IAccessManager - // Reentrancy is not an issue because permissions are checked on msg.sender. Additionally, - // _consumeScheduledOp guarantees a scheduled operation is only executed once. - // slither-disable-next-line reentrancy-no-eth - function execute(address target, bytes calldata data) public payable virtual returns (uint32) { - address caller = _msgSender(); - - // Fetch restrictions that apply to the caller on the targeted function - (bool immediate, uint32 setback) = _canCallExtended(caller, target, data); - - // If call is not authorized, revert - if (!immediate && setback == 0) { - revert AccessManagerUnauthorizedCall(caller, target, _checkSelector(data)); - } - - bytes32 operationId = hashOperation(caller, target, data); - uint32 nonce; - - // If caller is authorised, check operation was scheduled early enough - // Consume an available schedule even if there is no currently enforced delay - if (setback != 0 || getSchedule(operationId) != 0) { - nonce = _consumeScheduledOp(operationId); - } - - // Mark the target and selector as authorised - bytes32 executionIdBefore = _executionId; - _executionId = _hashExecutionId(target, _checkSelector(data)); - - // Perform call - Address.functionCallWithValue(target, data, msg.value); - - // Reset execute identifier - _executionId = executionIdBefore; - - return nonce; - } - - /// @inheritdoc IAccessManager - function cancel(address caller, address target, bytes calldata data) public virtual returns (uint32) { - address msgsender = _msgSender(); - bytes4 selector = _checkSelector(data); - - bytes32 operationId = hashOperation(caller, target, data); - if (_schedules[operationId].timepoint == 0) { - revert AccessManagerNotScheduled(operationId); - } else if (caller != msgsender) { - // calls can only be canceled by the account that scheduled them, a global admin, or by a guardian of the required role. - (bool isAdmin, ) = hasRole(ADMIN_ROLE, msgsender); - (bool isGuardian, ) = hasRole(getRoleGuardian(getTargetFunctionRole(target, selector)), msgsender); - if (!isAdmin && !isGuardian) { - revert AccessManagerUnauthorizedCancel(msgsender, caller, target, selector); - } - } - - delete _schedules[operationId].timepoint; // reset the timepoint, keep the nonce - uint32 nonce = _schedules[operationId].nonce; - emit OperationCanceled(operationId, nonce); - - return nonce; - } - - /// @inheritdoc IAccessManager - function consumeScheduledOp(address caller, bytes calldata data) public virtual { - address target = _msgSender(); - if (IAccessManaged(target).isConsumingScheduledOp() != IAccessManaged.isConsumingScheduledOp.selector) { - revert AccessManagerUnauthorizedConsume(target); - } - _consumeScheduledOp(hashOperation(caller, target, data)); - } - - /** - * @dev Internal variant of {consumeScheduledOp} that operates on bytes32 operationId. - * - * Returns the nonce of the scheduled operation that is consumed. - */ - function _consumeScheduledOp(bytes32 operationId) internal virtual returns (uint32) { - uint48 timepoint = _schedules[operationId].timepoint; - uint32 nonce = _schedules[operationId].nonce; - - if (timepoint == 0) { - revert AccessManagerNotScheduled(operationId); - } else if (timepoint > Time.timestamp()) { - revert AccessManagerNotReady(operationId); - } else if (_isExpired(timepoint)) { - revert AccessManagerExpired(operationId); - } - - delete _schedules[operationId].timepoint; // reset the timepoint, keep the nonce - emit OperationExecuted(operationId, nonce); - - return nonce; - } - - /// @inheritdoc IAccessManager - function hashOperation(address caller, address target, bytes calldata data) public view virtual returns (bytes32) { - return keccak256(abi.encode(caller, target, data)); - } - - // ==================================================== OTHERS ==================================================== - /// @inheritdoc IAccessManager - function updateAuthority(address target, address newAuthority) public virtual onlyAuthorized { - IAccessManaged(target).setAuthority(newAuthority); - } - - // ================================================= ADMIN LOGIC ================================================== - /** - * @dev Check if the current call is authorized according to admin and roles logic. - * - * WARNING: Carefully review the considerations of {AccessManaged-restricted} since they apply to this modifier. - */ - function _checkAuthorized() private { - address caller = _msgSender(); - (bool immediate, uint32 delay) = _canCallSelf(caller, _msgData()); - if (!immediate) { - if (delay == 0) { - (, uint64 requiredRole, ) = _getAdminRestrictions(_msgData()); - revert AccessManagerUnauthorizedAccount(caller, requiredRole); - } else { - _consumeScheduledOp(hashOperation(caller, address(this), _msgData())); - } - } - } - - /** - * @dev Get the admin restrictions of a given function call based on the function and arguments involved. - * - * Returns: - * - bool restricted: does this data match a restricted operation - * - uint64: which role is this operation restricted to - * - uint32: minimum delay to enforce for that operation (max between operation's delay and admin's execution delay) - */ - function _getAdminRestrictions( - bytes calldata data - ) private view returns (bool adminRestricted, uint64 roleAdminId, uint32 executionDelay) { - if (data.length < 4) { - return (false, 0, 0); - } - - bytes4 selector = _checkSelector(data); - - // Restricted to ADMIN with no delay beside any execution delay the caller may have - if ( - selector == this.labelRole.selector || - selector == this.setRoleAdmin.selector || - selector == this.setRoleGuardian.selector || - selector == this.setGrantDelay.selector || - selector == this.setTargetAdminDelay.selector - ) { - return (true, ADMIN_ROLE, 0); - } - - // Restricted to ADMIN with the admin delay corresponding to the target - if ( - selector == this.updateAuthority.selector || - selector == this.setTargetClosed.selector || - selector == this.setTargetFunctionRole.selector - ) { - // First argument is a target. - address target = abi.decode(data[0x04:0x24], (address)); - uint32 delay = getTargetAdminDelay(target); - return (true, ADMIN_ROLE, delay); - } - - // Restricted to that role's admin with no delay beside any execution delay the caller may have. - if (selector == this.grantRole.selector || selector == this.revokeRole.selector) { - // First argument is a roleId. - uint64 roleId = abi.decode(data[0x04:0x24], (uint64)); - return (true, getRoleAdmin(roleId), 0); - } - - return (false, getTargetFunctionRole(address(this), selector), 0); - } - - // =================================================== HELPERS ==================================================== - /** - * @dev An extended version of {canCall} for internal usage that checks {_canCallSelf} - * when the target is this contract. - * - * Returns: - * - bool immediate: whether the operation can be executed immediately (with no delay) - * - uint32 delay: the execution delay - */ - function _canCallExtended( - address caller, - address target, - bytes calldata data - ) private view returns (bool immediate, uint32 delay) { - if (target == address(this)) { - return _canCallSelf(caller, data); - } else { - return data.length < 4 ? (false, 0) : canCall(caller, target, _checkSelector(data)); - } - } - - /** - * @dev A version of {canCall} that checks for restrictions in this contract. - */ - function _canCallSelf(address caller, bytes calldata data) private view returns (bool immediate, uint32 delay) { - if (data.length < 4) { - return (false, 0); - } - - if (caller == address(this)) { - // Caller is AccessManager, this means the call was sent through {execute} and it already checked - // permissions. We verify that the call "identifier", which is set during {execute}, is correct. - return (_isExecuting(address(this), _checkSelector(data)), 0); - } - - (bool adminRestricted, uint64 roleId, uint32 operationDelay) = _getAdminRestrictions(data); - - // isTragetClosed apply to non-admin-restricted function - if (!adminRestricted && isTargetClosed(address(this))) { - return (false, 0); - } - - (bool inRole, uint32 executionDelay) = hasRole(roleId, caller); - if (!inRole) { - return (false, 0); - } - - // downcast is safe because both options are uint32 - delay = uint32(Math.max(operationDelay, executionDelay)); - return (delay == 0, delay); - } - - /** - * @dev Returns true if a call with `target` and `selector` is being executed via {executed}. - */ - function _isExecuting(address target, bytes4 selector) private view returns (bool) { - return _executionId == _hashExecutionId(target, selector); - } - - /** - * @dev Returns true if a schedule timepoint is past its expiration deadline. - */ - function _isExpired(uint48 timepoint) private view returns (bool) { - return timepoint + expiration() <= Time.timestamp(); - } - - /** - * @dev Extracts the selector from calldata. Panics if data is not at least 4 bytes - */ - function _checkSelector(bytes calldata data) private pure returns (bytes4) { - return bytes4(data[0:4]); - } - - /** - * @dev Hashing function for execute protection - */ - function _hashExecutionId(address target, bytes4 selector) private pure returns (bytes32) { - return keccak256(abi.encode(target, selector)); - } -} diff --git a/lib/openzeppelin-contracts/contracts/access/manager/AuthorityUtils.sol b/lib/openzeppelin-contracts/contracts/access/manager/AuthorityUtils.sol deleted file mode 100644 index fb3018c..0000000 --- a/lib/openzeppelin-contracts/contracts/access/manager/AuthorityUtils.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (access/manager/AuthorityUtils.sol) - -pragma solidity ^0.8.20; - -import {IAuthority} from "./IAuthority.sol"; - -library AuthorityUtils { - /** - * @dev Since `AccessManager` implements an extended IAuthority interface, invoking `canCall` with backwards compatibility - * for the preexisting `IAuthority` interface requires special care to avoid reverting on insufficient return data. - * This helper function takes care of invoking `canCall` in a backwards compatible way without reverting. - */ - function canCallWithDelay( - address authority, - address caller, - address target, - bytes4 selector - ) internal view returns (bool immediate, uint32 delay) { - (bool success, bytes memory data) = authority.staticcall( - abi.encodeCall(IAuthority.canCall, (caller, target, selector)) - ); - if (success) { - if (data.length >= 0x40) { - (immediate, delay) = abi.decode(data, (bool, uint32)); - } else if (data.length >= 0x20) { - immediate = abi.decode(data, (bool)); - } - } - return (immediate, delay); - } -} diff --git a/lib/openzeppelin-contracts/contracts/access/manager/IAccessManaged.sol b/lib/openzeppelin-contracts/contracts/access/manager/IAccessManaged.sol deleted file mode 100644 index 95206bd..0000000 --- a/lib/openzeppelin-contracts/contracts/access/manager/IAccessManaged.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (access/manager/IAccessManaged.sol) - -pragma solidity ^0.8.20; - -interface IAccessManaged { - /** - * @dev Authority that manages this contract was updated. - */ - event AuthorityUpdated(address authority); - - error AccessManagedUnauthorized(address caller); - error AccessManagedRequiredDelay(address caller, uint32 delay); - error AccessManagedInvalidAuthority(address authority); - - /** - * @dev Returns the current authority. - */ - function authority() external view returns (address); - - /** - * @dev Transfers control to a new authority. The caller must be the current authority. - */ - function setAuthority(address) external; - - /** - * @dev Returns true only in the context of a delayed restricted call, at the moment that the scheduled operation is - * being consumed. Prevents denial of service for delayed restricted calls in the case that the contract performs - * attacker controlled calls. - */ - function isConsumingScheduledOp() external view returns (bytes4); -} diff --git a/lib/openzeppelin-contracts/contracts/access/manager/IAccessManager.sol b/lib/openzeppelin-contracts/contracts/access/manager/IAccessManager.sol deleted file mode 100644 index 50637e9..0000000 --- a/lib/openzeppelin-contracts/contracts/access/manager/IAccessManager.sol +++ /dev/null @@ -1,402 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (access/manager/IAccessManager.sol) - -pragma solidity ^0.8.20; - -import {IAccessManaged} from "./IAccessManaged.sol"; -import {Time} from "../../utils/types/Time.sol"; - -interface IAccessManager { - /** - * @dev A delayed operation was scheduled. - */ - event OperationScheduled( - bytes32 indexed operationId, - uint32 indexed nonce, - uint48 schedule, - address caller, - address target, - bytes data - ); - - /** - * @dev A scheduled operation was executed. - */ - event OperationExecuted(bytes32 indexed operationId, uint32 indexed nonce); - - /** - * @dev A scheduled operation was canceled. - */ - event OperationCanceled(bytes32 indexed operationId, uint32 indexed nonce); - - /** - * @dev Informational labelling for a roleId. - */ - event RoleLabel(uint64 indexed roleId, string label); - - /** - * @dev Emitted when `account` is granted `roleId`. - * - * NOTE: The meaning of the `since` argument depends on the `newMember` argument. - * If the role is granted to a new member, the `since` argument indicates when the account becomes a member of the role, - * otherwise it indicates the execution delay for this account and roleId is updated. - */ - event RoleGranted(uint64 indexed roleId, address indexed account, uint32 delay, uint48 since, bool newMember); - - /** - * @dev Emitted when `account` membership or `roleId` is revoked. Unlike granting, revoking is instantaneous. - */ - event RoleRevoked(uint64 indexed roleId, address indexed account); - - /** - * @dev Role acting as admin over a given `roleId` is updated. - */ - event RoleAdminChanged(uint64 indexed roleId, uint64 indexed admin); - - /** - * @dev Role acting as guardian over a given `roleId` is updated. - */ - event RoleGuardianChanged(uint64 indexed roleId, uint64 indexed guardian); - - /** - * @dev Grant delay for a given `roleId` will be updated to `delay` when `since` is reached. - */ - event RoleGrantDelayChanged(uint64 indexed roleId, uint32 delay, uint48 since); - - /** - * @dev Target mode is updated (true = closed, false = open). - */ - event TargetClosed(address indexed target, bool closed); - - /** - * @dev Role required to invoke `selector` on `target` is updated to `roleId`. - */ - event TargetFunctionRoleUpdated(address indexed target, bytes4 selector, uint64 indexed roleId); - - /** - * @dev Admin delay for a given `target` will be updated to `delay` when `since` is reached. - */ - event TargetAdminDelayUpdated(address indexed target, uint32 delay, uint48 since); - - error AccessManagerAlreadyScheduled(bytes32 operationId); - error AccessManagerNotScheduled(bytes32 operationId); - error AccessManagerNotReady(bytes32 operationId); - error AccessManagerExpired(bytes32 operationId); - error AccessManagerLockedRole(uint64 roleId); - error AccessManagerBadConfirmation(); - error AccessManagerUnauthorizedAccount(address msgsender, uint64 roleId); - error AccessManagerUnauthorizedCall(address caller, address target, bytes4 selector); - error AccessManagerUnauthorizedConsume(address target); - error AccessManagerUnauthorizedCancel(address msgsender, address caller, address target, bytes4 selector); - error AccessManagerInvalidInitialAdmin(address initialAdmin); - - /** - * @dev Check if an address (`caller`) is authorised to call a given function on a given contract directly (with - * no restriction). Additionally, it returns the delay needed to perform the call indirectly through the {schedule} - * & {execute} workflow. - * - * This function is usually called by the targeted contract to control immediate execution of restricted functions. - * Therefore we only return true if the call can be performed without any delay. If the call is subject to a - * previously set delay (not zero), then the function should return false and the caller should schedule the operation - * for future execution. - * - * If `immediate` is true, the delay can be disregarded and the operation can be immediately executed, otherwise - * the operation can be executed if and only if delay is greater than 0. - * - * NOTE: The IAuthority interface does not include the `uint32` delay. This is an extension of that interface that - * is backward compatible. Some contracts may thus ignore the second return argument. In that case they will fail - * to identify the indirect workflow, and will consider calls that require a delay to be forbidden. - * - * NOTE: This function does not report the permissions of the admin functions in the manager itself. These are defined by the - * {AccessManager} documentation. - */ - function canCall( - address caller, - address target, - bytes4 selector - ) external view returns (bool allowed, uint32 delay); - - /** - * @dev Expiration delay for scheduled proposals. Defaults to 1 week. - * - * IMPORTANT: Avoid overriding the expiration with 0. Otherwise every contract proposal will be expired immediately, - * disabling any scheduling usage. - */ - function expiration() external view returns (uint32); - - /** - * @dev Minimum setback for all delay updates, with the exception of execution delays. It - * can be increased without setback (and reset via {revokeRole} in the case event of an - * accidental increase). Defaults to 5 days. - */ - function minSetback() external view returns (uint32); - - /** - * @dev Get whether the contract is closed disabling any access. Otherwise role permissions are applied. - * - * NOTE: When the manager itself is closed, admin functions are still accessible to avoid locking the contract. - */ - function isTargetClosed(address target) external view returns (bool); - - /** - * @dev Get the role required to call a function. - */ - function getTargetFunctionRole(address target, bytes4 selector) external view returns (uint64); - - /** - * @dev Get the admin delay for a target contract. Changes to contract configuration are subject to this delay. - */ - function getTargetAdminDelay(address target) external view returns (uint32); - - /** - * @dev Get the id of the role that acts as an admin for the given role. - * - * The admin permission is required to grant the role, revoke the role and update the execution delay to execute - * an operation that is restricted to this role. - */ - function getRoleAdmin(uint64 roleId) external view returns (uint64); - - /** - * @dev Get the role that acts as a guardian for a given role. - * - * The guardian permission allows canceling operations that have been scheduled under the role. - */ - function getRoleGuardian(uint64 roleId) external view returns (uint64); - - /** - * @dev Get the role current grant delay. - * - * Its value may change at any point without an event emitted following a call to {setGrantDelay}. - * Changes to this value, including effect timepoint are notified in advance by the {RoleGrantDelayChanged} event. - */ - function getRoleGrantDelay(uint64 roleId) external view returns (uint32); - - /** - * @dev Get the access details for a given account for a given role. These details include the timepoint at which - * membership becomes active, and the delay applied to all operation by this user that requires this permission - * level. - * - * Returns: - * [0] Timestamp at which the account membership becomes valid. 0 means role is not granted. - * [1] Current execution delay for the account. - * [2] Pending execution delay for the account. - * [3] Timestamp at which the pending execution delay will become active. 0 means no delay update is scheduled. - */ - function getAccess( - uint64 roleId, - address account - ) external view returns (uint48 since, uint32 currentDelay, uint32 pendingDelay, uint48 effect); - - /** - * @dev Check if a given account currently has the permission level corresponding to a given role. Note that this - * permission might be associated with an execution delay. {getAccess} can provide more details. - */ - function hasRole(uint64 roleId, address account) external view returns (bool isMember, uint32 executionDelay); - - /** - * @dev Give a label to a role, for improved role discoverability by UIs. - * - * Requirements: - * - * - the caller must be a global admin - * - * Emits a {RoleLabel} event. - */ - function labelRole(uint64 roleId, string calldata label) external; - - /** - * @dev Add `account` to `roleId`, or change its execution delay. - * - * This gives the account the authorization to call any function that is restricted to this role. An optional - * execution delay (in seconds) can be set. If that delay is non 0, the user is required to schedule any operation - * that is restricted to members of this role. The user will only be able to execute the operation after the delay has - * passed, before it has expired. During this period, admin and guardians can cancel the operation (see {cancel}). - * - * If the account has already been granted this role, the execution delay will be updated. This update is not - * immediate and follows the delay rules. For example, if a user currently has a delay of 3 hours, and this is - * called to reduce that delay to 1 hour, the new delay will take some time to take effect, enforcing that any - * operation executed in the 3 hours that follows this update was indeed scheduled before this update. - * - * Requirements: - * - * - the caller must be an admin for the role (see {getRoleAdmin}) - * - granted role must not be the `PUBLIC_ROLE` - * - * Emits a {RoleGranted} event. - */ - function grantRole(uint64 roleId, address account, uint32 executionDelay) external; - - /** - * @dev Remove an account from a role, with immediate effect. If the account does not have the role, this call has - * no effect. - * - * Requirements: - * - * - the caller must be an admin for the role (see {getRoleAdmin}) - * - revoked role must not be the `PUBLIC_ROLE` - * - * Emits a {RoleRevoked} event if the account had the role. - */ - function revokeRole(uint64 roleId, address account) external; - - /** - * @dev Renounce role permissions for the calling account with immediate effect. If the sender is not in - * the role this call has no effect. - * - * Requirements: - * - * - the caller must be `callerConfirmation`. - * - * Emits a {RoleRevoked} event if the account had the role. - */ - function renounceRole(uint64 roleId, address callerConfirmation) external; - - /** - * @dev Change admin role for a given role. - * - * Requirements: - * - * - the caller must be a global admin - * - * Emits a {RoleAdminChanged} event - */ - function setRoleAdmin(uint64 roleId, uint64 admin) external; - - /** - * @dev Change guardian role for a given role. - * - * Requirements: - * - * - the caller must be a global admin - * - * Emits a {RoleGuardianChanged} event - */ - function setRoleGuardian(uint64 roleId, uint64 guardian) external; - - /** - * @dev Update the delay for granting a `roleId`. - * - * Requirements: - * - * - the caller must be a global admin - * - * Emits a {RoleGrantDelayChanged} event. - */ - function setGrantDelay(uint64 roleId, uint32 newDelay) external; - - /** - * @dev Set the role required to call functions identified by the `selectors` in the `target` contract. - * - * Requirements: - * - * - the caller must be a global admin - * - * Emits a {TargetFunctionRoleUpdated} event per selector. - */ - function setTargetFunctionRole(address target, bytes4[] calldata selectors, uint64 roleId) external; - - /** - * @dev Set the delay for changing the configuration of a given target contract. - * - * Requirements: - * - * - the caller must be a global admin - * - * Emits a {TargetAdminDelayUpdated} event. - */ - function setTargetAdminDelay(address target, uint32 newDelay) external; - - /** - * @dev Set the closed flag for a contract. - * - * Closing the manager itself won't disable access to admin methods to avoid locking the contract. - * - * Requirements: - * - * - the caller must be a global admin - * - * Emits a {TargetClosed} event. - */ - function setTargetClosed(address target, bool closed) external; - - /** - * @dev Return the timepoint at which a scheduled operation will be ready for execution. This returns 0 if the - * operation is not yet scheduled, has expired, was executed, or was canceled. - */ - function getSchedule(bytes32 id) external view returns (uint48); - - /** - * @dev Return the nonce for the latest scheduled operation with a given id. Returns 0 if the operation has never - * been scheduled. - */ - function getNonce(bytes32 id) external view returns (uint32); - - /** - * @dev Schedule a delayed operation for future execution, and return the operation identifier. It is possible to - * choose the timestamp at which the operation becomes executable as long as it satisfies the execution delays - * required for the caller. The special value zero will automatically set the earliest possible time. - * - * Returns the `operationId` that was scheduled. Since this value is a hash of the parameters, it can reoccur when - * the same parameters are used; if this is relevant, the returned `nonce` can be used to uniquely identify this - * scheduled operation from other occurrences of the same `operationId` in invocations of {execute} and {cancel}. - * - * Emits a {OperationScheduled} event. - * - * NOTE: It is not possible to concurrently schedule more than one operation with the same `target` and `data`. If - * this is necessary, a random byte can be appended to `data` to act as a salt that will be ignored by the target - * contract if it is using standard Solidity ABI encoding. - */ - function schedule( - address target, - bytes calldata data, - uint48 when - ) external returns (bytes32 operationId, uint32 nonce); - - /** - * @dev Execute a function that is delay restricted, provided it was properly scheduled beforehand, or the - * execution delay is 0. - * - * Returns the nonce that identifies the previously scheduled operation that is executed, or 0 if the - * operation wasn't previously scheduled (if the caller doesn't have an execution delay). - * - * Emits an {OperationExecuted} event only if the call was scheduled and delayed. - */ - function execute(address target, bytes calldata data) external payable returns (uint32); - - /** - * @dev Cancel a scheduled (delayed) operation. Returns the nonce that identifies the previously scheduled - * operation that is cancelled. - * - * Requirements: - * - * - the caller must be the proposer, a guardian of the targeted function, or a global admin - * - * Emits a {OperationCanceled} event. - */ - function cancel(address caller, address target, bytes calldata data) external returns (uint32); - - /** - * @dev Consume a scheduled operation targeting the caller. If such an operation exists, mark it as consumed - * (emit an {OperationExecuted} event and clean the state). Otherwise, throw an error. - * - * This is useful for contract that want to enforce that calls targeting them were scheduled on the manager, - * with all the verifications that it implies. - * - * Emit a {OperationExecuted} event. - */ - function consumeScheduledOp(address caller, bytes calldata data) external; - - /** - * @dev Hashing function for delayed operations. - */ - function hashOperation(address caller, address target, bytes calldata data) external view returns (bytes32); - - /** - * @dev Changes the authority of a target managed by this manager instance. - * - * Requirements: - * - * - the caller must be a global admin - */ - function updateAuthority(address target, address newAuthority) external; -} diff --git a/lib/openzeppelin-contracts/contracts/access/manager/IAuthority.sol b/lib/openzeppelin-contracts/contracts/access/manager/IAuthority.sol deleted file mode 100644 index e2d3898..0000000 --- a/lib/openzeppelin-contracts/contracts/access/manager/IAuthority.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (access/manager/IAuthority.sol) - -pragma solidity ^0.8.20; - -/** - * @dev Standard interface for permissioning originally defined in Dappsys. - */ -interface IAuthority { - /** - * @dev Returns true if the caller can invoke on a target the function identified by a function selector. - */ - function canCall(address caller, address target, bytes4 selector) external view returns (bool allowed); -} diff --git a/lib/openzeppelin-contracts/contracts/finance/README.adoc b/lib/openzeppelin-contracts/contracts/finance/README.adoc deleted file mode 100644 index c855cbb..0000000 --- a/lib/openzeppelin-contracts/contracts/finance/README.adoc +++ /dev/null @@ -1,14 +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: - -- {VestingWallet} handles the vesting of Ether and ERC-20 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 - -{{VestingWallet}} diff --git a/lib/openzeppelin-contracts/contracts/finance/VestingWallet.sol b/lib/openzeppelin-contracts/contracts/finance/VestingWallet.sol deleted file mode 100644 index f472b66..0000000 --- a/lib/openzeppelin-contracts/contracts/finance/VestingWallet.sol +++ /dev/null @@ -1,154 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (finance/VestingWallet.sol) -pragma solidity ^0.8.20; - -import {IERC20} from "../token/ERC20/IERC20.sol"; -import {SafeERC20} from "../token/ERC20/utils/SafeERC20.sol"; -import {Address} from "../utils/Address.sol"; -import {Context} from "../utils/Context.sol"; -import {Ownable} from "../access/Ownable.sol"; - -/** - * @dev A vesting wallet is an ownable contract that can receive native currency and ERC-20 tokens, and release these - * assets to the wallet owner, also referred to as "beneficiary", according to a vesting schedule. - * - * Any assets 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. - * - * By setting the duration to 0, one can configure this contract to behave like an asset timelock that hold tokens for - * a beneficiary until a specified time. - * - * NOTE: Since the wallet is {Ownable}, and ownership can be transferred, it is possible to sell unvested tokens. - * Preventing this in a smart contract is difficult, considering that: 1) a beneficiary address could be a - * counterfactually deployed contract, 2) there is likely to be a migration path for EOAs to become contracts in the - * near future. - * - * NOTE: When using this contract with any token whose balance is adjusted automatically (i.e. a rebase token), make - * sure to account the supply/balance adjustment in the vesting schedule to ensure the vested amount is as intended. - */ -contract VestingWallet is Context, Ownable { - event EtherReleased(uint256 amount); - event ERC20Released(address indexed token, uint256 amount); - - uint256 private _released; - mapping(address token => uint256) private _erc20Released; - uint64 private immutable _start; - uint64 private immutable _duration; - - /** - * @dev Sets the sender as the initial owner, the beneficiary as the pending owner, the start timestamp and the - * vesting duration of the vesting wallet. - */ - constructor(address beneficiary, uint64 startTimestamp, uint64 durationSeconds) payable Ownable(beneficiary) { - _start = startTimestamp; - _duration = durationSeconds; - } - - /** - * @dev The contract should be able to receive Eth. - */ - receive() external payable virtual {} - - /** - * @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 Getter for the end timestamp. - */ - function end() public view virtual returns (uint256) { - return start() + 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); - Address.sendValue(payable(owner()), 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); - SafeERC20.safeTransfer(IERC20(token), owner(), 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(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 >= end()) { - return totalAllocation; - } else { - return (totalAllocation * (timestamp - start())) / duration(); - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/finance/VestingWalletCliff.sol b/lib/openzeppelin-contracts/contracts/finance/VestingWalletCliff.sol deleted file mode 100644 index d98be64..0000000 --- a/lib/openzeppelin-contracts/contracts/finance/VestingWalletCliff.sol +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {SafeCast} from "../utils/math/SafeCast.sol"; -import {VestingWallet} from "./VestingWallet.sol"; - -/** - * @dev Extension of {VestingWallet} that adds a cliff to the vesting schedule. - */ -abstract contract VestingWalletCliff is VestingWallet { - using SafeCast for *; - - uint64 private immutable _cliff; - - /// @dev The specified cliff duration is larger than the vesting duration. - error InvalidCliffDuration(uint64 cliffSeconds, uint64 durationSeconds); - - /** - * @dev Sets the sender as the initial owner, the beneficiary as the pending owner, the start timestamp, the - * vesting duration and the duration of the cliff of the vesting wallet. - */ - constructor(uint64 cliffSeconds) { - if (cliffSeconds > duration()) { - revert InvalidCliffDuration(cliffSeconds, duration().toUint64()); - } - _cliff = start().toUint64() + cliffSeconds; - } - - /** - * @dev Getter for the cliff timestamp. - */ - function cliff() public view virtual returns (uint256) { - return _cliff; - } - - /** - * @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. Returns 0 if the {cliff} timestamp is not met. - * - * IMPORTANT: The cliff not only makes the schedule return 0, but it also ignores every possible side - * effect from calling the inherited implementation (i.e. `super._vestingSchedule`). Carefully consider - * this caveat if the overridden implementation of this function has any (e.g. writing to memory or reverting). - */ - function _vestingSchedule( - uint256 totalAllocation, - uint64 timestamp - ) internal view virtual override returns (uint256) { - return timestamp < cliff() ? 0 : super._vestingSchedule(totalAllocation, timestamp); - } -} diff --git a/lib/openzeppelin-contracts/contracts/governance/Governor.sol b/lib/openzeppelin-contracts/contracts/governance/Governor.sol deleted file mode 100644 index be2cf79..0000000 --- a/lib/openzeppelin-contracts/contracts/governance/Governor.sol +++ /dev/null @@ -1,852 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (governance/Governor.sol) - -pragma solidity ^0.8.20; - -import {IERC721Receiver} from "../token/ERC721/IERC721Receiver.sol"; -import {IERC1155Receiver} from "../token/ERC1155/IERC1155Receiver.sol"; -import {EIP712} from "../utils/cryptography/EIP712.sol"; -import {SignatureChecker} from "../utils/cryptography/SignatureChecker.sol"; -import {IERC165, ERC165} from "../utils/introspection/ERC165.sol"; -import {SafeCast} from "../utils/math/SafeCast.sol"; -import {DoubleEndedQueue} from "../utils/structs/DoubleEndedQueue.sol"; -import {Address} from "../utils/Address.sol"; -import {Context} from "../utils/Context.sol"; -import {Nonces} from "../utils/Nonces.sol"; -import {IGovernor, IERC6372} from "./IGovernor.sol"; - -/** - * @dev Core of the governance system, designed to be extended through various modules. - * - * This contract is abstract and requires several functions to be implemented in various modules: - * - * - A counting module must implement {quorum}, {_quorumReached}, {_voteSucceeded} and {_countVote} - * - A voting module must implement {_getVotes} - * - Additionally, {votingPeriod} must also be implemented - */ -abstract contract Governor is Context, ERC165, EIP712, Nonces, IGovernor, IERC721Receiver, IERC1155Receiver { - using DoubleEndedQueue for DoubleEndedQueue.Bytes32Deque; - - bytes32 public constant BALLOT_TYPEHASH = - keccak256("Ballot(uint256 proposalId,uint8 support,address voter,uint256 nonce)"); - bytes32 public constant EXTENDED_BALLOT_TYPEHASH = - keccak256( - "ExtendedBallot(uint256 proposalId,uint8 support,address voter,uint256 nonce,string reason,bytes params)" - ); - - struct ProposalCore { - address proposer; - uint48 voteStart; - uint32 voteDuration; - bool executed; - bool canceled; - uint48 etaSeconds; - } - - bytes32 private constant ALL_PROPOSAL_STATES_BITMAP = bytes32((2 ** (uint8(type(ProposalState).max) + 1)) - 1); - string private _name; - - mapping(uint256 proposalId => 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 {execute}, consumed by the - // {onlyGovernance} modifier and eventually reset after {_executeOperations} completes. 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() { - _checkGovernance(); - _; - } - - /** - * @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 { - if (_executor() != address(this)) { - revert GovernorDisabledDeposit(); - } - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { - return - interfaceId == type(IGovernor).interfaceId || - interfaceId == type(IERC1155Receiver).interfaceId || - super.supportsInterface(interfaceId); - } - - /** - * @dev See {IGovernor-name}. - */ - function name() public view virtual returns (string memory) { - return _name; - } - - /** - * @dev See {IGovernor-version}. - */ - function version() public view virtual 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 returns (uint256) { - return uint256(keccak256(abi.encode(targets, values, calldatas, descriptionHash))); - } - - /** - * @dev See {IGovernor-state}. - */ - function state(uint256 proposalId) public view virtual returns (ProposalState) { - // We read the struct fields into the stack at once so Solidity emits a single SLOAD - ProposalCore storage proposal = _proposals[proposalId]; - bool proposalExecuted = proposal.executed; - bool proposalCanceled = proposal.canceled; - - if (proposalExecuted) { - return ProposalState.Executed; - } - - if (proposalCanceled) { - return ProposalState.Canceled; - } - - uint256 snapshot = proposalSnapshot(proposalId); - - if (snapshot == 0) { - revert GovernorNonexistentProposal(proposalId); - } - - uint256 currentTimepoint = clock(); - - if (snapshot >= currentTimepoint) { - return ProposalState.Pending; - } - - uint256 deadline = proposalDeadline(proposalId); - - if (deadline >= currentTimepoint) { - return ProposalState.Active; - } else if (!_quorumReached(proposalId) || !_voteSucceeded(proposalId)) { - return ProposalState.Defeated; - } else if (proposalEta(proposalId) == 0) { - return ProposalState.Succeeded; - } else { - return ProposalState.Queued; - } - } - - /** - * @dev See {IGovernor-proposalThreshold}. - */ - function proposalThreshold() public view virtual returns (uint256) { - return 0; - } - - /** - * @dev See {IGovernor-proposalSnapshot}. - */ - function proposalSnapshot(uint256 proposalId) public view virtual returns (uint256) { - return _proposals[proposalId].voteStart; - } - - /** - * @dev See {IGovernor-proposalDeadline}. - */ - function proposalDeadline(uint256 proposalId) public view virtual returns (uint256) { - return _proposals[proposalId].voteStart + _proposals[proposalId].voteDuration; - } - - /** - * @dev See {IGovernor-proposalProposer}. - */ - function proposalProposer(uint256 proposalId) public view virtual returns (address) { - return _proposals[proposalId].proposer; - } - - /** - * @dev See {IGovernor-proposalEta}. - */ - function proposalEta(uint256 proposalId) public view virtual returns (uint256) { - return _proposals[proposalId].etaSeconds; - } - - /** - * @dev See {IGovernor-proposalNeedsQueuing}. - */ - function proposalNeedsQueuing(uint256) public view virtual returns (bool) { - return false; - } - - /** - * @dev Reverts if the `msg.sender` is not the executor. In case the executor is not this contract - * itself, the function reverts if `msg.data` is not whitelisted as a result of an {execute} - * operation. See {onlyGovernance}. - */ - function _checkGovernance() internal virtual { - if (_executor() != _msgSender()) { - revert GovernorOnlyExecutor(_msgSender()); - } - 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 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 `timepoint`, for a vote as described by `params`. - */ - function _getVotes(address account, uint256 timepoint, 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 totalWeight, - bytes memory params - ) internal virtual returns (uint256); - - /** - * @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}. This function has opt-in frontrunning protection, described in {_isValidDescriptionForProposer}. - */ - function propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description - ) public virtual returns (uint256) { - address proposer = _msgSender(); - - // check description restriction - if (!_isValidDescriptionForProposer(proposer, description)) { - revert GovernorRestrictedProposer(proposer); - } - - // check proposal threshold - uint256 votesThreshold = proposalThreshold(); - if (votesThreshold > 0) { - uint256 proposerVotes = getVotes(proposer, clock() - 1); - if (proposerVotes < votesThreshold) { - revert GovernorInsufficientProposerVotes(proposer, proposerVotes, votesThreshold); - } - } - - return _propose(targets, values, calldatas, description, proposer); - } - - /** - * @dev Internal propose mechanism. Can be overridden to add more logic on proposal creation. - * - * Emits a {IGovernor-ProposalCreated} event. - */ - function _propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description, - address proposer - ) internal virtual returns (uint256 proposalId) { - proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description))); - - if (targets.length != values.length || targets.length != calldatas.length || targets.length == 0) { - revert GovernorInvalidProposalLength(targets.length, calldatas.length, values.length); - } - if (_proposals[proposalId].voteStart != 0) { - revert GovernorUnexpectedProposalState(proposalId, state(proposalId), bytes32(0)); - } - - uint256 snapshot = clock() + votingDelay(); - uint256 duration = votingPeriod(); - - ProposalCore storage proposal = _proposals[proposalId]; - proposal.proposer = proposer; - proposal.voteStart = SafeCast.toUint48(snapshot); - proposal.voteDuration = SafeCast.toUint32(duration); - - emit ProposalCreated( - proposalId, - proposer, - targets, - values, - new string[](targets.length), - calldatas, - snapshot, - snapshot + duration, - description - ); - - // Using a named return variable to avoid stack too deep errors - } - - /** - * @dev See {IGovernor-queue}. - */ - function queue( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) public virtual returns (uint256) { - uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); - - _validateStateBitmap(proposalId, _encodeStateBitmap(ProposalState.Succeeded)); - - uint48 etaSeconds = _queueOperations(proposalId, targets, values, calldatas, descriptionHash); - - if (etaSeconds != 0) { - _proposals[proposalId].etaSeconds = etaSeconds; - emit ProposalQueued(proposalId, etaSeconds); - } else { - revert GovernorQueueNotImplemented(); - } - - return proposalId; - } - - /** - * @dev Internal queuing mechanism. Can be overridden (without a super call) to modify the way queuing is - * performed (for example adding a vault/timelock). - * - * This is empty by default, and must be overridden to implement queuing. - * - * This function returns a timestamp that describes the expected ETA for execution. If the returned value is 0 - * (which is the default value), the core will consider queueing did not succeed, and the public {queue} function - * will revert. - * - * NOTE: Calling this function directly will NOT check the current state of the proposal, or emit the - * `ProposalQueued` event. Queuing a proposal should be done using {queue}. - */ - function _queueOperations( - uint256 /*proposalId*/, - address[] memory /*targets*/, - uint256[] memory /*values*/, - bytes[] memory /*calldatas*/, - bytes32 /*descriptionHash*/ - ) internal virtual returns (uint48) { - return 0; - } - - /** - * @dev See {IGovernor-execute}. - */ - function execute( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) public payable virtual returns (uint256) { - uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); - - _validateStateBitmap( - proposalId, - _encodeStateBitmap(ProposalState.Succeeded) | _encodeStateBitmap(ProposalState.Queued) - ); - - // mark as executed before calls to avoid reentrancy - _proposals[proposalId].executed = true; - - // before execute: register governance call in queue. - if (_executor() != address(this)) { - for (uint256 i = 0; i < targets.length; ++i) { - if (targets[i] == address(this)) { - _governanceCall.pushBack(keccak256(calldatas[i])); - } - } - } - - _executeOperations(proposalId, targets, values, calldatas, descriptionHash); - - // after execute: cleanup governance call queue. - if (_executor() != address(this) && !_governanceCall.empty()) { - _governanceCall.clear(); - } - - emit ProposalExecuted(proposalId); - - return proposalId; - } - - /** - * @dev Internal execution mechanism. Can be overridden (without a super call) to modify the way execution is - * performed (for example adding a vault/timelock). - * - * NOTE: Calling this function directly will NOT check the current state of the proposal, set the executed flag to - * true or emit the `ProposalExecuted` event. Executing a proposal should be done using {execute} or {_execute}. - */ - function _executeOperations( - uint256 /* proposalId */, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 /*descriptionHash*/ - ) internal virtual { - 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); - } - } - - /** - * @dev See {IGovernor-cancel}. - */ - function cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) public virtual returns (uint256) { - // The proposalId will be recomputed in the `_cancel` call further down. However we need the value before we - // do the internal call, because we need to check the proposal state BEFORE the internal `_cancel` call - // changes it. The `hashProposal` duplication has a cost that is limited, and that we accept. - uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); - - // public cancel restrictions (on top of existing _cancel restrictions). - _validateStateBitmap(proposalId, _encodeStateBitmap(ProposalState.Pending)); - if (_msgSender() != proposalProposer(proposalId)) { - revert GovernorOnlyProposer(_msgSender()); - } - - return _cancel(targets, values, calldatas, descriptionHash); - } - - /** - * @dev Internal cancel mechanism with minimal restrictions. A proposal can be cancelled in any state other than - * Canceled, Expired, or Executed. Once cancelled a proposal can't be re-submitted. - * - * 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); - - _validateStateBitmap( - proposalId, - ALL_PROPOSAL_STATES_BITMAP ^ - _encodeStateBitmap(ProposalState.Canceled) ^ - _encodeStateBitmap(ProposalState.Expired) ^ - _encodeStateBitmap(ProposalState.Executed) - ); - - _proposals[proposalId].canceled = true; - emit ProposalCanceled(proposalId); - - return proposalId; - } - - /** - * @dev See {IGovernor-getVotes}. - */ - function getVotes(address account, uint256 timepoint) public view virtual returns (uint256) { - return _getVotes(account, timepoint, _defaultParams()); - } - - /** - * @dev See {IGovernor-getVotesWithParams}. - */ - function getVotesWithParams( - address account, - uint256 timepoint, - bytes memory params - ) public view virtual returns (uint256) { - return _getVotes(account, timepoint, params); - } - - /** - * @dev See {IGovernor-castVote}. - */ - function castVote(uint256 proposalId, uint8 support) public virtual 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 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 returns (uint256) { - address voter = _msgSender(); - return _castVote(proposalId, voter, support, reason, params); - } - - /** - * @dev See {IGovernor-castVoteBySig}. - */ - function castVoteBySig( - uint256 proposalId, - uint8 support, - address voter, - bytes memory signature - ) public virtual returns (uint256) { - bool valid = SignatureChecker.isValidSignatureNow( - voter, - _hashTypedDataV4(keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support, voter, _useNonce(voter)))), - signature - ); - - if (!valid) { - revert GovernorInvalidSignature(voter); - } - - return _castVote(proposalId, voter, support, ""); - } - - /** - * @dev See {IGovernor-castVoteWithReasonAndParamsBySig}. - */ - function castVoteWithReasonAndParamsBySig( - uint256 proposalId, - uint8 support, - address voter, - string calldata reason, - bytes memory params, - bytes memory signature - ) public virtual returns (uint256) { - bool valid = SignatureChecker.isValidSignatureNow( - voter, - _hashTypedDataV4( - keccak256( - abi.encode( - EXTENDED_BALLOT_TYPEHASH, - proposalId, - support, - voter, - _useNonce(voter), - keccak256(bytes(reason)), - keccak256(params) - ) - ) - ), - signature - ); - - if (!valid) { - revert GovernorInvalidSignature(voter); - } - - 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) { - _validateStateBitmap(proposalId, _encodeStateBitmap(ProposalState.Active)); - - uint256 totalWeight = _getVotes(account, proposalSnapshot(proposalId), params); - uint256 votedWeight = _countVote(proposalId, account, support, totalWeight, params); - - if (params.length == 0) { - emit VoteCast(account, proposalId, support, votedWeight, reason); - } else { - emit VoteCastWithParams(account, proposalId, support, votedWeight, reason, params); - } - - return votedWeight; - } - - /** - * @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); - Address.verifyCallResult(success, returndata); - } - - /** - * @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}. - * Receiving tokens is disabled if the governance executor is other than the governor itself (eg. when using with a timelock). - */ - function onERC721Received(address, address, uint256, bytes memory) public virtual returns (bytes4) { - if (_executor() != address(this)) { - revert GovernorDisabledDeposit(); - } - return this.onERC721Received.selector; - } - - /** - * @dev See {IERC1155Receiver-onERC1155Received}. - * Receiving tokens is disabled if the governance executor is other than the governor itself (eg. when using with a timelock). - */ - function onERC1155Received(address, address, uint256, uint256, bytes memory) public virtual returns (bytes4) { - if (_executor() != address(this)) { - revert GovernorDisabledDeposit(); - } - return this.onERC1155Received.selector; - } - - /** - * @dev See {IERC1155Receiver-onERC1155BatchReceived}. - * Receiving tokens is disabled if the governance executor is other than the governor itself (eg. when using with a timelock). - */ - function onERC1155BatchReceived( - address, - address, - uint256[] memory, - uint256[] memory, - bytes memory - ) public virtual returns (bytes4) { - if (_executor() != address(this)) { - revert GovernorDisabledDeposit(); - } - return this.onERC1155BatchReceived.selector; - } - - /** - * @dev Encodes a `ProposalState` into a `bytes32` representation where each bit enabled corresponds to - * the underlying position in the `ProposalState` enum. For example: - * - * 0x000...10000 - * ^^^^^^------ ... - * ^----- Succeeded - * ^---- Defeated - * ^--- Canceled - * ^-- Active - * ^- Pending - */ - function _encodeStateBitmap(ProposalState proposalState) internal pure returns (bytes32) { - return bytes32(1 << uint8(proposalState)); - } - - /** - * @dev Check that the current state of a proposal matches the requirements described by the `allowedStates` bitmap. - * This bitmap should be built using `_encodeStateBitmap`. - * - * If requirements are not met, reverts with a {GovernorUnexpectedProposalState} error. - */ - function _validateStateBitmap(uint256 proposalId, bytes32 allowedStates) private view returns (ProposalState) { - ProposalState currentState = state(proposalId); - if (_encodeStateBitmap(currentState) & allowedStates == bytes32(0)) { - revert GovernorUnexpectedProposalState(proposalId, currentState, allowedStates); - } - return currentState; - } - - /* - * @dev Check if the proposer is authorized to submit a proposal with the given description. - * - * If the proposal description ends with `#proposer=0x???`, where `0x???` is an address written as a hex string - * (case insensitive), then the submission of this proposal will only be authorized to said address. - * - * This is used for frontrunning protection. By adding this pattern at the end of their proposal, one can ensure - * that no other address can submit the same proposal. An attacker would have to either remove or change that part, - * which would result in a different proposal id. - * - * If the description does not match this pattern, it is unrestricted and anyone can submit it. This includes: - * - If the `0x???` part is not a valid hex string. - * - If the `0x???` part is a valid hex string, but does not contain exactly 40 hex digits. - * - If it ends with the expected suffix followed by newlines or other whitespace. - * - If it ends with some other similar suffix, e.g. `#other=abc`. - * - If it does not end with any such suffix. - */ - function _isValidDescriptionForProposer( - address proposer, - string memory description - ) internal view virtual returns (bool) { - uint256 len = bytes(description).length; - - // Length is too short to contain a valid proposer suffix - if (len < 52) { - return true; - } - - // Extract what would be the `#proposer=0x` marker beginning the suffix - bytes12 marker; - assembly { - // - Start of the string contents in memory = description + 32 - // - First character of the marker = len - 52 - // - Length of "#proposer=0x0000000000000000000000000000000000000000" = 52 - // - We read the memory word starting at the first character of the marker: - // - (description + 32) + (len - 52) = description + (len - 20) - // - Note: Solidity will ignore anything past the first 12 bytes - marker := mload(add(description, sub(len, 20))) - } - - // If the marker is not found, there is no proposer suffix to check - if (marker != bytes12("#proposer=0x")) { - return true; - } - - // Parse the 40 characters following the marker as uint160 - uint160 recovered = 0; - for (uint256 i = len - 40; i < len; ++i) { - (bool isHex, uint8 value) = _tryHexToUint(bytes(description)[i]); - // If any of the characters is not a hex digit, ignore the suffix entirely - if (!isHex) { - return true; - } - recovered = (recovered << 4) | value; - } - - return recovered == uint160(proposer); - } - - /** - * @dev Try to parse a character from a string as a hex value. Returns `(true, value)` if the char is in - * `[0-9a-fA-F]` and `(false, 0)` otherwise. Value is guaranteed to be in the range `0 <= value < 16` - */ - function _tryHexToUint(bytes1 char) private pure returns (bool, uint8) { - uint8 c = uint8(char); - unchecked { - // Case 0-9 - if (47 < c && c < 58) { - return (true, c - 48); - } - // Case A-F - else if (64 < c && c < 71) { - return (true, c - 55); - } - // Case a-f - else if (96 < c && c < 103) { - return (true, c - 87); - } - // Else: not a hex char - else { - return (false, 0); - } - } - } - - /** - * @inheritdoc IERC6372 - */ - function clock() public view virtual returns (uint48); - - /** - * @inheritdoc IERC6372 - */ - // solhint-disable-next-line func-name-mixedcase - function CLOCK_MODE() public view virtual returns (string memory); - - /** - * @inheritdoc IGovernor - */ - function votingDelay() public view virtual returns (uint256); - - /** - * @inheritdoc IGovernor - */ - function votingPeriod() public view virtual returns (uint256); - - /** - * @inheritdoc IGovernor - */ - function quorum(uint256 timepoint) public view virtual returns (uint256); -} diff --git a/lib/openzeppelin-contracts/contracts/governance/IGovernor.sol b/lib/openzeppelin-contracts/contracts/governance/IGovernor.sol deleted file mode 100644 index a35aa18..0000000 --- a/lib/openzeppelin-contracts/contracts/governance/IGovernor.sol +++ /dev/null @@ -1,438 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (governance/IGovernor.sol) - -pragma solidity ^0.8.20; - -import {IERC165} from "../interfaces/IERC165.sol"; -import {IERC6372} from "../interfaces/IERC6372.sol"; - -/** - * @dev Interface of the {Governor} core. - */ -interface IGovernor is IERC165, IERC6372 { - enum ProposalState { - Pending, - Active, - Canceled, - Defeated, - Succeeded, - Queued, - Expired, - Executed - } - - /** - * @dev Empty proposal or a mismatch between the parameters length for a proposal call. - */ - error GovernorInvalidProposalLength(uint256 targets, uint256 calldatas, uint256 values); - - /** - * @dev The vote was already cast. - */ - error GovernorAlreadyCastVote(address voter); - - /** - * @dev Token deposits are disabled in this contract. - */ - error GovernorDisabledDeposit(); - - /** - * @dev The `account` is not a proposer. - */ - error GovernorOnlyProposer(address account); - - /** - * @dev The `account` is not the governance executor. - */ - error GovernorOnlyExecutor(address account); - - /** - * @dev The `proposalId` doesn't exist. - */ - error GovernorNonexistentProposal(uint256 proposalId); - - /** - * @dev The current state of a proposal is not the required for performing an operation. - * The `expectedStates` is a bitmap with the bits enabled for each ProposalState enum position - * counting from right to left. - * - * NOTE: If `expectedState` is `bytes32(0)`, the proposal is expected to not be in any state (i.e. not exist). - * This is the case when a proposal that is expected to be unset is already initiated (the proposal is duplicated). - * - * See {Governor-_encodeStateBitmap}. - */ - error GovernorUnexpectedProposalState(uint256 proposalId, ProposalState current, bytes32 expectedStates); - - /** - * @dev The voting period set is not a valid period. - */ - error GovernorInvalidVotingPeriod(uint256 votingPeriod); - - /** - * @dev The `proposer` does not have the required votes to create a proposal. - */ - error GovernorInsufficientProposerVotes(address proposer, uint256 votes, uint256 threshold); - - /** - * @dev The `proposer` is not allowed to create a proposal. - */ - error GovernorRestrictedProposer(address proposer); - - /** - * @dev The vote type used is not valid for the corresponding counting module. - */ - error GovernorInvalidVoteType(); - - /** - * @dev The provided params buffer is not supported by the counting module. - */ - error GovernorInvalidVoteParams(); - - /** - * @dev Queue operation is not implemented for this governor. Execute should be called directly. - */ - error GovernorQueueNotImplemented(); - - /** - * @dev The proposal hasn't been queued yet. - */ - error GovernorNotQueuedProposal(uint256 proposalId); - - /** - * @dev The proposal has already been queued. - */ - error GovernorAlreadyQueuedProposal(uint256 proposalId); - - /** - * @dev The provided signature is not valid for the expected `voter`. - * If the `voter` is a contract, the signature is not valid using {IERC1271-isValidSignature}. - */ - error GovernorInvalidSignature(address voter); - - /** - * @dev Emitted when a proposal is created. - */ - event ProposalCreated( - uint256 proposalId, - address proposer, - address[] targets, - uint256[] values, - string[] signatures, - bytes[] calldatas, - uint256 voteStart, - uint256 voteEnd, - string description - ); - - /** - * @dev Emitted when a proposal is queued. - */ - event ProposalQueued(uint256 proposalId, uint256 etaSeconds); - - /** - * @dev Emitted when a proposal is executed. - */ - event ProposalExecuted(uint256 proposalId); - - /** - * @dev Emitted when a proposal is canceled. - */ - event ProposalCanceled(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 interpretation 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 EIP-712 domain separator). - */ - function name() external view returns (string memory); - - /** - * @notice module:core - * @dev Version of the governor instance (used in building the EIP-712 domain separator). Default: "1" - */ - function version() external view 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() external view 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 - ) external pure returns (uint256); - - /** - * @notice module:core - * @dev Current state of a proposal, following Compound's convention - */ - function state(uint256 proposalId) external view returns (ProposalState); - - /** - * @notice module:core - * @dev The number of votes required in order for a voter to become a proposer. - */ - function proposalThreshold() external view returns (uint256); - - /** - * @notice module:core - * @dev Timepoint used to retrieve user's votes and quorum. If using block number (as per Compound's Comp), 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) external view returns (uint256); - - /** - * @notice module:core - * @dev Timepoint at which votes close. If using block number, votes close at the end of this block, so it is - * possible to cast a vote during this block. - */ - function proposalDeadline(uint256 proposalId) external view returns (uint256); - - /** - * @notice module:core - * @dev The account that created a proposal. - */ - function proposalProposer(uint256 proposalId) external view returns (address); - - /** - * @notice module:core - * @dev The time when a queued proposal becomes executable ("ETA"). Unlike {proposalSnapshot} and - * {proposalDeadline}, this doesn't use the governor clock, and instead relies on the executor's clock which may be - * different. In most cases this will be a timestamp. - */ - function proposalEta(uint256 proposalId) external view returns (uint256); - - /** - * @notice module:core - * @dev Whether a proposal needs to be queued before execution. - */ - function proposalNeedsQueuing(uint256 proposalId) external view returns (bool); - - /** - * @notice module:user-config - * @dev Delay, between the proposal is created and the vote starts. The unit this duration is expressed in depends - * on the clock (see ERC-6372) this contract uses. - * - * This can be increased to leave time for users to buy voting power, or delegate it, before the voting of a - * proposal starts. - * - * NOTE: While this interface returns a uint256, timepoints are stored as uint48 following the ERC-6372 clock type. - * Consequently this value must fit in a uint48 (when added to the current clock). See {IERC6372-clock}. - */ - function votingDelay() external view returns (uint256); - - /** - * @notice module:user-config - * @dev Delay between the vote start and vote end. The unit this duration is expressed in depends on the clock - * (see ERC-6372) this contract uses. - * - * NOTE: The {votingDelay} can delay the start of the vote. This must be considered when setting the voting - * duration compared to the voting delay. - * - * NOTE: This value is stored when the proposal is submitted so that possible changes to the value do not affect - * proposals that have already been submitted. The type used to save it is a uint32. Consequently, while this - * interface returns a uint256, the value it returns should fit in a uint32. - */ - function votingPeriod() external view returns (uint256); - - /** - * @notice module:user-config - * @dev Minimum number of cast voted required for a proposal to be successful. - * - * NOTE: The `timepoint` 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 timepoint (see {ERC20Votes}). - */ - function quorum(uint256 timepoint) external view returns (uint256); - - /** - * @notice module:reputation - * @dev Voting power of an `account` at a specific `timepoint`. - * - * 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 timepoint) external view returns (uint256); - - /** - * @notice module:reputation - * @dev Voting power of an `account` at a specific `timepoint` given additional encoded parameters. - */ - function getVotesWithParams( - address account, - uint256 timepoint, - bytes memory params - ) external view returns (uint256); - - /** - * @notice module:voting - * @dev Returns whether `account` has cast a vote on `proposalId`. - */ - function hasVoted(uint256 proposalId, address account) external view returns (bool); - - /** - * @dev Create a new proposal. Vote start after a delay specified by {IGovernor-votingDelay} and lasts for a - * duration specified by {IGovernor-votingPeriod}. - * - * Emits a {ProposalCreated} event. - * - * NOTE: The state of the Governor and `targets` may change between the proposal creation and its execution. - * This may be the result of third party actions on the targeted contracts, or other governor proposals. - * For example, the balance of this contract could be updated or its access control permissions may be modified, - * possibly compromising the proposal's ability to execute successfully (e.g. the governor doesn't have enough - * value to cover a proposal with multiple transfers). - */ - function propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description - ) external returns (uint256 proposalId); - - /** - * @dev Queue a proposal. Some governors require this step to be performed before execution can happen. If queuing - * is not necessary, this function may revert. - * Queuing a proposal requires the quorum to be reached, the vote to be successful, and the deadline to be reached. - * - * Emits a {ProposalQueued} event. - */ - function queue( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) external 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. Depending on the governor it might also be required that the proposal was queued and - * that some delay passed. - * - * Emits a {ProposalExecuted} event. - * - * NOTE: Some modules 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 - ) external payable returns (uint256 proposalId); - - /** - * @dev Cancel a proposal. A proposal is cancellable by the proposer, but only while it is Pending state, i.e. - * before the vote starts. - * - * Emits a {ProposalCanceled} event. - */ - function cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) external returns (uint256 proposalId); - - /** - * @dev Cast a vote - * - * Emits a {VoteCast} event. - */ - function castVote(uint256 proposalId, uint8 support) external returns (uint256 balance); - - /** - * @dev Cast a vote with a reason - * - * Emits a {VoteCast} event. - */ - function castVoteWithReason( - uint256 proposalId, - uint8 support, - string calldata reason - ) external 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 - ) external returns (uint256 balance); - - /** - * @dev Cast a vote using the voter's signature, including ERC-1271 signature support. - * - * Emits a {VoteCast} event. - */ - function castVoteBySig( - uint256 proposalId, - uint8 support, - address voter, - bytes memory signature - ) external returns (uint256 balance); - - /** - * @dev Cast a vote with a reason and additional encoded parameters using the voter's signature, - * including ERC-1271 signature support. - * - * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length of params. - */ - function castVoteWithReasonAndParamsBySig( - uint256 proposalId, - uint8 support, - address voter, - string calldata reason, - bytes memory params, - bytes memory signature - ) external returns (uint256 balance); -} diff --git a/lib/openzeppelin-contracts/contracts/governance/README.adoc b/lib/openzeppelin-contracts/contracts/governance/README.adoc deleted file mode 100644 index da678f4..0000000 --- a/lib/openzeppelin-contracts/contracts/governance/README.adoc +++ /dev/null @@ -1,175 +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}, or since v4.5 an {ERC721Votes} 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. - -* {GovernorCountingFractional}: A more modular voting system that allows a user to vote with only part of its voting power, and to split that weight arbitrarily between the 3 different 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. - -* {GovernorTimelockAccess}: Connects with an instance of an {AccessManager}. This allows restrictions (and delays) enforced by the manager to be considered by the Governor and integrated into the AccessManager's "schedule + execute" workflow. - -* {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. - -* {GovernorStorage}: Stores the proposal details onchain and provides enumerability of the proposals. This can be useful for some L2 chains where storage is cheap compared to calldata. - -* {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 ERC-6372 clock) 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 ERC-6372 clock) since the proposal starts until voting ends. -* <>: Quorum required for a proposal to be successful. This function includes a `timepoint` argument (see ERC-6372) 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}} - -{{GovernorCountingFractional}} - -{{GovernorVotes}} - -{{GovernorVotesQuorumFraction}} - -=== Extensions - -{{GovernorTimelockAccess}} - -{{GovernorTimelockControl}} - -{{GovernorTimelockCompound}} - -{{GovernorSettings}} - -{{GovernorPreventLateQuorum}} - -{{GovernorStorage}} - -== 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. -** *Waiting:* An operation that has been scheduled, before the timer expires. -** *Ready:* An operation that has been scheduled, after the timer expires. -** *Pending:* An operation that is either waiting or ready. -** *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. - -[[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/openzeppelin-contracts/contracts/governance/TimelockController.sol b/lib/openzeppelin-contracts/contracts/governance/TimelockController.sol deleted file mode 100644 index 349d940..0000000 --- a/lib/openzeppelin-contracts/contracts/governance/TimelockController.sol +++ /dev/null @@ -1,472 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (governance/TimelockController.sol) - -pragma solidity ^0.8.20; - -import {AccessControl} from "../access/AccessControl.sol"; -import {ERC721Holder} from "../token/ERC721/utils/ERC721Holder.sol"; -import {ERC1155Holder} from "../token/ERC1155/utils/ERC1155Holder.sol"; -import {Address} from "../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. - */ -contract TimelockController is AccessControl, ERC721Holder, ERC1155Holder { - 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 id => uint256) private _timestamps; - uint256 private _minDelay; - - enum OperationState { - Unset, - Waiting, - Ready, - Done - } - - /** - * @dev Mismatch between the parameters length for an operation call. - */ - error TimelockInvalidOperationLength(uint256 targets, uint256 payloads, uint256 values); - - /** - * @dev The schedule operation doesn't meet the minimum delay. - */ - error TimelockInsufficientDelay(uint256 delay, uint256 minDelay); - - /** - * @dev The current state of an operation is not as required. - * The `expectedStates` is a bitmap with the bits enabled for each OperationState enum position - * counting from right to left. - * - * See {_encodeStateBitmap}. - */ - error TimelockUnexpectedOperationState(bytes32 operationId, bytes32 expectedStates); - - /** - * @dev The predecessor to an operation not yet done. - */ - error TimelockUnexecutedPredecessor(bytes32 predecessorId); - - /** - * @dev The caller account is not authorized. - */ - error TimelockUnauthorizedCaller(address caller); - - /** - * @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 new proposal is scheduled with non-zero salt. - */ - event CallSalt(bytes32 indexed id, bytes32 salt); - - /** - * @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 in seconds 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. - */ - constructor(uint256 minDelay, address[] memory proposers, address[] memory executors, address admin) { - // self administration - _grantRole(DEFAULT_ADMIN_ROLE, address(this)); - - // optional admin - if (admin != address(0)) { - _grantRole(DEFAULT_ADMIN_ROLE, admin); - } - - // register proposers and cancellers - for (uint256 i = 0; i < proposers.length; ++i) { - _grantRole(PROPOSER_ROLE, proposers[i]); - _grantRole(CANCELLER_ROLE, proposers[i]); - } - - // register executors - for (uint256 i = 0; i < executors.length; ++i) { - _grantRole(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(AccessControl, ERC1155Holder) returns (bool) { - return super.supportsInterface(interfaceId); - } - - /** - * @dev Returns whether an id corresponds to a registered operation. This - * includes both Waiting, Ready, and Done operations. - */ - function isOperation(bytes32 id) public view returns (bool) { - return getOperationState(id) != OperationState.Unset; - } - - /** - * @dev Returns whether an operation is pending or not. Note that a "pending" operation may also be "ready". - */ - function isOperationPending(bytes32 id) public view returns (bool) { - OperationState state = getOperationState(id); - return state == OperationState.Waiting || state == OperationState.Ready; - } - - /** - * @dev Returns whether an operation is ready for execution. Note that a "ready" operation is also "pending". - */ - function isOperationReady(bytes32 id) public view returns (bool) { - return getOperationState(id) == OperationState.Ready; - } - - /** - * @dev Returns whether an operation is done or not. - */ - function isOperationDone(bytes32 id) public view returns (bool) { - return getOperationState(id) == OperationState.Done; - } - - /** - * @dev Returns the timestamp at which an operation becomes ready (0 for - * unset operations, 1 for done operations). - */ - function getTimestamp(bytes32 id) public view virtual returns (uint256) { - return _timestamps[id]; - } - - /** - * @dev Returns operation state. - */ - function getOperationState(bytes32 id) public view virtual returns (OperationState) { - uint256 timestamp = getTimestamp(id); - if (timestamp == 0) { - return OperationState.Unset; - } else if (timestamp == _DONE_TIMESTAMP) { - return OperationState.Done; - } else if (timestamp > block.timestamp) { - return OperationState.Waiting; - } else { - return OperationState.Ready; - } - } - - /** - * @dev Returns the minimum delay in seconds 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) { - 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) { - 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) { - return keccak256(abi.encode(targets, values, payloads, predecessor, salt)); - } - - /** - * @dev Schedule an operation containing a single transaction. - * - * Emits {CallSalt} if salt is nonzero, and {CallScheduled}. - * - * 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); - if (salt != bytes32(0)) { - emit CallSalt(id, salt); - } - } - - /** - * @dev Schedule an operation containing a batch of transactions. - * - * Emits {CallSalt} if salt is nonzero, and 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) { - if (targets.length != values.length || targets.length != payloads.length) { - revert TimelockInvalidOperationLength(targets.length, payloads.length, values.length); - } - - 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); - } - if (salt != bytes32(0)) { - emit CallSalt(id, salt); - } - } - - /** - * @dev Schedule an operation that is to become valid after a given delay. - */ - function _schedule(bytes32 id, uint256 delay) private { - if (isOperation(id)) { - revert TimelockUnexpectedOperationState(id, _encodeStateBitmap(OperationState.Unset)); - } - uint256 minDelay = getMinDelay(); - if (delay < minDelay) { - revert TimelockInsufficientDelay(delay, minDelay); - } - _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) { - if (!isOperationPending(id)) { - revert TimelockUnexpectedOperationState( - id, - _encodeStateBitmap(OperationState.Waiting) | _encodeStateBitmap(OperationState.Ready) - ); - } - 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) { - if (targets.length != values.length || targets.length != payloads.length) { - revert TimelockInvalidOperationLength(targets.length, payloads.length, values.length); - } - - 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, bytes memory returndata) = target.call{value: value}(data); - Address.verifyCallResult(success, returndata); - } - - /** - * @dev Checks before execution of an operation's calls. - */ - function _beforeCall(bytes32 id, bytes32 predecessor) private view { - if (!isOperationReady(id)) { - revert TimelockUnexpectedOperationState(id, _encodeStateBitmap(OperationState.Ready)); - } - if (predecessor != bytes32(0) && !isOperationDone(predecessor)) { - revert TimelockUnexecutedPredecessor(predecessor); - } - } - - /** - * @dev Checks after execution of an operation's calls. - */ - function _afterCall(bytes32 id) private { - if (!isOperationReady(id)) { - revert TimelockUnexpectedOperationState(id, _encodeStateBitmap(OperationState.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 { - address sender = _msgSender(); - if (sender != address(this)) { - revert TimelockUnauthorizedCaller(sender); - } - emit MinDelayChange(_minDelay, newDelay); - _minDelay = newDelay; - } - - /** - * @dev Encodes a `OperationState` into a `bytes32` representation where each bit enabled corresponds to - * the underlying position in the `OperationState` enum. For example: - * - * 0x000...1000 - * ^^^^^^----- ... - * ^---- Done - * ^--- Ready - * ^-- Waiting - * ^- Unset - */ - function _encodeStateBitmap(OperationState operationState) internal pure returns (bytes32) { - return bytes32(1 << uint8(operationState)); - } -} diff --git a/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorCountingFractional.sol b/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorCountingFractional.sol deleted file mode 100644 index 5a553fb..0000000 --- a/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorCountingFractional.sol +++ /dev/null @@ -1,193 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {Governor} from "../Governor.sol"; -import {GovernorCountingSimple} from "./GovernorCountingSimple.sol"; -import {Math} from "../../utils/math/Math.sol"; - -/** - * @dev Extension of {Governor} for fractional voting. - * - * Similar to {GovernorCountingSimple}, this contract is a votes counting module for {Governor} that supports 3 options: - * Against, For, Abstain. Additionally, it includes a fourth option: Fractional, which allows voters to split their voting - * power amongst the other 3 options. - * - * Votes cast with the Fractional support must be accompanied by a `params` argument that is three packed `uint128` values - * representing the weight the delegate assigns to Against, For, and Abstain respectively. For those votes cast for the other - * 3 options, the `params` argument must be empty. - * - * This is mostly useful when the delegate is a contract that implements its own rules for voting. These delegate-contracts - * can cast fractional votes according to the preferences of multiple entities delegating their voting power. - * - * Some example use cases include: - * - * * Voting from tokens that are held by a DeFi pool - * * Voting from an L2 with tokens held by a bridge - * * Voting privately from a shielded pool using zero knowledge proofs. - * - * Based on ScopeLift's GovernorCountingFractional[https://github.com/ScopeLift/flexible-voting/blob/e5de2efd1368387b840931f19f3c184c85842761/src/GovernorCountingFractional.sol] - */ -abstract contract GovernorCountingFractional is Governor { - using Math for *; - - uint8 internal constant VOTE_TYPE_FRACTIONAL = 255; - - struct ProposalVote { - uint256 againstVotes; - uint256 forVotes; - uint256 abstainVotes; - mapping(address voter => uint256) usedVotes; - } - - /** - * @dev Mapping from proposal ID to vote tallies for that proposal. - */ - mapping(uint256 => ProposalVote) private _proposalVotes; - - /** - * @dev A fractional vote params uses more votes than are available for that user. - */ - error GovernorExceedRemainingWeight(address voter, uint256 usedVotes, uint256 remainingWeight); - - /** - * @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,fractional&quorum=for,abstain¶ms=fractional"; - } - - /** - * @dev See {IGovernor-hasVoted}. - */ - function hasVoted(uint256 proposalId, address account) public view virtual override returns (bool) { - return usedVotes(proposalId, account) > 0; - } - - /** - * @dev Get the number of votes already cast by `account` for a proposal with `proposalId`. Useful for - * integrations that allow delegates to cast rolling, partial votes. - */ - function usedVotes(uint256 proposalId, address account) public view virtual returns (uint256) { - return _proposalVotes[proposalId].usedVotes[account]; - } - - /** - * @dev Get current distribution of votes for a given proposal. - */ - 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, forVotes must be > 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}. Function that records the delegate's votes. - * - * Executing this function consumes (part of) the delegate's weight on the proposal. This weight can be - * distributed amongst the 3 options (Against, For, Abstain) by specifying a fractional `support`. - * - * This counting module supports two vote casting modes: nominal and fractional. - * - * - Nominal: A nominal vote is cast by setting `support` to one of the 3 bravo options (Against, For, Abstain). - * - Fractional: A fractional vote is cast by setting `support` to `type(uint8).max` (255). - * - * Casting a nominal vote requires `params` to be empty and consumes the delegate's full remaining weight on the - * proposal for the specified `support` option. This is similar to the {GovernorCountingSimple} module and follows - * the `VoteType` enum from Governor Bravo. As a consequence, no vote weight remains unspent so no further voting - * is possible (for this `proposalId` and this `account`). - * - * Casting a fractional vote consumes a fraction of the delegate's remaining weight on the proposal according to the - * weights the delegate assigns to each support option (Against, For, Abstain respectively). The sum total of the - * three decoded vote weights _must_ be less than or equal to the delegate's remaining weight on the proposal (i.e. - * their checkpointed total weight minus votes already cast on the proposal). This format can be produced using: - * - * `abi.encodePacked(uint128(againstVotes), uint128(forVotes), uint128(abstainVotes))` - * - * NOTE: Consider that fractional voting restricts the number of casted vote (in each category) to 128 bits. - * Depending on how many decimals the underlying token has, a single voter may require to split their vote into - * multiple vote operations. For precision higher than ~30 decimals, large token holders may require an - * potentially large number of calls to cast all their votes. The voter has the possibility to cast all the - * remaining votes in a single operation using the traditional "bravo" vote. - */ - // slither-disable-next-line cyclomatic-complexity - function _countVote( - uint256 proposalId, - address account, - uint8 support, - uint256 totalWeight, - bytes memory params - ) internal virtual override returns (uint256) { - // Compute number of remaining votes. Returns 0 on overflow. - (, uint256 remainingWeight) = totalWeight.trySub(usedVotes(proposalId, account)); - if (remainingWeight == 0) { - revert GovernorAlreadyCastVote(account); - } - - uint256 againstVotes = 0; - uint256 forVotes = 0; - uint256 abstainVotes = 0; - uint256 usedWeight; - - // For clarity of event indexing, fractional voting must be clearly advertised in the "support" field. - // - // Supported `support` value must be: - // - "Full" voting: `support = 0` (Against), `1` (For) or `2` (Abstain), with empty params. - // - "Fractional" voting: `support = 255`, with 48 bytes params. - if (support == uint8(GovernorCountingSimple.VoteType.Against)) { - if (params.length != 0) revert GovernorInvalidVoteParams(); - usedWeight = againstVotes = remainingWeight; - } else if (support == uint8(GovernorCountingSimple.VoteType.For)) { - if (params.length != 0) revert GovernorInvalidVoteParams(); - usedWeight = forVotes = remainingWeight; - } else if (support == uint8(GovernorCountingSimple.VoteType.Abstain)) { - if (params.length != 0) revert GovernorInvalidVoteParams(); - usedWeight = abstainVotes = remainingWeight; - } else if (support == VOTE_TYPE_FRACTIONAL) { - // The `params` argument is expected to be three packed `uint128`: - // `abi.encodePacked(uint128(againstVotes), uint128(forVotes), uint128(abstainVotes))` - if (params.length != 0x30) revert GovernorInvalidVoteParams(); - - assembly ("memory-safe") { - againstVotes := shr(128, mload(add(params, 0x20))) - forVotes := shr(128, mload(add(params, 0x30))) - abstainVotes := shr(128, mload(add(params, 0x40))) - usedWeight := add(add(againstVotes, forVotes), abstainVotes) // inputs are uint128: cannot overflow - } - - // check parsed arguments are valid - if (usedWeight > remainingWeight) { - revert GovernorExceedRemainingWeight(account, usedWeight, remainingWeight); - } - } else { - revert GovernorInvalidVoteType(); - } - - // update votes tracking - ProposalVote storage details = _proposalVotes[proposalId]; - if (againstVotes > 0) details.againstVotes += againstVotes; - if (forVotes > 0) details.forVotes += forVotes; - if (abstainVotes > 0) details.abstainVotes += abstainVotes; - details.usedVotes[account] += usedWeight; - - return usedWeight; - } -} diff --git a/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorCountingSimple.sol b/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorCountingSimple.sol deleted file mode 100644 index def29e3..0000000 --- a/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorCountingSimple.sol +++ /dev/null @@ -1,102 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (governance/extensions/GovernorCountingSimple.sol) - -pragma solidity ^0.8.20; - -import {Governor} from "../Governor.sol"; - -/** - * @dev Extension of {Governor} for simple, 3 options, vote counting. - */ -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 voter => bool) hasVoted; - } - - mapping(uint256 proposalId => 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 totalWeight, - bytes memory // params - ) internal virtual override returns (uint256) { - ProposalVote storage proposalVote = _proposalVotes[proposalId]; - - if (proposalVote.hasVoted[account]) { - revert GovernorAlreadyCastVote(account); - } - proposalVote.hasVoted[account] = true; - - if (support == uint8(VoteType.Against)) { - proposalVote.againstVotes += totalWeight; - } else if (support == uint8(VoteType.For)) { - proposalVote.forVotes += totalWeight; - } else if (support == uint8(VoteType.Abstain)) { - proposalVote.abstainVotes += totalWeight; - } else { - revert GovernorInvalidVoteType(); - } - - return totalWeight; - } -} diff --git a/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorPreventLateQuorum.sol b/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorPreventLateQuorum.sol deleted file mode 100644 index ff80af6..0000000 --- a/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorPreventLateQuorum.sol +++ /dev/null @@ -1,102 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (governance/extensions/GovernorPreventLateQuorum.sol) - -pragma solidity ^0.8.20; - -import {Governor} from "../Governor.sol"; -import {Math} from "../../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 specified time has passed (the "vote extension" parameter). This parameter can be set through a governance - * proposal. - */ -abstract contract GovernorPreventLateQuorum is Governor { - uint48 private _voteExtension; - - mapping(uint256 proposalId => uint48) 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 time in either number of blocks or seconds (depending on the - * governor clock mode) that is required to pass since the moment a proposal reaches quorum until its voting period - * ends. If necessary the voting period will be extended beyond the one set during proposal creation. - */ - constructor(uint48 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]); - } - - /** - * @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); - - if (_extendedDeadlines[proposalId] == 0 && _quorumReached(proposalId)) { - uint48 extendedDeadline = clock() + lateQuorumVoteExtension(); - - if (extendedDeadline > proposalDeadline(proposalId)) { - emit ProposalExtended(proposalId, extendedDeadline); - } - - _extendedDeadlines[proposalId] = extendedDeadline; - } - - 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 (uint48) { - 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(uint48 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(uint48 newVoteExtension) internal virtual { - emit LateQuorumVoteExtensionSet(_voteExtension, newVoteExtension); - _voteExtension = newVoteExtension; - } -} diff --git a/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorSettings.sol b/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorSettings.sol deleted file mode 100644 index 7347ee2..0000000 --- a/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorSettings.sol +++ /dev/null @@ -1,112 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (governance/extensions/GovernorSettings.sol) - -pragma solidity ^0.8.20; - -import {Governor} from "../Governor.sol"; - -/** - * @dev Extension of {Governor} for settings updatable through governance. - */ -abstract contract GovernorSettings is Governor { - // amount of token - uint256 private _proposalThreshold; - // timepoint: limited to uint48 in core (same as clock() type) - uint48 private _votingDelay; - // duration: limited to uint32 in core - uint32 private _votingPeriod; - - event VotingDelaySet(uint256 oldVotingDelay, uint256 newVotingDelay); - event VotingPeriodSet(uint256 oldVotingPeriod, uint256 newVotingPeriod); - event ProposalThresholdSet(uint256 oldProposalThreshold, uint256 newProposalThreshold); - - /** - * @dev Initialize the governance parameters. - */ - constructor(uint48 initialVotingDelay, uint32 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(uint48 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(uint32 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(uint48 newVotingDelay) internal virtual { - emit VotingDelaySet(_votingDelay, newVotingDelay); - _votingDelay = newVotingDelay; - } - - /** - * @dev Internal setter for the voting period. - * - * Emits a {VotingPeriodSet} event. - */ - function _setVotingPeriod(uint32 newVotingPeriod) internal virtual { - if (newVotingPeriod == 0) { - revert GovernorInvalidVotingPeriod(0); - } - 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/openzeppelin-contracts/contracts/governance/extensions/GovernorStorage.sol b/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorStorage.sol deleted file mode 100644 index 2547b55..0000000 --- a/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorStorage.sol +++ /dev/null @@ -1,115 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (governance/extensions/GovernorStorage.sol) - -pragma solidity ^0.8.20; - -import {Governor} from "../Governor.sol"; - -/** - * @dev Extension of {Governor} that implements storage of proposal details. This modules also provides primitives for - * the enumerability of proposals. - * - * Use cases for this module include: - * - UIs that explore the proposal state without relying on event indexing. - * - Using only the proposalId as an argument in the {Governor-queue} and {Governor-execute} functions for L2 chains - * where storage is cheap compared to calldata. - */ -abstract contract GovernorStorage is Governor { - struct ProposalDetails { - address[] targets; - uint256[] values; - bytes[] calldatas; - bytes32 descriptionHash; - } - - uint256[] private _proposalIds; - mapping(uint256 proposalId => ProposalDetails) private _proposalDetails; - - /** - * @dev Hook into the proposing mechanism - */ - function _propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description, - address proposer - ) internal virtual override returns (uint256) { - uint256 proposalId = super._propose(targets, values, calldatas, description, proposer); - - // store - _proposalIds.push(proposalId); - _proposalDetails[proposalId] = ProposalDetails({ - targets: targets, - values: values, - calldatas: calldatas, - descriptionHash: keccak256(bytes(description)) - }); - - return proposalId; - } - - /** - * @dev Version of {IGovernorTimelock-queue} with only `proposalId` as an argument. - */ - function queue(uint256 proposalId) public virtual { - // here, using storage is more efficient than memory - ProposalDetails storage details = _proposalDetails[proposalId]; - queue(details.targets, details.values, details.calldatas, details.descriptionHash); - } - - /** - * @dev Version of {IGovernor-execute} with only `proposalId` as an argument. - */ - function execute(uint256 proposalId) public payable virtual { - // here, using storage is more efficient than memory - ProposalDetails storage details = _proposalDetails[proposalId]; - execute(details.targets, details.values, details.calldatas, details.descriptionHash); - } - - /** - * @dev ProposalId version of {IGovernor-cancel}. - */ - function cancel(uint256 proposalId) public virtual { - // here, using storage is more efficient than memory - ProposalDetails storage details = _proposalDetails[proposalId]; - cancel(details.targets, details.values, details.calldatas, details.descriptionHash); - } - - /** - * @dev Returns the number of stored proposals. - */ - function proposalCount() public view virtual returns (uint256) { - return _proposalIds.length; - } - - /** - * @dev Returns the details of a proposalId. Reverts if `proposalId` is not a known proposal. - */ - function proposalDetails( - uint256 proposalId - ) public view virtual returns (address[] memory, uint256[] memory, bytes[] memory, bytes32) { - // here, using memory is more efficient than storage - ProposalDetails memory details = _proposalDetails[proposalId]; - if (details.descriptionHash == 0) { - revert GovernorNonexistentProposal(proposalId); - } - return (details.targets, details.values, details.calldatas, details.descriptionHash); - } - - /** - * @dev Returns the details (including the proposalId) of a proposal given its sequential index. - */ - function proposalDetailsAt( - uint256 index - ) public view virtual returns (uint256, address[] memory, uint256[] memory, bytes[] memory, bytes32) { - uint256 proposalId = _proposalIds[index]; - ( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) = proposalDetails(proposalId); - return (proposalId, targets, values, calldatas, descriptionHash); - } -} diff --git a/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockAccess.sol b/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockAccess.sol deleted file mode 100644 index 6e2c5b8..0000000 --- a/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockAccess.sol +++ /dev/null @@ -1,349 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (governance/extensions/GovernorTimelockAccess.sol) - -pragma solidity ^0.8.20; - -import {Governor} from "../Governor.sol"; -import {AuthorityUtils} from "../../access/manager/AuthorityUtils.sol"; -import {IAccessManager} from "../../access/manager/IAccessManager.sol"; -import {Address} from "../../utils/Address.sol"; -import {Math} from "../../utils/math/Math.sol"; -import {SafeCast} from "../../utils/math/SafeCast.sol"; -import {Time} from "../../utils/types/Time.sol"; - -/** - * @dev This module connects a {Governor} instance to an {AccessManager} instance, allowing the governor to make calls - * that are delay-restricted by the manager using the normal {queue} workflow. An optional base delay is applied to - * operations that are not delayed externally by the manager. Execution of a proposal will be delayed as much as - * necessary to meet the required delays of all of its operations. - * - * This extension allows the governor to hold and use its own assets and permissions, unlike {GovernorTimelockControl} - * and {GovernorTimelockCompound}, where the timelock is a separate contract that must be the one to hold assets and - * permissions. Operations that are delay-restricted by the manager, however, will be executed through the - * {AccessManager-execute} function. - * - * ==== Security Considerations - * - * Some operations may be cancelable in the `AccessManager` by the admin or a set of guardians, depending on the - * restricted function being invoked. Since proposals are atomic, the cancellation by a guardian of a single operation - * in a proposal will cause all of the proposal to become unable to execute. Consider proposing cancellable operations - * separately. - * - * By default, function calls will be routed through the associated `AccessManager` whenever it claims the target - * function to be restricted by it. However, admins may configure the manager to make that claim for functions that a - * governor would want to call directly (e.g., token transfers) in an attempt to deny it access to those functions. To - * mitigate this attack vector, the governor is able to ignore the restrictions claimed by the `AccessManager` using - * {setAccessManagerIgnored}. While permanent denial of service is mitigated, temporary DoS may still be technically - * possible. All of the governor's own functions (e.g., {setBaseDelaySeconds}) ignore the `AccessManager` by default. - * - * NOTE: `AccessManager` does not support scheduling more than one operation with the same target and calldata at - * the same time. See {AccessManager-schedule} for a workaround. - */ -abstract contract GovernorTimelockAccess is Governor { - // An execution plan is produced at the moment a proposal is created, in order to fix at that point the exact - // execution semantics of the proposal, namely whether a call will go through {AccessManager-execute}. - struct ExecutionPlan { - uint16 length; - uint32 delay; - // We use mappings instead of arrays because it allows us to pack values in storage more tightly without - // storing the length redundantly. - // We pack 8 operations' data in each bucket. Each uint32 value is set to 1 upon proposal creation if it has - // to be scheduled and executed through the manager. Upon queuing, the value is set to nonce + 2, where the - // nonce is received from the manager when scheduling the operation. - mapping(uint256 operationBucket => uint32[8]) managerData; - } - - // The meaning of the "toggle" set to true depends on the target contract. - // If target == address(this), the manager is ignored by default, and a true toggle means it won't be ignored. - // For all other target contracts, the manager is used by default, and a true toggle means it will be ignored. - mapping(address target => mapping(bytes4 selector => bool)) private _ignoreToggle; - - mapping(uint256 proposalId => ExecutionPlan) private _executionPlan; - - uint32 private _baseDelay; - - IAccessManager private immutable _manager; - - error GovernorUnmetDelay(uint256 proposalId, uint256 neededTimestamp); - error GovernorMismatchedNonce(uint256 proposalId, uint256 expectedNonce, uint256 actualNonce); - error GovernorLockedIgnore(); - - event BaseDelaySet(uint32 oldBaseDelaySeconds, uint32 newBaseDelaySeconds); - event AccessManagerIgnoredSet(address target, bytes4 selector, bool ignored); - - /** - * @dev Initialize the governor with an {AccessManager} and initial base delay. - */ - constructor(address manager, uint32 initialBaseDelay) { - _manager = IAccessManager(manager); - _setBaseDelaySeconds(initialBaseDelay); - } - - /** - * @dev Returns the {AccessManager} instance associated to this governor. - */ - function accessManager() public view virtual returns (IAccessManager) { - return _manager; - } - - /** - * @dev Base delay that will be applied to all function calls. Some may be further delayed by their associated - * `AccessManager` authority; in this case the final delay will be the maximum of the base delay and the one - * demanded by the authority. - * - * NOTE: Execution delays are processed by the `AccessManager` contracts, and according to that contract are - * expressed in seconds. Therefore, the base delay is also in seconds, regardless of the governor's clock mode. - */ - function baseDelaySeconds() public view virtual returns (uint32) { - return _baseDelay; - } - - /** - * @dev Change the value of {baseDelaySeconds}. This operation can only be invoked through a governance proposal. - */ - function setBaseDelaySeconds(uint32 newBaseDelay) public virtual onlyGovernance { - _setBaseDelaySeconds(newBaseDelay); - } - - /** - * @dev Change the value of {baseDelaySeconds}. Internal function without access control. - */ - function _setBaseDelaySeconds(uint32 newBaseDelay) internal virtual { - emit BaseDelaySet(_baseDelay, newBaseDelay); - _baseDelay = newBaseDelay; - } - - /** - * @dev Check if restrictions from the associated {AccessManager} are ignored for a target function. Returns true - * when the target function will be invoked directly regardless of `AccessManager` settings for the function. - * See {setAccessManagerIgnored} and Security Considerations above. - */ - function isAccessManagerIgnored(address target, bytes4 selector) public view virtual returns (bool) { - bool isGovernor = target == address(this); - return _ignoreToggle[target][selector] != isGovernor; // equivalent to: isGovernor ? !toggle : toggle - } - - /** - * @dev Configure whether restrictions from the associated {AccessManager} are ignored for a target function. - * See Security Considerations above. - */ - function setAccessManagerIgnored( - address target, - bytes4[] calldata selectors, - bool ignored - ) public virtual onlyGovernance { - for (uint256 i = 0; i < selectors.length; ++i) { - _setAccessManagerIgnored(target, selectors[i], ignored); - } - } - - /** - * @dev Internal version of {setAccessManagerIgnored} without access restriction. - */ - function _setAccessManagerIgnored(address target, bytes4 selector, bool ignored) internal virtual { - bool isGovernor = target == address(this); - if (isGovernor && selector == this.setAccessManagerIgnored.selector) { - revert GovernorLockedIgnore(); - } - _ignoreToggle[target][selector] = ignored != isGovernor; // equivalent to: isGovernor ? !ignored : ignored - emit AccessManagerIgnoredSet(target, selector, ignored); - } - - /** - * @dev Public accessor to check the execution plan, including the number of seconds that the proposal will be - * delayed since queuing, an array indicating which of the proposal actions will be executed indirectly through - * the associated {AccessManager}, and another indicating which will be scheduled in {queue}. Note that - * those that must be scheduled are cancellable by `AccessManager` guardians. - */ - function proposalExecutionPlan( - uint256 proposalId - ) public view returns (uint32 delay, bool[] memory indirect, bool[] memory withDelay) { - ExecutionPlan storage plan = _executionPlan[proposalId]; - - uint32 length = plan.length; - delay = plan.delay; - indirect = new bool[](length); - withDelay = new bool[](length); - for (uint256 i = 0; i < length; ++i) { - (indirect[i], withDelay[i], ) = _getManagerData(plan, i); - } - - return (delay, indirect, withDelay); - } - - /** - * @dev See {IGovernor-proposalNeedsQueuing}. - */ - function proposalNeedsQueuing(uint256 proposalId) public view virtual override returns (bool) { - return _executionPlan[proposalId].delay > 0; - } - - /** - * @dev See {IGovernor-propose} - */ - function propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description - ) public virtual override returns (uint256) { - uint256 proposalId = super.propose(targets, values, calldatas, description); - - uint32 neededDelay = baseDelaySeconds(); - - ExecutionPlan storage plan = _executionPlan[proposalId]; - plan.length = SafeCast.toUint16(targets.length); - - for (uint256 i = 0; i < targets.length; ++i) { - if (calldatas[i].length < 4) { - continue; - } - address target = targets[i]; - bytes4 selector = bytes4(calldatas[i]); - (bool immediate, uint32 delay) = AuthorityUtils.canCallWithDelay( - address(_manager), - address(this), - target, - selector - ); - if ((immediate || delay > 0) && !isAccessManagerIgnored(target, selector)) { - _setManagerData(plan, i, !immediate, 0); - // downcast is safe because both arguments are uint32 - neededDelay = uint32(Math.max(delay, neededDelay)); - } - } - - plan.delay = neededDelay; - - return proposalId; - } - - /** - * @dev Mechanism to queue a proposal, potentially scheduling some of its operations in the AccessManager. - * - * NOTE: The execution delay is chosen based on the delay information retrieved in {propose}. This value may be - * off if the delay was updated since proposal creation. In this case, the proposal needs to be recreated. - */ - function _queueOperations( - uint256 proposalId, - address[] memory targets, - uint256[] memory /* values */, - bytes[] memory calldatas, - bytes32 /* descriptionHash */ - ) internal virtual override returns (uint48) { - ExecutionPlan storage plan = _executionPlan[proposalId]; - uint48 etaSeconds = Time.timestamp() + plan.delay; - - for (uint256 i = 0; i < targets.length; ++i) { - (, bool withDelay, ) = _getManagerData(plan, i); - if (withDelay) { - (, uint32 nonce) = _manager.schedule(targets[i], calldatas[i], etaSeconds); - _setManagerData(plan, i, true, nonce); - } - } - - return etaSeconds; - } - - /** - * @dev Mechanism to execute a proposal, potentially going through {AccessManager-execute} for delayed operations. - */ - function _executeOperations( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 /* descriptionHash */ - ) internal virtual override { - uint48 etaSeconds = SafeCast.toUint48(proposalEta(proposalId)); - if (block.timestamp < etaSeconds) { - revert GovernorUnmetDelay(proposalId, etaSeconds); - } - - ExecutionPlan storage plan = _executionPlan[proposalId]; - - for (uint256 i = 0; i < targets.length; ++i) { - (bool controlled, bool withDelay, uint32 nonce) = _getManagerData(plan, i); - if (controlled) { - uint32 executedNonce = _manager.execute{value: values[i]}(targets[i], calldatas[i]); - if (withDelay && executedNonce != nonce) { - revert GovernorMismatchedNonce(proposalId, nonce, executedNonce); - } - } else { - (bool success, bytes memory returndata) = targets[i].call{value: values[i]}(calldatas[i]); - Address.verifyCallResult(success, returndata); - } - } - } - - /** - * @dev See {IGovernor-_cancel} - */ - 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); - - uint48 etaSeconds = SafeCast.toUint48(proposalEta(proposalId)); - - ExecutionPlan storage plan = _executionPlan[proposalId]; - - // If the proposal has been scheduled it will have an ETA and we may have to externally cancel - if (etaSeconds != 0) { - for (uint256 i = 0; i < targets.length; ++i) { - (, bool withDelay, uint32 nonce) = _getManagerData(plan, i); - // Only attempt to cancel if the execution plan included a delay - if (withDelay) { - bytes32 operationId = _manager.hashOperation(address(this), targets[i], calldatas[i]); - // Check first if the current operation nonce is the one that we observed previously. It could - // already have been cancelled and rescheduled. We don't want to cancel unless it is exactly the - // instance that we previously scheduled. - if (nonce == _manager.getNonce(operationId)) { - // It is important that all calls have an opportunity to be cancelled. We chose to ignore - // potential failures of some of the cancel operations to give the other operations a chance to - // be properly cancelled. In particular cancel might fail if the operation was already cancelled - // by guardians previously. We don't match on the revert reason to avoid encoding assumptions - // about specific errors. - try _manager.cancel(address(this), targets[i], calldatas[i]) {} catch {} - } - } - } - } - - return proposalId; - } - - /** - * @dev Returns whether the operation at an index is delayed by the manager, and its scheduling nonce once queued. - */ - function _getManagerData( - ExecutionPlan storage plan, - uint256 index - ) private view returns (bool controlled, bool withDelay, uint32 nonce) { - (uint256 bucket, uint256 subindex) = _getManagerDataIndices(index); - uint32 value = plan.managerData[bucket][subindex]; - unchecked { - return (value > 0, value > 1, value > 1 ? value - 2 : 0); - } - } - - /** - * @dev Marks an operation at an index as permissioned by the manager, potentially delayed, and - * when delayed sets its scheduling nonce. - */ - function _setManagerData(ExecutionPlan storage plan, uint256 index, bool withDelay, uint32 nonce) private { - (uint256 bucket, uint256 subindex) = _getManagerDataIndices(index); - plan.managerData[bucket][subindex] = withDelay ? nonce + 2 : 1; - } - - /** - * @dev Returns bucket and subindex for reading manager data from the packed array mapping. - */ - function _getManagerDataIndices(uint256 index) private pure returns (uint256 bucket, uint256 subindex) { - bucket = index >> 3; // index / 8 - subindex = index & 7; // index % 8 - } -} diff --git a/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockCompound.sol b/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockCompound.sol deleted file mode 100644 index 77cf369..0000000 --- a/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockCompound.sol +++ /dev/null @@ -1,167 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (governance/extensions/GovernorTimelockCompound.sol) - -pragma solidity ^0.8.20; - -import {IGovernor, Governor} from "../Governor.sol"; -import {ICompoundTimelock} from "../../vendor/compound/ICompoundTimelock.sol"; -import {Address} from "../../utils/Address.sol"; -import {SafeCast} from "../../utils/math/SafeCast.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 from a proposal, unless executed via {Governor-relay}. - */ -abstract contract GovernorTimelockCompound is Governor { - ICompoundTimelock private _timelock; - - /** - * @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 Overridden version of the {Governor-state} function with added support for the `Expired` state. - */ - function state(uint256 proposalId) public view virtual override returns (ProposalState) { - ProposalState currentState = super.state(proposalId); - - return - (currentState == ProposalState.Queued && - block.timestamp >= proposalEta(proposalId) + _timelock.GRACE_PERIOD()) - ? ProposalState.Expired - : currentState; - } - - /** - * @dev Public accessor to check the address of the timelock - */ - function timelock() public view virtual returns (address) { - return address(_timelock); - } - - /** - * @dev See {IGovernor-proposalNeedsQueuing}. - */ - function proposalNeedsQueuing(uint256) public view virtual override returns (bool) { - return true; - } - - /** - * @dev Function to queue a proposal to the timelock. - */ - function _queueOperations( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 /*descriptionHash*/ - ) internal virtual override returns (uint48) { - uint48 etaSeconds = SafeCast.toUint48(block.timestamp + _timelock.delay()); - - for (uint256 i = 0; i < targets.length; ++i) { - if ( - _timelock.queuedTransactions(keccak256(abi.encode(targets[i], values[i], "", calldatas[i], etaSeconds))) - ) { - revert GovernorAlreadyQueuedProposal(proposalId); - } - _timelock.queueTransaction(targets[i], values[i], "", calldatas[i], etaSeconds); - } - - return etaSeconds; - } - - /** - * @dev Overridden version of the {Governor-_executeOperations} function that run the already queued proposal - * through the timelock. - */ - function _executeOperations( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 /*descriptionHash*/ - ) internal virtual override { - uint256 etaSeconds = proposalEta(proposalId); - if (etaSeconds == 0) { - revert GovernorNotQueuedProposal(proposalId); - } - Address.sendValue(payable(_timelock), msg.value); - for (uint256 i = 0; i < targets.length; ++i) { - _timelock.executeTransaction(targets[i], values[i], "", calldatas[i], etaSeconds); - } - } - - /** - * @dev Overridden version of the {Governor-_cancel} function to cancel the timelocked proposal if it has 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 etaSeconds = proposalEta(proposalId); - if (etaSeconds > 0) { - // do external call later - for (uint256 i = 0; i < targets.length; ++i) { - _timelock.cancelTransaction(targets[i], values[i], "", calldatas[i], etaSeconds); - } - } - - 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/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockControl.sol b/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockControl.sol deleted file mode 100644 index 52d4b42..0000000 --- a/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockControl.sol +++ /dev/null @@ -1,170 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (governance/extensions/GovernorTimelockControl.sol) - -pragma solidity ^0.8.20; - -import {IGovernor, Governor} from "../Governor.sol"; -import {TimelockController} from "../TimelockController.sol"; -import {IERC165} from "../../interfaces/IERC165.sol"; -import {SafeCast} from "../../utils/math/SafeCast.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 and canceller) 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 from a proposal, unless executed via {Governor-relay}. - * - * WARNING: Setting up the TimelockController to have additional proposers or cancellers besides the governor is very - * risky, as it grants them the ability to: 1) execute operations as the timelock, and thus possibly performing - * operations or accessing funds that are expected to only be accessible through a vote, and 2) block governance - * proposals that have been approved by the voters, effectively executing a Denial of Service attack. - */ -abstract contract GovernorTimelockControl is Governor { - TimelockController private _timelock; - mapping(uint256 proposalId => 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 Overridden version of the {Governor-state} function that considers the status reported by the timelock. - */ - function state(uint256 proposalId) public view virtual override returns (ProposalState) { - ProposalState currentState = super.state(proposalId); - - if (currentState != ProposalState.Queued) { - return currentState; - } - - bytes32 queueid = _timelockIds[proposalId]; - if (_timelock.isOperationPending(queueid)) { - return ProposalState.Queued; - } else if (_timelock.isOperationDone(queueid)) { - // This can happen if the proposal is executed directly on the timelock. - return ProposalState.Executed; - } else { - // This can happen if the proposal is canceled directly on the timelock. - return ProposalState.Canceled; - } - } - - /** - * @dev Public accessor to check the address of the timelock - */ - function timelock() public view virtual returns (address) { - return address(_timelock); - } - - /** - * @dev See {IGovernor-proposalNeedsQueuing}. - */ - function proposalNeedsQueuing(uint256) public view virtual override returns (bool) { - return true; - } - - /** - * @dev Function to queue a proposal to the timelock. - */ - function _queueOperations( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal virtual override returns (uint48) { - uint256 delay = _timelock.getMinDelay(); - - bytes32 salt = _timelockSalt(descriptionHash); - _timelockIds[proposalId] = _timelock.hashOperationBatch(targets, values, calldatas, 0, salt); - _timelock.scheduleBatch(targets, values, calldatas, 0, salt, delay); - - return SafeCast.toUint48(block.timestamp + delay); - } - - /** - * @dev Overridden version of the {Governor-_executeOperations} function that runs the already queued proposal - * through the timelock. - */ - function _executeOperations( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal virtual override { - // execute - _timelock.executeBatch{value: msg.value}(targets, values, calldatas, 0, _timelockSalt(descriptionHash)); - // cleanup for refund - delete _timelockIds[proposalId]; - } - - /** - * @dev Overridden version of the {Governor-_cancel} function to cancel the timelocked proposal if it has 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); - - bytes32 timelockId = _timelockIds[proposalId]; - if (timelockId != 0) { - // cancel - _timelock.cancel(timelockId); - // cleanup - 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; - } - - /** - * @dev Computes the {TimelockController} operation salt. - * - * It is computed with the governor address itself to avoid collisions across governor instances using the - * same timelock. - */ - function _timelockSalt(bytes32 descriptionHash) private view returns (bytes32) { - return bytes20(address(this)) ^ descriptionHash; - } -} diff --git a/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotes.sol b/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotes.sol deleted file mode 100644 index 16cd934..0000000 --- a/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotes.sol +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (governance/extensions/GovernorVotes.sol) - -pragma solidity ^0.8.20; - -import {Governor} from "../Governor.sol"; -import {IVotes} from "../utils/IVotes.sol"; -import {IERC5805} from "../../interfaces/IERC5805.sol"; -import {SafeCast} from "../../utils/math/SafeCast.sol"; -import {Time} from "../../utils/types/Time.sol"; - -/** - * @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token, or since v4.5 an {ERC721Votes} - * token. - */ -abstract contract GovernorVotes is Governor { - IERC5805 private immutable _token; - - constructor(IVotes tokenAddress) { - _token = IERC5805(address(tokenAddress)); - } - - /** - * @dev The token that voting power is sourced from. - */ - function token() public view virtual returns (IERC5805) { - return _token; - } - - /** - * @dev Clock (as specified in ERC-6372) is set to match the token's clock. Fallback to block numbers if the token - * does not implement ERC-6372. - */ - function clock() public view virtual override returns (uint48) { - try token().clock() returns (uint48 timepoint) { - return timepoint; - } catch { - return Time.blockNumber(); - } - } - - /** - * @dev Machine-readable description of the clock as specified in ERC-6372. - */ - // solhint-disable-next-line func-name-mixedcase - function CLOCK_MODE() public view virtual override returns (string memory) { - try token().CLOCK_MODE() returns (string memory clockmode) { - return clockmode; - } catch { - return "mode=blocknumber&from=default"; - } - } - - /** - * Read the voting weight from the token's built in snapshot mechanism (see {Governor-_getVotes}). - */ - function _getVotes( - address account, - uint256 timepoint, - bytes memory /*params*/ - ) internal view virtual override returns (uint256) { - return token().getPastVotes(account, timepoint); - } -} diff --git a/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotesQuorumFraction.sol b/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotesQuorumFraction.sol deleted file mode 100644 index 85a1f98..0000000 --- a/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotesQuorumFraction.sol +++ /dev/null @@ -1,110 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (governance/extensions/GovernorVotesQuorumFraction.sol) - -pragma solidity ^0.8.20; - -import {GovernorVotes} from "./GovernorVotes.sol"; -import {SafeCast} from "../../utils/math/SafeCast.sol"; -import {Checkpoints} from "../../utils/structs/Checkpoints.sol"; - -/** - * @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token and a quorum expressed as a - * fraction of the total supply. - */ -abstract contract GovernorVotesQuorumFraction is GovernorVotes { - using Checkpoints for Checkpoints.Trace208; - - Checkpoints.Trace208 private _quorumNumeratorHistory; - - event QuorumNumeratorUpdated(uint256 oldQuorumNumerator, uint256 newQuorumNumerator); - - /** - * @dev The quorum set is not a valid fraction. - */ - error GovernorInvalidQuorumFraction(uint256 quorumNumerator, uint256 quorumDenominator); - - /** - * @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 _quorumNumeratorHistory.latest(); - } - - /** - * @dev Returns the quorum numerator at a specific timepoint. See {quorumDenominator}. - */ - function quorumNumerator(uint256 timepoint) public view virtual returns (uint256) { - uint256 length = _quorumNumeratorHistory._checkpoints.length; - - // Optimistic search, check the latest checkpoint - Checkpoints.Checkpoint208 storage latest = _quorumNumeratorHistory._checkpoints[length - 1]; - uint48 latestKey = latest._key; - uint208 latestValue = latest._value; - if (latestKey <= timepoint) { - return latestValue; - } - - // Otherwise, do the binary search - return _quorumNumeratorHistory.upperLookupRecent(SafeCast.toUint48(timepoint)); - } - - /** - * @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 timepoint, in terms of number of votes: `supply * numerator / denominator`. - */ - function quorum(uint256 timepoint) public view virtual override returns (uint256) { - return (token().getPastTotalSupply(timepoint) * quorumNumerator(timepoint)) / 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 { - uint256 denominator = quorumDenominator(); - if (newQuorumNumerator > denominator) { - revert GovernorInvalidQuorumFraction(newQuorumNumerator, denominator); - } - - uint256 oldQuorumNumerator = quorumNumerator(); - _quorumNumeratorHistory.push(clock(), SafeCast.toUint208(newQuorumNumerator)); - - emit QuorumNumeratorUpdated(oldQuorumNumerator, newQuorumNumerator); - } -} diff --git a/lib/openzeppelin-contracts/contracts/governance/utils/IVotes.sol b/lib/openzeppelin-contracts/contracts/governance/utils/IVotes.sol deleted file mode 100644 index 7ba012e..0000000 --- a/lib/openzeppelin-contracts/contracts/governance/utils/IVotes.sol +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (governance/utils/IVotes.sol) -pragma solidity ^0.8.20; - -/** - * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts. - */ -interface IVotes { - /** - * @dev The signature used has expired. - */ - error VotesExpiredSignature(uint256 expiry); - - /** - * @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 voting units. - */ - event DelegateVotesChanged(address indexed delegate, uint256 previousVotes, uint256 newVotes); - - /** - * @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 a specific moment in the past. If the `clock()` is - * configured to use block numbers, this will return the value at the end of the corresponding block. - */ - function getPastVotes(address account, uint256 timepoint) external view returns (uint256); - - /** - * @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is - * configured to use block numbers, this will return the value at the end of the corresponding block. - * - * 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 timepoint) 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/openzeppelin-contracts/contracts/governance/utils/Votes.sol b/lib/openzeppelin-contracts/contracts/governance/utils/Votes.sol deleted file mode 100644 index 2b4def2..0000000 --- a/lib/openzeppelin-contracts/contracts/governance/utils/Votes.sol +++ /dev/null @@ -1,251 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (governance/utils/Votes.sol) -pragma solidity ^0.8.20; - -import {IERC5805} from "../../interfaces/IERC5805.sol"; -import {Context} from "../../utils/Context.sol"; -import {Nonces} from "../../utils/Nonces.sol"; -import {EIP712} from "../../utils/cryptography/EIP712.sol"; -import {Checkpoints} from "../../utils/structs/Checkpoints.sol"; -import {SafeCast} from "../../utils/math/SafeCast.sol"; -import {ECDSA} from "../../utils/cryptography/ECDSA.sol"; -import {Time} from "../../utils/types/Time.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-_update}). - */ -abstract contract Votes is Context, EIP712, Nonces, IERC5805 { - using Checkpoints for Checkpoints.Trace208; - - bytes32 private constant DELEGATION_TYPEHASH = - keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); - - mapping(address account => address) private _delegatee; - - mapping(address delegatee => Checkpoints.Trace208) private _delegateCheckpoints; - - Checkpoints.Trace208 private _totalCheckpoints; - - /** - * @dev The clock was incorrectly modified. - */ - error ERC6372InconsistentClock(); - - /** - * @dev Lookup to future votes is not available. - */ - error ERC5805FutureLookup(uint256 timepoint, uint48 clock); - - /** - * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based - * checkpoints (and voting), in which case {CLOCK_MODE} should be overridden as well to match. - */ - function clock() public view virtual returns (uint48) { - return Time.blockNumber(); - } - - /** - * @dev Machine-readable description of the clock as specified in ERC-6372. - */ - // solhint-disable-next-line func-name-mixedcase - function CLOCK_MODE() public view virtual returns (string memory) { - // Check that the clock was not modified - if (clock() != Time.blockNumber()) { - revert ERC6372InconsistentClock(); - } - return "mode=blocknumber&from=default"; - } - - /** - * @dev Returns the current amount of votes that `account` has. - */ - function getVotes(address account) public view virtual returns (uint256) { - return _delegateCheckpoints[account].latest(); - } - - /** - * @dev Returns the amount of votes that `account` had at a specific moment in the past. If the `clock()` is - * configured to use block numbers, this will return the value at the end of the corresponding block. - * - * Requirements: - * - * - `timepoint` must be in the past. If operating using block numbers, the block must be already mined. - */ - function getPastVotes(address account, uint256 timepoint) public view virtual returns (uint256) { - uint48 currentTimepoint = clock(); - if (timepoint >= currentTimepoint) { - revert ERC5805FutureLookup(timepoint, currentTimepoint); - } - return _delegateCheckpoints[account].upperLookupRecent(SafeCast.toUint48(timepoint)); - } - - /** - * @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is - * configured to use block numbers, this will return the value at the end of the corresponding block. - * - * 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: - * - * - `timepoint` must be in the past. If operating using block numbers, the block must be already mined. - */ - function getPastTotalSupply(uint256 timepoint) public view virtual returns (uint256) { - uint48 currentTimepoint = clock(); - if (timepoint >= currentTimepoint) { - revert ERC5805FutureLookup(timepoint, currentTimepoint); - } - return _totalCheckpoints.upperLookupRecent(SafeCast.toUint48(timepoint)); - } - - /** - * @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 returns (address) { - return _delegatee[account]; - } - - /** - * @dev Delegates votes from the sender to `delegatee`. - */ - function delegate(address delegatee) public virtual { - 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 { - if (block.timestamp > expiry) { - revert VotesExpiredSignature(expiry); - } - address signer = ECDSA.recover( - _hashTypedDataV4(keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry))), - v, - r, - s - ); - _useCheckedNonce(signer, 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); - _delegatee[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)) { - _push(_totalCheckpoints, _add, SafeCast.toUint208(amount)); - } - if (to == address(0)) { - _push(_totalCheckpoints, _subtract, SafeCast.toUint208(amount)); - } - _moveDelegateVotes(delegates(from), delegates(to), amount); - } - - /** - * @dev Moves delegated votes from one delegate to another. - */ - function _moveDelegateVotes(address from, address to, uint256 amount) internal virtual { - if (from != to && amount > 0) { - if (from != address(0)) { - (uint256 oldValue, uint256 newValue) = _push( - _delegateCheckpoints[from], - _subtract, - SafeCast.toUint208(amount) - ); - emit DelegateVotesChanged(from, oldValue, newValue); - } - if (to != address(0)) { - (uint256 oldValue, uint256 newValue) = _push( - _delegateCheckpoints[to], - _add, - SafeCast.toUint208(amount) - ); - emit DelegateVotesChanged(to, oldValue, newValue); - } - } - } - - /** - * @dev Get number of checkpoints for `account`. - */ - function _numCheckpoints(address account) internal view virtual returns (uint32) { - return SafeCast.toUint32(_delegateCheckpoints[account].length()); - } - - /** - * @dev Get the `pos`-th checkpoint for `account`. - */ - function _checkpoints( - address account, - uint32 pos - ) internal view virtual returns (Checkpoints.Checkpoint208 memory) { - return _delegateCheckpoints[account].at(pos); - } - - function _push( - Checkpoints.Trace208 storage store, - function(uint208, uint208) view returns (uint208) op, - uint208 delta - ) private returns (uint208, uint208) { - return store.push(clock(), op(store.latest(), delta)); - } - - function _add(uint208 a, uint208 b) private pure returns (uint208) { - return a + b; - } - - function _subtract(uint208 a, uint208 b) private pure returns (uint208) { - return a - b; - } - - /** - * @dev Must return the voting units held by an account. - */ - function _getVotingUnits(address) internal view virtual returns (uint256); -} diff --git a/lib/openzeppelin-contracts/contracts/interfaces/IERC1155.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC1155.sol deleted file mode 100644 index bb502b1..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC1155.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1155.sol) - -pragma solidity ^0.8.20; - -import {IERC1155} from "../token/ERC1155/IERC1155.sol"; diff --git a/lib/openzeppelin-contracts/contracts/interfaces/IERC1155MetadataURI.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC1155MetadataURI.sol deleted file mode 100644 index dac0bab..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC1155MetadataURI.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1155MetadataURI.sol) - -pragma solidity ^0.8.20; - -import {IERC1155MetadataURI} from "../token/ERC1155/extensions/IERC1155MetadataURI.sol"; diff --git a/lib/openzeppelin-contracts/contracts/interfaces/IERC1155Receiver.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC1155Receiver.sol deleted file mode 100644 index 6bb7c96..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC1155Receiver.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1155Receiver.sol) - -pragma solidity ^0.8.20; - -import {IERC1155Receiver} from "../token/ERC1155/IERC1155Receiver.sol"; diff --git a/lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol deleted file mode 100644 index 5f5b326..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1271.sol) - -pragma solidity ^0.8.20; - -/** - * @dev Interface of the ERC-1271 standard signature validation method for - * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271]. - */ -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/openzeppelin-contracts/contracts/interfaces/IERC1363.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol deleted file mode 100644 index a5246da..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1363.sol) - -pragma solidity ^0.8.20; - -import {IERC20} from "./IERC20.sol"; -import {IERC165} from "./IERC165.sol"; - -/** - * @title IERC1363 - * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363]. - * - * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract - * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction. - */ -interface IERC1363 is IERC20, IERC165 { - /* - * Note: the ERC-165 identifier for this interface is 0xb0202a11. - * 0xb0202a11 === - * bytes4(keccak256('transferAndCall(address,uint256)')) ^ - * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^ - * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^ - * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^ - * bytes4(keccak256('approveAndCall(address,uint256)')) ^ - * bytes4(keccak256('approveAndCall(address,uint256,bytes)')) - */ - - /** - * @dev Moves a `value` amount of tokens from the caller's account to `to` - * and then calls {IERC1363Receiver-onTransferReceived} on `to`. - * @param to The address which you want to transfer to. - * @param value The amount of tokens to be transferred. - * @return A boolean value indicating whether the operation succeeded unless throwing. - */ - function transferAndCall(address to, uint256 value) external returns (bool); - - /** - * @dev Moves a `value` amount of tokens from the caller's account to `to` - * and then calls {IERC1363Receiver-onTransferReceived} on `to`. - * @param to The address which you want to transfer to. - * @param value The amount of tokens to be transferred. - * @param data Additional data with no specified format, sent in call to `to`. - * @return A boolean value indicating whether the operation succeeded unless throwing. - */ - function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool); - - /** - * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism - * and then calls {IERC1363Receiver-onTransferReceived} on `to`. - * @param from The address which you want to send tokens from. - * @param to The address which you want to transfer to. - * @param value The amount of tokens to be transferred. - * @return A boolean value indicating whether the operation succeeded unless throwing. - */ - function transferFromAndCall(address from, address to, uint256 value) external returns (bool); - - /** - * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism - * and then calls {IERC1363Receiver-onTransferReceived} on `to`. - * @param from The address which you want to send tokens from. - * @param to The address which you want to transfer to. - * @param value The amount of tokens to be transferred. - * @param data Additional data with no specified format, sent in call to `to`. - * @return A boolean value indicating whether the operation succeeded unless throwing. - */ - function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool); - - /** - * @dev Sets a `value` amount of tokens as the allowance of `spender` over the - * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. - * @param spender The address which will spend the funds. - * @param value The amount of tokens to be spent. - * @return A boolean value indicating whether the operation succeeded unless throwing. - */ - function approveAndCall(address spender, uint256 value) external returns (bool); - - /** - * @dev Sets a `value` amount of tokens as the allowance of `spender` over the - * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. - * @param spender The address which will spend the funds. - * @param value The amount of tokens to be spent. - * @param data Additional data with no specified format, sent in call to `spender`. - * @return A boolean value indicating whether the operation succeeded unless throwing. - */ - function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool); -} diff --git a/lib/openzeppelin-contracts/contracts/interfaces/IERC1363Receiver.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC1363Receiver.sol deleted file mode 100644 index ebcffe2..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC1363Receiver.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1363Receiver.sol) - -pragma solidity ^0.8.20; - -/** - * @title IERC1363Receiver - * @dev Interface for any contract that wants to support `transferAndCall` or `transferFromAndCall` - * from ERC-1363 token contracts. - */ -interface IERC1363Receiver { - /** - * @dev Whenever ERC-1363 tokens are transferred to this contract via `transferAndCall` or `transferFromAndCall` - * by `operator` from `from`, this function is called. - * - * NOTE: To accept the transfer, this must return - * `bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)"))` - * (i.e. 0x88a7ca5c, or its own function selector). - * - * @param operator The address which called `transferAndCall` or `transferFromAndCall` function. - * @param from The address which are tokens transferred from. - * @param value The amount of tokens transferred. - * @param data Additional data with no specified format. - * @return `bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)"))` if transfer is allowed unless throwing. - */ - function onTransferReceived( - address operator, - address from, - uint256 value, - bytes calldata data - ) external returns (bytes4); -} diff --git a/lib/openzeppelin-contracts/contracts/interfaces/IERC1363Spender.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC1363Spender.sol deleted file mode 100644 index b4bf3f4..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC1363Spender.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1363Spender.sol) - -pragma solidity ^0.8.20; - -/** - * @title ERC1363Spender - * @dev Interface for any contract that wants to support `approveAndCall` - * from ERC-1363 token contracts. - */ -interface IERC1363Spender { - /** - * @dev Whenever an ERC-1363 token `owner` approves this contract via `approveAndCall` - * to spend their tokens, this function is called. - * - * NOTE: To accept the approval, this must return - * `bytes4(keccak256("onApprovalReceived(address,uint256,bytes)"))` - * (i.e. 0x7b04a2d0, or its own function selector). - * - * @param owner The address which called `approveAndCall` function and previously owned the tokens. - * @param value The amount of tokens to be spent. - * @param data Additional data with no specified format. - * @return `bytes4(keccak256("onApprovalReceived(address,uint256,bytes)"))` if approval is allowed unless throwing. - */ - function onApprovalReceived(address owner, uint256 value, bytes calldata data) external returns (bytes4); -} diff --git a/lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol deleted file mode 100644 index 944dd0d..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol) - -pragma solidity ^0.8.20; - -import {IERC165} from "../utils/introspection/IERC165.sol"; diff --git a/lib/openzeppelin-contracts/contracts/interfaces/IERC1820Implementer.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC1820Implementer.sol deleted file mode 100644 index 9cf941a..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC1820Implementer.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1820Implementer.sol) - -pragma solidity ^0.8.20; - -/** - * @dev Interface for an ERC-1820 implementer, as defined in the - * https://eips.ethereum.org/EIPS/eip-1820#interface-implementation-erc1820implementerinterface[ERC]. - * 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/openzeppelin-contracts/contracts/interfaces/IERC1820Registry.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC1820Registry.sol deleted file mode 100644 index b8f3d73..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC1820Registry.sol +++ /dev/null @@ -1,112 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1820Registry.sol) - -pragma solidity ^0.8.20; - -/** - * @dev Interface of the global ERC-1820 Registry, as defined in the - * https://eips.ethereum.org/EIPS/eip-1820[ERC]. 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 ERC 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 ERC]. - */ - function interfaceHash(string calldata interfaceName) external pure returns (bytes32); - - /** - * @notice Updates the cache with whether the contract implements an ERC-165 interface or not. - * @param account Address of the contract for which to update the cache. - * @param interfaceId ERC-165 interface for which to update the cache. - */ - function updateERC165Cache(address account, bytes4 interfaceId) external; - - /** - * @notice Checks whether a contract implements an ERC-165 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 ERC-165 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 ERC-165 interface or not without using or updating the cache. - * @param account Address of the contract to check. - * @param interfaceId ERC-165 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/openzeppelin-contracts/contracts/interfaces/IERC1967.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC1967.sol deleted file mode 100644 index d285ec8..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC1967.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1967.sol) - -pragma solidity ^0.8.20; - -/** - * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC. - */ -interface IERC1967 { - /** - * @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/openzeppelin-contracts/contracts/interfaces/IERC20.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol deleted file mode 100644 index 21d5a41..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol) - -pragma solidity ^0.8.20; - -import {IERC20} from "../token/ERC20/IERC20.sol"; diff --git a/lib/openzeppelin-contracts/contracts/interfaces/IERC20Metadata.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC20Metadata.sol deleted file mode 100644 index b7bc691..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC20Metadata.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20Metadata.sol) - -pragma solidity ^0.8.20; - -import {IERC20Metadata} from "../token/ERC20/extensions/IERC20Metadata.sol"; diff --git a/lib/openzeppelin-contracts/contracts/interfaces/IERC2309.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC2309.sol deleted file mode 100644 index aa00f34..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC2309.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC2309.sol) - -pragma solidity ^0.8.20; - -/** - * @dev ERC-2309: ERC-721 Consecutive Transfer Extension. - */ -interface IERC2309 { - /** - * @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/openzeppelin-contracts/contracts/interfaces/IERC2612.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC2612.sol deleted file mode 100644 index c0427bb..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC2612.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC2612.sol) - -pragma solidity ^0.8.20; - -import {IERC20Permit} from "../token/ERC20/extensions/IERC20Permit.sol"; - -interface IERC2612 is IERC20Permit {} diff --git a/lib/openzeppelin-contracts/contracts/interfaces/IERC2981.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC2981.sol deleted file mode 100644 index 9e7871d..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC2981.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC2981.sol) - -pragma solidity ^0.8.20; - -import {IERC165} from "../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. - */ -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/openzeppelin-contracts/contracts/interfaces/IERC3156.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC3156.sol deleted file mode 100644 index 0f48bf3..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC3156.sol +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC3156.sol) - -pragma solidity ^0.8.20; - -import {IERC3156FlashBorrower} from "./IERC3156FlashBorrower.sol"; -import {IERC3156FlashLender} from "./IERC3156FlashLender.sol"; diff --git a/lib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashBorrower.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashBorrower.sol deleted file mode 100644 index 4fd10e7..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashBorrower.sol +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC3156FlashBorrower.sol) - -pragma solidity ^0.8.20; - -/** - * @dev Interface of the ERC-3156 FlashBorrower, as defined in - * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156]. - */ -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 "ERC3156FlashBorrower.onFlashLoan" - */ - function onFlashLoan( - address initiator, - address token, - uint256 amount, - uint256 fee, - bytes calldata data - ) external returns (bytes32); -} diff --git a/lib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashLender.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashLender.sol deleted file mode 100644 index 47208ac..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashLender.sol +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC3156FlashLender.sol) - -pragma solidity ^0.8.20; - -import {IERC3156FlashBorrower} from "./IERC3156FlashBorrower.sol"; - -/** - * @dev Interface of the ERC-3156 FlashLender, as defined in - * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156]. - */ -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/openzeppelin-contracts/contracts/interfaces/IERC4626.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol deleted file mode 100644 index 9a24507..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol +++ /dev/null @@ -1,230 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4626.sol) - -pragma solidity ^0.8.20; - -import {IERC20} from "../token/ERC20/IERC20.sol"; -import {IERC20Metadata} from "../token/ERC20/extensions/IERC20Metadata.sol"; - -/** - * @dev Interface of the ERC-4626 "Tokenized Vault Standard", as defined in - * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626]. - */ -interface IERC4626 is IERC20, IERC20Metadata { - 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/openzeppelin-contracts/contracts/interfaces/IERC4906.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC4906.sol deleted file mode 100644 index cdcace3..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC4906.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol) - -pragma solidity ^0.8.20; - -import {IERC165} from "./IERC165.sol"; -import {IERC721} from "./IERC721.sol"; - -/// @title ERC-721 Metadata Update Extension -interface IERC4906 is IERC165, IERC721 { - /// @dev This event emits when the metadata of a token is changed. - /// So that the third-party platforms such as NFT market could - /// timely update the images and related attributes of the NFT. - event MetadataUpdate(uint256 _tokenId); - - /// @dev This event emits when the metadata of a range of tokens is changed. - /// So that the third-party platforms such as NFT market could - /// timely update the images and related attributes of the NFTs. - event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId); -} diff --git a/lib/openzeppelin-contracts/contracts/interfaces/IERC5267.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC5267.sol deleted file mode 100644 index 47a9fd5..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC5267.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5267.sol) - -pragma solidity ^0.8.20; - -interface IERC5267 { - /** - * @dev MAY be emitted to signal that the domain could have changed. - */ - event EIP712DomainChanged(); - - /** - * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712 - * signature. - */ - function eip712Domain() - external - view - returns ( - bytes1 fields, - string memory name, - string memory version, - uint256 chainId, - address verifyingContract, - bytes32 salt, - uint256[] memory extensions - ); -} diff --git a/lib/openzeppelin-contracts/contracts/interfaces/IERC5313.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC5313.sol deleted file mode 100644 index 62f8d75..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC5313.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5313.sol) - -pragma solidity ^0.8.20; - -/** - * @dev Interface for the Light Contract Ownership Standard. - * - * A standardized minimal interface required to identify an account that controls a contract - */ -interface IERC5313 { - /** - * @dev Gets the address of the owner. - */ - function owner() external view returns (address); -} diff --git a/lib/openzeppelin-contracts/contracts/interfaces/IERC5805.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC5805.sol deleted file mode 100644 index a89e22d..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC5805.sol +++ /dev/null @@ -1,9 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5805.sol) - -pragma solidity ^0.8.20; - -import {IVotes} from "../governance/utils/IVotes.sol"; -import {IERC6372} from "./IERC6372.sol"; - -interface IERC5805 is IERC6372, IVotes {} diff --git a/lib/openzeppelin-contracts/contracts/interfaces/IERC6372.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC6372.sol deleted file mode 100644 index 7d2ea4a..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC6372.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC6372.sol) - -pragma solidity ^0.8.20; - -interface IERC6372 { - /** - * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based checkpoints (and voting). - */ - function clock() external view returns (uint48); - - /** - * @dev Description of the clock - */ - // solhint-disable-next-line func-name-mixedcase - function CLOCK_MODE() external view returns (string memory); -} diff --git a/lib/openzeppelin-contracts/contracts/interfaces/IERC721.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC721.sol deleted file mode 100644 index 0ea735b..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC721.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC721.sol) - -pragma solidity ^0.8.20; - -import {IERC721} from "../token/ERC721/IERC721.sol"; diff --git a/lib/openzeppelin-contracts/contracts/interfaces/IERC721Enumerable.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC721Enumerable.sol deleted file mode 100644 index d83a056..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC721Enumerable.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC721Enumerable.sol) - -pragma solidity ^0.8.20; - -import {IERC721Enumerable} from "../token/ERC721/extensions/IERC721Enumerable.sol"; diff --git a/lib/openzeppelin-contracts/contracts/interfaces/IERC721Metadata.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC721Metadata.sol deleted file mode 100644 index d79dd68..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC721Metadata.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC721Metadata.sol) - -pragma solidity ^0.8.20; - -import {IERC721Metadata} from "../token/ERC721/extensions/IERC721Metadata.sol"; diff --git a/lib/openzeppelin-contracts/contracts/interfaces/IERC721Receiver.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC721Receiver.sol deleted file mode 100644 index 6b2a5aa..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC721Receiver.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC721Receiver.sol) - -pragma solidity ^0.8.20; - -import {IERC721Receiver} from "../token/ERC721/IERC721Receiver.sol"; diff --git a/lib/openzeppelin-contracts/contracts/interfaces/IERC777.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC777.sol deleted file mode 100644 index 31f05aa..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC777.sol +++ /dev/null @@ -1,200 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC777.sol) - -pragma solidity ^0.8.20; - -/** - * @dev Interface of the ERC-777 Token standard as defined in the ERC. - * - * This contract uses the - * https://eips.ethereum.org/EIPS/eip-1820[ERC-1820 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 - * {IERC1820Implementer}. - */ -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/openzeppelin-contracts/contracts/interfaces/IERC777Recipient.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC777Recipient.sol deleted file mode 100644 index 1619e11..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC777Recipient.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC777Recipient.sol) - -pragma solidity ^0.8.20; - -/** - * @dev Interface of the ERC-777 Tokens Recipient standard as defined in the ERC. - * - * 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[ERC-1820 global registry]. - * - * See {IERC1820Registry} and {IERC1820Implementer}. - */ -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/openzeppelin-contracts/contracts/interfaces/IERC777Sender.sol b/lib/openzeppelin-contracts/contracts/interfaces/IERC777Sender.sol deleted file mode 100644 index f47a783..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/IERC777Sender.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC777Sender.sol) - -pragma solidity ^0.8.20; - -/** - * @dev Interface of the ERC-777 Tokens Sender standard as defined in the ERC. - * - * {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[ERC-1820 global registry]. - * - * See {IERC1820Registry} and {IERC1820Implementer}. - */ -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/openzeppelin-contracts/contracts/interfaces/README.adoc b/lib/openzeppelin-contracts/contracts/interfaces/README.adoc deleted file mode 100644 index 379a24a..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/README.adoc +++ /dev/null @@ -1,82 +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} -- {IERC20Errors} -- {IERC20Metadata} -- {IERC165} -- {IERC721} -- {IERC721Receiver} -- {IERC721Enumerable} -- {IERC721Metadata} -- {IERC721Errors} -- {IERC777} -- {IERC777Recipient} -- {IERC777Sender} -- {IERC1155} -- {IERC1155Receiver} -- {IERC1155MetadataURI} -- {IERC1155Errors} -- {IERC1271} -- {IERC1363} -- {IERC1363Receiver} -- {IERC1363Spender} -- {IERC1820Implementer} -- {IERC1820Registry} -- {IERC1822Proxiable} -- {IERC2612} -- {IERC2981} -- {IERC3156FlashLender} -- {IERC3156FlashBorrower} -- {IERC4626} -- {IERC4906} -- {IERC5267} -- {IERC5313} -- {IERC5805} -- {IERC6372} - -== Detailed ABI - -{{IERC20Errors}} - -{{IERC721Errors}} - -{{IERC1155Errors}} - -{{IERC1271}} - -{{IERC1363}} - -{{IERC1363Receiver}} - -{{IERC1363Spender}} - -{{IERC1820Implementer}} - -{{IERC1820Registry}} - -{{IERC1822Proxiable}} - -{{IERC2612}} - -{{IERC2981}} - -{{IERC3156FlashLender}} - -{{IERC3156FlashBorrower}} - -{{IERC4626}} - -{{IERC5313}} - -{{IERC5267}} - -{{IERC5805}} - -{{IERC6372}} diff --git a/lib/openzeppelin-contracts/contracts/interfaces/draft-IERC1822.sol b/lib/openzeppelin-contracts/contracts/interfaces/draft-IERC1822.sol deleted file mode 100644 index ad047da..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/draft-IERC1822.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC1822.sol) - -pragma solidity ^0.8.20; - -/** - * @dev ERC-1822: 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/openzeppelin-contracts/contracts/interfaces/draft-IERC6093.sol b/lib/openzeppelin-contracts/contracts/interfaces/draft-IERC6093.sol deleted file mode 100644 index 75fd756..0000000 --- a/lib/openzeppelin-contracts/contracts/interfaces/draft-IERC6093.sol +++ /dev/null @@ -1,161 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol) -pragma solidity ^0.8.20; - -/** - * @dev Standard ERC-20 Errors - * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens. - */ -interface IERC20Errors { - /** - * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. - * @param sender Address whose tokens are being transferred. - * @param balance Current balance for the interacting account. - * @param needed Minimum amount required to perform a transfer. - */ - error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); - - /** - * @dev Indicates a failure with the token `sender`. Used in transfers. - * @param sender Address whose tokens are being transferred. - */ - error ERC20InvalidSender(address sender); - - /** - * @dev Indicates a failure with the token `receiver`. Used in transfers. - * @param receiver Address to which tokens are being transferred. - */ - error ERC20InvalidReceiver(address receiver); - - /** - * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. - * @param spender Address that may be allowed to operate on tokens without being their owner. - * @param allowance Amount of tokens a `spender` is allowed to operate with. - * @param needed Minimum amount required to perform a transfer. - */ - error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); - - /** - * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. - * @param approver Address initiating an approval operation. - */ - error ERC20InvalidApprover(address approver); - - /** - * @dev Indicates a failure with the `spender` to be approved. Used in approvals. - * @param spender Address that may be allowed to operate on tokens without being their owner. - */ - error ERC20InvalidSpender(address spender); -} - -/** - * @dev Standard ERC-721 Errors - * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens. - */ -interface IERC721Errors { - /** - * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20. - * Used in balance queries. - * @param owner Address of the current owner of a token. - */ - error ERC721InvalidOwner(address owner); - - /** - * @dev Indicates a `tokenId` whose `owner` is the zero address. - * @param tokenId Identifier number of a token. - */ - error ERC721NonexistentToken(uint256 tokenId); - - /** - * @dev Indicates an error related to the ownership over a particular token. Used in transfers. - * @param sender Address whose tokens are being transferred. - * @param tokenId Identifier number of a token. - * @param owner Address of the current owner of a token. - */ - error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); - - /** - * @dev Indicates a failure with the token `sender`. Used in transfers. - * @param sender Address whose tokens are being transferred. - */ - error ERC721InvalidSender(address sender); - - /** - * @dev Indicates a failure with the token `receiver`. Used in transfers. - * @param receiver Address to which tokens are being transferred. - */ - error ERC721InvalidReceiver(address receiver); - - /** - * @dev Indicates a failure with the `operator`’s approval. Used in transfers. - * @param operator Address that may be allowed to operate on tokens without being their owner. - * @param tokenId Identifier number of a token. - */ - error ERC721InsufficientApproval(address operator, uint256 tokenId); - - /** - * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. - * @param approver Address initiating an approval operation. - */ - error ERC721InvalidApprover(address approver); - - /** - * @dev Indicates a failure with the `operator` to be approved. Used in approvals. - * @param operator Address that may be allowed to operate on tokens without being their owner. - */ - error ERC721InvalidOperator(address operator); -} - -/** - * @dev Standard ERC-1155 Errors - * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens. - */ -interface IERC1155Errors { - /** - * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. - * @param sender Address whose tokens are being transferred. - * @param balance Current balance for the interacting account. - * @param needed Minimum amount required to perform a transfer. - * @param tokenId Identifier number of a token. - */ - error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); - - /** - * @dev Indicates a failure with the token `sender`. Used in transfers. - * @param sender Address whose tokens are being transferred. - */ - error ERC1155InvalidSender(address sender); - - /** - * @dev Indicates a failure with the token `receiver`. Used in transfers. - * @param receiver Address to which tokens are being transferred. - */ - error ERC1155InvalidReceiver(address receiver); - - /** - * @dev Indicates a failure with the `operator`’s approval. Used in transfers. - * @param operator Address that may be allowed to operate on tokens without being their owner. - * @param owner Address of the current owner of a token. - */ - error ERC1155MissingApprovalForAll(address operator, address owner); - - /** - * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. - * @param approver Address initiating an approval operation. - */ - error ERC1155InvalidApprover(address approver); - - /** - * @dev Indicates a failure with the `operator` to be approved. Used in approvals. - * @param operator Address that may be allowed to operate on tokens without being their owner. - */ - error ERC1155InvalidOperator(address operator); - - /** - * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. - * Used in batch transfers. - * @param idsLength Length of the array of token identifiers - * @param valuesLength Length of the array of token amounts - */ - error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); -} diff --git a/lib/openzeppelin-contracts/contracts/metatx/ERC2771Context.sol b/lib/openzeppelin-contracts/contracts/metatx/ERC2771Context.sol deleted file mode 100644 index d448b24..0000000 --- a/lib/openzeppelin-contracts/contracts/metatx/ERC2771Context.sol +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.1) (metatx/ERC2771Context.sol) - -pragma solidity ^0.8.20; - -import {Context} from "../utils/Context.sol"; - -/** - * @dev Context variant with ERC-2771 support. - * - * WARNING: Avoid using this pattern in contracts that rely in a specific calldata length as they'll - * be affected by any forwarder whose `msg.data` is suffixed with the `from` address according to the ERC-2771 - * specification adding the address size in bytes (20) to the calldata size. An example of an unexpected - * behavior could be an unintended fallback (or another function) invocation while trying to invoke the `receive` - * function only accessible if `msg.data.length == 0`. - * - * WARNING: The usage of `delegatecall` in this contract is dangerous and may result in context corruption. - * Any forwarded request to this contract triggering a `delegatecall` to itself will result in an invalid {_msgSender} - * recovery. - */ -abstract contract ERC2771Context is Context { - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable - address private immutable _trustedForwarder; - - /** - * @dev Initializes the contract with a trusted forwarder, which will be able to - * invoke functions on this contract on behalf of other accounts. - * - * NOTE: The trusted forwarder can be replaced by overriding {trustedForwarder}. - */ - /// @custom:oz-upgrades-unsafe-allow constructor - constructor(address trustedForwarder_) { - _trustedForwarder = trustedForwarder_; - } - - /** - * @dev Returns the address of the trusted forwarder. - */ - function trustedForwarder() public view virtual returns (address) { - return _trustedForwarder; - } - - /** - * @dev Indicates whether any particular address is the trusted forwarder. - */ - function isTrustedForwarder(address forwarder) public view virtual returns (bool) { - return forwarder == trustedForwarder(); - } - - /** - * @dev Override for `msg.sender`. Defaults to the original `msg.sender` whenever - * a call is not performed by the trusted forwarder or the calldata length is less than - * 20 bytes (an address length). - */ - function _msgSender() internal view virtual override returns (address) { - uint256 calldataLength = msg.data.length; - uint256 contextSuffixLength = _contextSuffixLength(); - if (isTrustedForwarder(msg.sender) && calldataLength >= contextSuffixLength) { - return address(bytes20(msg.data[calldataLength - contextSuffixLength:])); - } else { - return super._msgSender(); - } - } - - /** - * @dev Override for `msg.data`. Defaults to the original `msg.data` whenever - * a call is not performed by the trusted forwarder or the calldata length is less than - * 20 bytes (an address length). - */ - function _msgData() internal view virtual override returns (bytes calldata) { - uint256 calldataLength = msg.data.length; - uint256 contextSuffixLength = _contextSuffixLength(); - if (isTrustedForwarder(msg.sender) && calldataLength >= contextSuffixLength) { - return msg.data[:calldataLength - contextSuffixLength]; - } else { - return super._msgData(); - } - } - - /** - * @dev ERC-2771 specifies the context as being a single address (20 bytes). - */ - function _contextSuffixLength() internal view virtual override returns (uint256) { - return 20; - } -} diff --git a/lib/openzeppelin-contracts/contracts/metatx/ERC2771Forwarder.sol b/lib/openzeppelin-contracts/contracts/metatx/ERC2771Forwarder.sol deleted file mode 100644 index 03c3bee..0000000 --- a/lib/openzeppelin-contracts/contracts/metatx/ERC2771Forwarder.sol +++ /dev/null @@ -1,371 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (metatx/ERC2771Forwarder.sol) - -pragma solidity ^0.8.20; - -import {ERC2771Context} from "./ERC2771Context.sol"; -import {ECDSA} from "../utils/cryptography/ECDSA.sol"; -import {EIP712} from "../utils/cryptography/EIP712.sol"; -import {Nonces} from "../utils/Nonces.sol"; -import {Address} from "../utils/Address.sol"; -import {Errors} from "../utils/Errors.sol"; - -/** - * @dev A forwarder compatible with ERC-2771 contracts. See {ERC2771Context}. - * - * This forwarder operates on forward requests that include: - * - * * `from`: An address to operate on behalf of. It is required to be equal to the request signer. - * * `to`: The address that should be called. - * * `value`: The amount of native token to attach with the requested call. - * * `gas`: The amount of gas limit that will be forwarded with the requested call. - * * `nonce`: A unique transaction ordering identifier to avoid replayability and request invalidation. - * * `deadline`: A timestamp after which the request is not executable anymore. - * * `data`: Encoded `msg.data` to send with the requested call. - * - * Relayers are able to submit batches if they are processing a high volume of requests. With high - * throughput, relayers may run into limitations of the chain such as limits on the number of - * transactions in the mempool. In these cases the recommendation is to distribute the load among - * multiple accounts. - * - * NOTE: Batching requests includes an optional refund for unused `msg.value` that is achieved by - * performing a call with empty calldata. While this is within the bounds of ERC-2771 compliance, - * if the refund receiver happens to consider the forwarder a trusted forwarder, it MUST properly - * handle `msg.data.length == 0`. `ERC2771Context` in OpenZeppelin Contracts versions prior to 4.9.3 - * do not handle this properly. - * - * ==== Security Considerations - * - * If a relayer submits a forward request, it should be willing to pay up to 100% of the gas amount - * specified in the request. This contract does not implement any kind of retribution for this gas, - * and it is assumed that there is an out of band incentive for relayers to pay for execution on - * behalf of signers. Often, the relayer is operated by a project that will consider it a user - * acquisition cost. - * - * By offering to pay for gas, relayers are at risk of having that gas used by an attacker toward - * some other purpose that is not aligned with the expected out of band incentives. If you operate a - * relayer, consider whitelisting target contracts and function selectors. When relaying ERC-721 or - * ERC-1155 transfers specifically, consider rejecting the use of the `data` field, since it can be - * used to execute arbitrary code. - */ -contract ERC2771Forwarder is EIP712, Nonces { - using ECDSA for bytes32; - - struct ForwardRequestData { - address from; - address to; - uint256 value; - uint256 gas; - uint48 deadline; - bytes data; - bytes signature; - } - - bytes32 internal constant _FORWARD_REQUEST_TYPEHASH = - keccak256( - "ForwardRequest(address from,address to,uint256 value,uint256 gas,uint256 nonce,uint48 deadline,bytes data)" - ); - - /** - * @dev Emitted when a `ForwardRequest` is executed. - * - * NOTE: An unsuccessful forward request could be due to an invalid signature, an expired deadline, - * or simply a revert in the requested call. The contract guarantees that the relayer is not able to force - * the requested call to run out of gas. - */ - event ExecutedForwardRequest(address indexed signer, uint256 nonce, bool success); - - /** - * @dev The request `from` doesn't match with the recovered `signer`. - */ - error ERC2771ForwarderInvalidSigner(address signer, address from); - - /** - * @dev The `requestedValue` doesn't match with the available `msgValue`. - */ - error ERC2771ForwarderMismatchedValue(uint256 requestedValue, uint256 msgValue); - - /** - * @dev The request `deadline` has expired. - */ - error ERC2771ForwarderExpiredRequest(uint48 deadline); - - /** - * @dev The request target doesn't trust the `forwarder`. - */ - error ERC2771UntrustfulTarget(address target, address forwarder); - - /** - * @dev See {EIP712-constructor}. - */ - constructor(string memory name) EIP712(name, "1") {} - - /** - * @dev Returns `true` if a request is valid for a provided `signature` at the current block timestamp. - * - * A transaction is considered valid when the target trusts this forwarder, the request hasn't expired - * (deadline is not met), and the signer matches the `from` parameter of the signed request. - * - * NOTE: A request may return false here but it won't cause {executeBatch} to revert if a refund - * receiver is provided. - */ - function verify(ForwardRequestData calldata request) public view virtual returns (bool) { - (bool isTrustedForwarder, bool active, bool signerMatch, ) = _validate(request); - return isTrustedForwarder && active && signerMatch; - } - - /** - * @dev Executes a `request` on behalf of `signature`'s signer using the ERC-2771 protocol. The gas - * provided to the requested call may not be exactly the amount requested, but the call will not run - * out of gas. Will revert if the request is invalid or the call reverts, in this case the nonce is not consumed. - * - * Requirements: - * - * - The request value should be equal to the provided `msg.value`. - * - The request should be valid according to {verify}. - */ - function execute(ForwardRequestData calldata request) public payable virtual { - // We make sure that msg.value and request.value match exactly. - // If the request is invalid or the call reverts, this whole function - // will revert, ensuring value isn't stuck. - if (msg.value != request.value) { - revert ERC2771ForwarderMismatchedValue(request.value, msg.value); - } - - if (!_execute(request, true)) { - revert Errors.FailedCall(); - } - } - - /** - * @dev Batch version of {execute} with optional refunding and atomic execution. - * - * In case a batch contains at least one invalid request (see {verify}), the - * request will be skipped and the `refundReceiver` parameter will receive back the - * unused requested value at the end of the execution. This is done to prevent reverting - * the entire batch when a request is invalid or has already been submitted. - * - * If the `refundReceiver` is the `address(0)`, this function will revert when at least - * one of the requests was not valid instead of skipping it. This could be useful if - * a batch is required to get executed atomically (at least at the top-level). For example, - * refunding (and thus atomicity) can be opt-out if the relayer is using a service that avoids - * including reverted transactions. - * - * Requirements: - * - * - The sum of the requests' values should be equal to the provided `msg.value`. - * - All of the requests should be valid (see {verify}) when `refundReceiver` is the zero address. - * - * NOTE: Setting a zero `refundReceiver` guarantees an all-or-nothing requests execution only for - * the first-level forwarded calls. In case a forwarded request calls to a contract with another - * subcall, the second-level call may revert without the top-level call reverting. - */ - function executeBatch( - ForwardRequestData[] calldata requests, - address payable refundReceiver - ) public payable virtual { - bool atomic = refundReceiver == address(0); - - uint256 requestsValue; - uint256 refundValue; - - for (uint256 i; i < requests.length; ++i) { - requestsValue += requests[i].value; - bool success = _execute(requests[i], atomic); - if (!success) { - refundValue += requests[i].value; - } - } - - // The batch should revert if there's a mismatched msg.value provided - // to avoid request value tampering - if (requestsValue != msg.value) { - revert ERC2771ForwarderMismatchedValue(requestsValue, msg.value); - } - - // Some requests with value were invalid (possibly due to frontrunning). - // To avoid leaving ETH in the contract this value is refunded. - if (refundValue != 0) { - // We know refundReceiver != address(0) && requestsValue == msg.value - // meaning we can ensure refundValue is not taken from the original contract's balance - // and refundReceiver is a known account. - Address.sendValue(refundReceiver, refundValue); - } - } - - /** - * @dev Validates if the provided request can be executed at current block timestamp with - * the given `request.signature` on behalf of `request.signer`. - */ - function _validate( - ForwardRequestData calldata request - ) internal view virtual returns (bool isTrustedForwarder, bool active, bool signerMatch, address signer) { - (bool isValid, address recovered) = _recoverForwardRequestSigner(request); - - return ( - _isTrustedByTarget(request.to), - request.deadline >= block.timestamp, - isValid && recovered == request.from, - recovered - ); - } - - /** - * @dev Returns a tuple with the recovered the signer of an EIP712 forward request message hash - * and a boolean indicating if the signature is valid. - * - * NOTE: The signature is considered valid if {ECDSA-tryRecover} indicates no recover error for it. - */ - function _recoverForwardRequestSigner( - ForwardRequestData calldata request - ) internal view virtual returns (bool, address) { - (address recovered, ECDSA.RecoverError err, ) = _hashTypedDataV4( - keccak256( - abi.encode( - _FORWARD_REQUEST_TYPEHASH, - request.from, - request.to, - request.value, - request.gas, - nonces(request.from), - request.deadline, - keccak256(request.data) - ) - ) - ).tryRecover(request.signature); - - return (err == ECDSA.RecoverError.NoError, recovered); - } - - /** - * @dev Validates and executes a signed request returning the request call `success` value. - * - * Internal function without msg.value validation. - * - * Requirements: - * - * - The caller must have provided enough gas to forward with the call. - * - The request must be valid (see {verify}) if the `requireValidRequest` is true. - * - * Emits an {ExecutedForwardRequest} event. - * - * IMPORTANT: Using this function doesn't check that all the `msg.value` was sent, potentially - * leaving value stuck in the contract. - */ - function _execute( - ForwardRequestData calldata request, - bool requireValidRequest - ) internal virtual returns (bool success) { - (bool isTrustedForwarder, bool active, bool signerMatch, address signer) = _validate(request); - - // Need to explicitly specify if a revert is required since non-reverting is default for - // batches and reversion is opt-in since it could be useful in some scenarios - if (requireValidRequest) { - if (!isTrustedForwarder) { - revert ERC2771UntrustfulTarget(request.to, address(this)); - } - - if (!active) { - revert ERC2771ForwarderExpiredRequest(request.deadline); - } - - if (!signerMatch) { - revert ERC2771ForwarderInvalidSigner(signer, request.from); - } - } - - // Ignore an invalid request because requireValidRequest = false - if (isTrustedForwarder && signerMatch && active) { - // Nonce should be used before the call to prevent reusing by reentrancy - uint256 currentNonce = _useNonce(signer); - - uint256 reqGas = request.gas; - address to = request.to; - uint256 value = request.value; - bytes memory data = abi.encodePacked(request.data, request.from); - - uint256 gasLeft; - - assembly { - success := call(reqGas, to, value, add(data, 0x20), mload(data), 0, 0) - gasLeft := gas() - } - - _checkForwardedGas(gasLeft, request); - - emit ExecutedForwardRequest(signer, currentNonce, success); - } - } - - /** - * @dev Returns whether the target trusts this forwarder. - * - * This function performs a static call to the target contract calling the - * {ERC2771Context-isTrustedForwarder} function. - */ - function _isTrustedByTarget(address target) private view returns (bool) { - bytes memory encodedParams = abi.encodeCall(ERC2771Context.isTrustedForwarder, (address(this))); - - bool success; - uint256 returnSize; - uint256 returnValue; - /// @solidity memory-safe-assembly - assembly { - // Perform the staticcall and save the result in the scratch space. - // | Location | Content | Content (Hex) | - // |-----------|----------|--------------------------------------------------------------------| - // | | | result ↓ | - // | 0x00:0x1F | selector | 0x0000000000000000000000000000000000000000000000000000000000000001 | - success := staticcall(gas(), target, add(encodedParams, 0x20), mload(encodedParams), 0, 0x20) - returnSize := returndatasize() - returnValue := mload(0) - } - - return success && returnSize >= 0x20 && returnValue > 0; - } - - /** - * @dev Checks if the requested gas was correctly forwarded to the callee. - * - * As a consequence of https://eips.ethereum.org/EIPS/eip-150[EIP-150]: - * - At most `gasleft() - floor(gasleft() / 64)` is forwarded to the callee. - * - At least `floor(gasleft() / 64)` is kept in the caller. - * - * It reverts consuming all the available gas if the forwarded gas is not the requested gas. - * - * IMPORTANT: The `gasLeft` parameter should be measured exactly at the end of the forwarded call. - * Any gas consumed in between will make room for bypassing this check. - */ - function _checkForwardedGas(uint256 gasLeft, ForwardRequestData calldata request) private pure { - // To avoid insufficient gas griefing attacks, as referenced in https://ronan.eth.limo/blog/ethereum-gas-dangers/ - // - // A malicious relayer can attempt to shrink the gas forwarded so that the underlying call reverts out-of-gas - // but the forwarding itself still succeeds. In order to make sure that the subcall received sufficient gas, - // we will inspect gasleft() after the forwarding. - // - // Let X be the gas available before the subcall, such that the subcall gets at most X * 63 / 64. - // We can't know X after CALL dynamic costs, but we want it to be such that X * 63 / 64 >= req.gas. - // Let Y be the gas used in the subcall. gasleft() measured immediately after the subcall will be gasleft() = X - Y. - // If the subcall ran out of gas, then Y = X * 63 / 64 and gasleft() = X - Y = X / 64. - // Under this assumption req.gas / 63 > gasleft() is true if and only if - // req.gas / 63 > X / 64, or equivalently req.gas > X * 63 / 64. - // This means that if the subcall runs out of gas we are able to detect that insufficient gas was passed. - // - // We will now also see that req.gas / 63 > gasleft() implies that req.gas >= X * 63 / 64. - // The contract guarantees Y <= req.gas, thus gasleft() = X - Y >= X - req.gas. - // - req.gas / 63 > gasleft() - // - req.gas / 63 >= X - req.gas - // - req.gas >= X * 63 / 64 - // In other words if req.gas < X * 63 / 64 then req.gas / 63 <= gasleft(), thus if the relayer behaves honestly - // the forwarding does not revert. - if (gasLeft < request.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.20 - // https://docs.soliditylang.org/en/v0.8.20/control-structures.html#panic-via-assert-and-error-via-require - /// @solidity memory-safe-assembly - assembly { - invalid() - } - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/metatx/README.adoc b/lib/openzeppelin-contracts/contracts/metatx/README.adoc deleted file mode 100644 index c02fb10..0000000 --- a/lib/openzeppelin-contracts/contracts/metatx/README.adoc +++ /dev/null @@ -1,17 +0,0 @@ -= Meta Transactions - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/metatx - -This directory includes contracts for adding meta-transaction capabilities (i.e. abstracting the execution context from the transaction origin) following the https://eips.ethereum.org/EIPS/eip-2771[ERC-2771 specification]. - -- {ERC2771Context}: Provides a mechanism to override the sender and calldata of the execution context (`msg.sender` and `msg.data`) with a custom value specified by a trusted forwarder. -- {ERC2771Forwarder}: A production-ready forwarder that relays operation requests signed off-chain by an EOA. - -== Core - -{{ERC2771Context}} - -== Utils - -{{ERC2771Forwarder}} diff --git a/lib/openzeppelin-contracts/contracts/mocks/AccessManagedTarget.sol b/lib/openzeppelin-contracts/contracts/mocks/AccessManagedTarget.sol deleted file mode 100644 index 673feed..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/AccessManagedTarget.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {AccessManaged} from "../access/manager/AccessManaged.sol"; -import {StorageSlot} from "../utils/StorageSlot.sol"; - -abstract contract AccessManagedTarget is AccessManaged { - event CalledRestricted(address caller); - event CalledUnrestricted(address caller); - event CalledFallback(address caller); - - function fnRestricted() public restricted { - emit CalledRestricted(msg.sender); - } - - function fnUnrestricted() public { - emit CalledUnrestricted(msg.sender); - } - - function setIsConsumingScheduledOp(bool isConsuming, bytes32 slot) external { - // Memory layout is 0x....<_consumingSchedule (boolean)> - bytes32 mask = bytes32(uint256(1 << 160)); - if (isConsuming) { - StorageSlot.getBytes32Slot(slot).value |= mask; - } else { - StorageSlot.getBytes32Slot(slot).value &= ~mask; - } - } - - fallback() external { - emit CalledFallback(msg.sender); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/AccessManagerMock.sol b/lib/openzeppelin-contracts/contracts/mocks/AccessManagerMock.sol deleted file mode 100644 index 952c761..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/AccessManagerMock.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {AccessManager} from "../access/manager/AccessManager.sol"; -import {StorageSlot} from "../utils/StorageSlot.sol"; - -contract AccessManagerMock is AccessManager { - event CalledRestricted(address caller); - event CalledUnrestricted(address caller); - - constructor(address initialAdmin) AccessManager(initialAdmin) {} - - function fnRestricted() public onlyAuthorized { - emit CalledRestricted(msg.sender); - } - - function fnUnrestricted() public { - emit CalledUnrestricted(msg.sender); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/ArraysMock.sol b/lib/openzeppelin-contracts/contracts/mocks/ArraysMock.sol deleted file mode 100644 index 63f4c8e..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/ArraysMock.sol +++ /dev/null @@ -1,127 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {Arrays} from "../utils/Arrays.sol"; - -contract Uint256ArraysMock { - using Arrays for uint256[]; - - uint256[] private _array; - - constructor(uint256[] memory array) { - _array = array; - } - - function findUpperBound(uint256 value) external view returns (uint256) { - return _array.findUpperBound(value); - } - - function lowerBound(uint256 value) external view returns (uint256) { - return _array.lowerBound(value); - } - - function upperBound(uint256 value) external view returns (uint256) { - return _array.upperBound(value); - } - - function lowerBoundMemory(uint256[] memory array, uint256 value) external pure returns (uint256) { - return array.lowerBoundMemory(value); - } - - function upperBoundMemory(uint256[] memory array, uint256 value) external pure returns (uint256) { - return array.upperBoundMemory(value); - } - - function unsafeAccess(uint256 pos) external view returns (uint256) { - return _array.unsafeAccess(pos).value; - } - - function sort(uint256[] memory array) external pure returns (uint256[] memory) { - return array.sort(); - } - - function sortReverse(uint256[] memory array) external pure returns (uint256[] memory) { - return array.sort(_reverse); - } - - function _reverse(uint256 a, uint256 b) private pure returns (bool) { - return a > b; - } - - function unsafeSetLength(uint256 newLength) external { - _array.unsafeSetLength(newLength); - } - - function length() external view returns (uint256) { - return _array.length; - } -} - -contract AddressArraysMock { - using Arrays for address[]; - - address[] private _array; - - constructor(address[] memory array) { - _array = array; - } - - function unsafeAccess(uint256 pos) external view returns (address) { - return _array.unsafeAccess(pos).value; - } - - function sort(address[] memory array) external pure returns (address[] memory) { - return array.sort(); - } - - function sortReverse(address[] memory array) external pure returns (address[] memory) { - return array.sort(_reverse); - } - - function _reverse(address a, address b) private pure returns (bool) { - return uint160(a) > uint160(b); - } - - function unsafeSetLength(uint256 newLength) external { - _array.unsafeSetLength(newLength); - } - - function length() external view returns (uint256) { - return _array.length; - } -} - -contract Bytes32ArraysMock { - using Arrays for bytes32[]; - - bytes32[] private _array; - - constructor(bytes32[] memory array) { - _array = array; - } - - function unsafeAccess(uint256 pos) external view returns (bytes32) { - return _array.unsafeAccess(pos).value; - } - - function sort(bytes32[] memory array) external pure returns (bytes32[] memory) { - return array.sort(); - } - - function sortReverse(bytes32[] memory array) external pure returns (bytes32[] memory) { - return array.sort(_reverse); - } - - function _reverse(bytes32 a, bytes32 b) private pure returns (bool) { - return uint256(a) > uint256(b); - } - - function unsafeSetLength(uint256 newLength) external { - _array.unsafeSetLength(newLength); - } - - function length() external view returns (uint256) { - return _array.length; - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/AuthorityMock.sol b/lib/openzeppelin-contracts/contracts/mocks/AuthorityMock.sol deleted file mode 100644 index 4f3e1de..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/AuthorityMock.sol +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {IAccessManaged} from "../access/manager/IAccessManaged.sol"; -import {IAuthority} from "../access/manager/IAuthority.sol"; - -contract NotAuthorityMock is IAuthority { - function canCall(address /* caller */, address /* target */, bytes4 /* selector */) external pure returns (bool) { - revert("AuthorityNoDelayMock: not implemented"); - } -} - -contract AuthorityNoDelayMock is IAuthority { - bool _immediate; - - function canCall( - address /* caller */, - address /* target */, - bytes4 /* selector */ - ) external view returns (bool immediate) { - return _immediate; - } - - function _setImmediate(bool immediate) external { - _immediate = immediate; - } -} - -contract AuthorityDelayMock { - bool _immediate; - uint32 _delay; - - function canCall( - address /* caller */, - address /* target */, - bytes4 /* selector */ - ) external view returns (bool immediate, uint32 delay) { - return (_immediate, _delay); - } - - function _setImmediate(bool immediate) external { - _immediate = immediate; - } - - function _setDelay(uint32 delay) external { - _delay = delay; - } -} - -contract AuthorityNoResponse { - function canCall(address /* caller */, address /* target */, bytes4 /* selector */) external view {} -} - -contract AuthorityObserveIsConsuming { - event ConsumeScheduledOpCalled(address caller, bytes data, bytes4 isConsuming); - - function canCall( - address /* caller */, - address /* target */, - bytes4 /* selector */ - ) external pure returns (bool immediate, uint32 delay) { - return (false, 1); - } - - function consumeScheduledOp(address caller, bytes memory data) public { - emit ConsumeScheduledOpCalled(caller, data, IAccessManaged(msg.sender).isConsumingScheduledOp()); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/Base64Dirty.sol b/lib/openzeppelin-contracts/contracts/mocks/Base64Dirty.sol deleted file mode 100644 index 238bd26..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/Base64Dirty.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {Base64} from "../utils/Base64.sol"; - -contract Base64Dirty { - struct A { - uint256 value; - } - - function encode(bytes memory input) public pure returns (string memory) { - A memory unused = A({value: type(uint256).max}); - // To silence warning - unused; - - return Base64.encode(input); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/CallReceiverMock.sol b/lib/openzeppelin-contracts/contracts/mocks/CallReceiverMock.sol deleted file mode 100644 index e371c7d..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/CallReceiverMock.sol +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -contract CallReceiverMock { - event MockFunctionCalled(); - event MockFunctionCalledWithArgs(uint256 a, uint256 b); - - uint256[] private _array; - - function mockFunction() public payable returns (string memory) { - emit MockFunctionCalled(); - - return "0x1234"; - } - - function mockFunctionEmptyReturn() public payable { - emit MockFunctionCalled(); - } - - 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(bytes32 slot, bytes32 value) public returns (string memory) { - assembly { - sstore(slot, value) - } - return "0x1234"; - } -} - -contract CallReceiverMockTrustingForwarder is CallReceiverMock { - address private _trustedForwarder; - - constructor(address trustedForwarder_) { - _trustedForwarder = trustedForwarder_; - } - - function isTrustedForwarder(address forwarder) public view virtual returns (bool) { - return forwarder == _trustedForwarder; - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/ConstructorMock.sol b/lib/openzeppelin-contracts/contracts/mocks/ConstructorMock.sol deleted file mode 100644 index 50e671b..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/ConstructorMock.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -contract ConstructorMock { - bool foo; - - enum RevertType { - None, - RevertWithoutMessage, - RevertWithMessage, - RevertWithCustomError, - Panic - } - - error CustomError(); - - constructor(RevertType error) { - // After transpilation to upgradeable contract, the constructor will become an initializer - // To silence the `... can be restricted to view` warning, we write to state - foo = true; - - if (error == RevertType.RevertWithoutMessage) { - revert(); - } else if (error == RevertType.RevertWithMessage) { - revert("ConstructorMock: reverting"); - } else if (error == RevertType.RevertWithCustomError) { - revert CustomError(); - } else if (error == RevertType.Panic) { - uint256 a = uint256(0) / uint256(0); - a; - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/ContextMock.sol b/lib/openzeppelin-contracts/contracts/mocks/ContextMock.sol deleted file mode 100644 index 199b2a9..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/ContextMock.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {Context} from "../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); - } - - event DataShort(bytes data); - - function msgDataShort() public { - emit DataShort(_msgData()); - } -} - -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/openzeppelin-contracts/contracts/mocks/DummyImplementation.sol b/lib/openzeppelin-contracts/contracts/mocks/DummyImplementation.sol deleted file mode 100644 index 4925c89..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/DummyImplementation.sol +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {ERC1967Utils} from "../proxy/ERC1967/ERC1967Utils.sol"; -import {StorageSlot} from "../utils/StorageSlot.sol"; - -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"); - } - - // Use for forcing an unsafe TransparentUpgradeableProxy admin override - function unsafeOverrideAdmin(address newAdmin) public { - StorageSlot.getAddressSlot(ERC1967Utils.ADMIN_SLOT).value = newAdmin; - } -} - -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/openzeppelin-contracts/contracts/mocks/EIP712Verifier.sol b/lib/openzeppelin-contracts/contracts/mocks/EIP712Verifier.sol deleted file mode 100644 index fe32a21..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/EIP712Verifier.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {ECDSA} from "../utils/cryptography/ECDSA.sol"; -import {EIP712} from "../utils/cryptography/EIP712.sol"; - -abstract contract EIP712Verifier is EIP712 { - 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); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/ERC1271WalletMock.sol b/lib/openzeppelin-contracts/contracts/mocks/ERC1271WalletMock.sol deleted file mode 100644 index cba7d47..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/ERC1271WalletMock.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {Ownable} from "../access/Ownable.sol"; -import {IERC1271} from "../interfaces/IERC1271.sol"; -import {ECDSA} from "../utils/cryptography/ECDSA.sol"; - -contract ERC1271WalletMock is Ownable, IERC1271 { - constructor(address originalOwner) Ownable(originalOwner) {} - - function isValidSignature(bytes32 hash, bytes memory signature) public view 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 returns (bytes4) { - assembly { - mstore(0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - return(0, 32) - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165InterfacesSupported.sol b/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165InterfacesSupported.sol deleted file mode 100644 index dffd6a2..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165InterfacesSupported.sol +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {IERC165} from "../../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 interfaceId => bool) private _supportedInterfaces; - - /** - * @dev A contract implementing SupportsInterfaceWithLookup - * implement ERC-165 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/openzeppelin-contracts/contracts/mocks/ERC165/ERC165MaliciousData.sol b/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165MaliciousData.sol deleted file mode 100644 index 3542756..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165MaliciousData.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -contract ERC165MaliciousData { - function supportsInterface(bytes4) public pure returns (bool) { - assembly { - mstore(0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - return(0, 32) - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165MissingData.sol b/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165MissingData.sol deleted file mode 100644 index fec4339..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165MissingData.sol +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -contract ERC165MissingData { - function supportsInterface(bytes4 interfaceId) public view {} // missing return -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165NotSupported.sol b/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165NotSupported.sol deleted file mode 100644 index 78ef9c8..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165NotSupported.sol +++ /dev/null @@ -1,5 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -contract ERC165NotSupported {} diff --git a/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165ReturnBomb.sol b/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165ReturnBomb.sol deleted file mode 100644 index 4bfacfd..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165ReturnBomb.sol +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {IERC165} from "../../utils/introspection/IERC165.sol"; - -contract ERC165ReturnBombMock is IERC165 { - function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { - if (interfaceId == type(IERC165).interfaceId) { - assembly { - mstore(0, 1) - } - } - assembly { - return(0, 101500) - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/ERC2771ContextMock.sol b/lib/openzeppelin-contracts/contracts/mocks/ERC2771ContextMock.sol deleted file mode 100644 index 33887cf..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/ERC2771ContextMock.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {ContextMock} from "./ContextMock.sol"; -import {Context} from "../utils/Context.sol"; -import {Multicall} from "../utils/Multicall.sol"; -import {ERC2771Context} from "../metatx/ERC2771Context.sol"; - -// By inheriting from ERC2771Context, Context's internal functions are overridden automatically -contract ERC2771ContextMock is ContextMock, ERC2771Context, Multicall { - /// @custom:oz-upgrades-unsafe-allow constructor - constructor(address trustedForwarder) ERC2771Context(trustedForwarder) { - emit Sender(_msgSender()); // _msgSender() should be accessible during construction - } - - function _msgSender() internal view override(Context, ERC2771Context) returns (address) { - return ERC2771Context._msgSender(); - } - - function _msgData() internal view override(Context, ERC2771Context) returns (bytes calldata) { - return ERC2771Context._msgData(); - } - - function _contextSuffixLength() internal view override(Context, ERC2771Context) returns (uint256) { - return ERC2771Context._contextSuffixLength(); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/ERC3156FlashBorrowerMock.sol b/lib/openzeppelin-contracts/contracts/mocks/ERC3156FlashBorrowerMock.sol deleted file mode 100644 index 261fea1..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/ERC3156FlashBorrowerMock.sol +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {IERC20} from "../token/ERC20/IERC20.sol"; -import {IERC3156FlashBorrower} from "../interfaces/IERC3156.sol"; -import {Address} from "../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 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/openzeppelin-contracts/contracts/mocks/EtherReceiverMock.sol b/lib/openzeppelin-contracts/contracts/mocks/EtherReceiverMock.sol deleted file mode 100644 index 1b1c936..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/EtherReceiverMock.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -contract EtherReceiverMock { - bool private _acceptEther; - - function setAcceptEther(bool acceptEther) public { - _acceptEther = acceptEther; - } - - receive() external payable { - if (!_acceptEther) { - revert(); - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/InitializableMock.sol b/lib/openzeppelin-contracts/contracts/mocks/InitializableMock.sol deleted file mode 100644 index 7f76caa..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/InitializableMock.sol +++ /dev/null @@ -1,130 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {Initializable} from "../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 (uint64) { - return _getInitializedVersion(); - } - - function initialize() public initializer { - doStuff(); - } - - function reinitialize(uint64 i) public reinitializer(i) { - doStuff(); - } - - function nestedReinitialize(uint64 i, uint64 j) public reinitializer(i) { - reinitialize(j); - } - - function chainReinitialize(uint64 i, uint64 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/openzeppelin-contracts/contracts/mocks/MerkleProofCustomHashMock.sol b/lib/openzeppelin-contracts/contracts/mocks/MerkleProofCustomHashMock.sol deleted file mode 100644 index 1039af3..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/MerkleProofCustomHashMock.sol +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {MerkleProof} from "../utils/cryptography/MerkleProof.sol"; - -// This could be a library, but then we would have to add it to the Stateless.sol mock for upgradeable tests -abstract contract MerkleProofCustomHashMock { - function customHash(bytes32 a, bytes32 b) internal pure returns (bytes32) { - return a < b ? sha256(abi.encode(a, b)) : sha256(abi.encode(b, a)); - } - - function verify(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal view returns (bool) { - return MerkleProof.verify(proof, root, leaf, customHash); - } - - function processProof(bytes32[] calldata proof, bytes32 leaf) internal view returns (bytes32) { - return MerkleProof.processProof(proof, leaf, customHash); - } - - function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal view returns (bool) { - return MerkleProof.verifyCalldata(proof, root, leaf, customHash); - } - - function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal view returns (bytes32) { - return MerkleProof.processProofCalldata(proof, leaf, customHash); - } - - function multiProofVerify( - bytes32[] calldata proof, - bool[] calldata proofFlags, - bytes32 root, - bytes32[] calldata leaves - ) internal view returns (bool) { - return MerkleProof.multiProofVerify(proof, proofFlags, root, leaves, customHash); - } - - function processMultiProof( - bytes32[] calldata proof, - bool[] calldata proofFlags, - bytes32[] calldata leaves - ) internal view returns (bytes32) { - return MerkleProof.processMultiProof(proof, proofFlags, leaves, customHash); - } - - function multiProofVerifyCalldata( - bytes32[] calldata proof, - bool[] calldata proofFlags, - bytes32 root, - bytes32[] calldata leaves - ) internal view returns (bool) { - return MerkleProof.multiProofVerifyCalldata(proof, proofFlags, root, leaves, customHash); - } - - function processMultiProofCalldata( - bytes32[] calldata proof, - bool[] calldata proofFlags, - bytes32[] calldata leaves - ) internal view returns (bytes32) { - return MerkleProof.processMultiProofCalldata(proof, proofFlags, leaves, customHash); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/MerkleTreeMock.sol b/lib/openzeppelin-contracts/contracts/mocks/MerkleTreeMock.sol deleted file mode 100644 index 2454efa..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/MerkleTreeMock.sol +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import {MerkleTree} from "../utils/structs/MerkleTree.sol"; - -contract MerkleTreeMock { - using MerkleTree for MerkleTree.Bytes32PushTree; - - MerkleTree.Bytes32PushTree private _tree; - - // This mock only stored the latest root. - // Production contract may want to store historical values. - bytes32 public root; - - event LeafInserted(bytes32 leaf, uint256 index, bytes32 root); - - function setup(uint8 _depth, bytes32 _zero) public { - root = _tree.setup(_depth, _zero); - } - - function push(bytes32 leaf) public { - (uint256 leafIndex, bytes32 currentRoot) = _tree.push(leaf); - emit LeafInserted(leaf, leafIndex, currentRoot); - root = currentRoot; - } - - function depth() public view returns (uint256) { - return _tree.depth(); - } - - // internal state - function nextLeafIndex() public view returns (uint256) { - return _tree._nextLeafIndex; - } - - function sides(uint256 i) public view returns (bytes32) { - return _tree._sides[i]; - } - - function zeros(uint256 i) public view returns (bytes32) { - return _tree._zeros[i]; - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/MulticallHelper.sol b/lib/openzeppelin-contracts/contracts/mocks/MulticallHelper.sol deleted file mode 100644 index d70f3bf..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/MulticallHelper.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {ERC20MulticallMock} from "./token/ERC20MulticallMock.sol"; - -contract MulticallHelper { - function checkReturnValues( - ERC20MulticallMock 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.encodeCall(multicallToken.transfer, (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/openzeppelin-contracts/contracts/mocks/MultipleInheritanceInitializableMocks.sol b/lib/openzeppelin-contracts/contracts/mocks/MultipleInheritanceInitializableMocks.sol deleted file mode 100644 index 51030ac..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/MultipleInheritanceInitializableMocks.sol +++ /dev/null @@ -1,131 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {Initializable} from "../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 initializable 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 initializable 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 initializable 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 initializable 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/openzeppelin-contracts/contracts/mocks/PausableMock.sol b/lib/openzeppelin-contracts/contracts/mocks/PausableMock.sol deleted file mode 100644 index fa701e2..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/PausableMock.sol +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {Pausable} from "../utils/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/openzeppelin-contracts/contracts/mocks/ReentrancyAttack.sol b/lib/openzeppelin-contracts/contracts/mocks/ReentrancyAttack.sol deleted file mode 100644 index 3df2d1c..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/ReentrancyAttack.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {Context} from "../utils/Context.sol"; - -contract ReentrancyAttack is Context { - function callSender(bytes calldata data) public { - (bool success, ) = _msgSender().call(data); - require(success, "ReentrancyAttack: failed call"); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/ReentrancyMock.sol b/lib/openzeppelin-contracts/contracts/mocks/ReentrancyMock.sol deleted file mode 100644 index 39e2d5e..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/ReentrancyMock.sol +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {ReentrancyGuard} from "../utils/ReentrancyGuard.sol"; -import {ReentrancyAttack} from "./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.encodeCall(this.countThisRecursive, (n - 1))); - require(success, "ReentrancyMock: failed call"); - } - } - - function countAndCall(ReentrancyAttack attacker) public nonReentrant { - _count(); - attacker.callSender(abi.encodeCall(this.callback, ())); - } - - function _count() private { - counter += 1; - } - - function guardedCheckEntered() public nonReentrant { - require(_reentrancyGuardEntered()); - } - - function unguardedCheckNotEntered() public view { - require(!_reentrancyGuardEntered()); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/ReentrancyTransientMock.sol b/lib/openzeppelin-contracts/contracts/mocks/ReentrancyTransientMock.sol deleted file mode 100644 index f0e61ea..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/ReentrancyTransientMock.sol +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -import {ReentrancyGuardTransient} from "../utils/ReentrancyGuardTransient.sol"; -import {ReentrancyAttack} from "./ReentrancyAttack.sol"; - -contract ReentrancyTransientMock is ReentrancyGuardTransient { - 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.encodeCall(this.countThisRecursive, (n - 1))); - require(success, "ReentrancyTransientMock: failed call"); - } - } - - function countAndCall(ReentrancyAttack attacker) public nonReentrant { - _count(); - attacker.callSender(abi.encodeCall(this.callback, ())); - } - - function _count() private { - counter += 1; - } - - function guardedCheckEntered() public nonReentrant { - require(_reentrancyGuardEntered()); - } - - function unguardedCheckNotEntered() public view { - require(!_reentrancyGuardEntered()); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/RegressionImplementation.sol b/lib/openzeppelin-contracts/contracts/mocks/RegressionImplementation.sol deleted file mode 100644 index 19b9706..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/RegressionImplementation.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {Initializable} from "../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/openzeppelin-contracts/contracts/mocks/SingleInheritanceInitializableMocks.sol b/lib/openzeppelin-contracts/contracts/mocks/SingleInheritanceInitializableMocks.sol deleted file mode 100644 index 0bd3c61..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/SingleInheritanceInitializableMocks.sol +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {Initializable} from "../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/openzeppelin-contracts/contracts/mocks/Stateless.sol b/lib/openzeppelin-contracts/contracts/mocks/Stateless.sol deleted file mode 100644 index 7f18d57..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/Stateless.sol +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -// We keep these imports and a dummy contract just to we can run the test suite after transpilation. - -import {Address} from "../utils/Address.sol"; -import {Arrays} from "../utils/Arrays.sol"; -import {AuthorityUtils} from "../access/manager/AuthorityUtils.sol"; -import {Base64} from "../utils/Base64.sol"; -import {BitMaps} from "../utils/structs/BitMaps.sol"; -import {Checkpoints} from "../utils/structs/Checkpoints.sol"; -import {CircularBuffer} from "../utils/structs/CircularBuffer.sol"; -import {Clones} from "../proxy/Clones.sol"; -import {Create2} from "../utils/Create2.sol"; -import {DoubleEndedQueue} from "../utils/structs/DoubleEndedQueue.sol"; -import {ECDSA} from "../utils/cryptography/ECDSA.sol"; -import {EnumerableMap} from "../utils/structs/EnumerableMap.sol"; -import {EnumerableSet} from "../utils/structs/EnumerableSet.sol"; -import {ERC1155Holder} from "../token/ERC1155/utils/ERC1155Holder.sol"; -import {ERC165} from "../utils/introspection/ERC165.sol"; -import {ERC165Checker} from "../utils/introspection/ERC165Checker.sol"; -import {ERC1967Utils} from "../proxy/ERC1967/ERC1967Utils.sol"; -import {ERC721Holder} from "../token/ERC721/utils/ERC721Holder.sol"; -import {Math} from "../utils/math/Math.sol"; -import {MerkleProof} from "../utils/cryptography/MerkleProof.sol"; -import {MessageHashUtils} from "../utils/cryptography/MessageHashUtils.sol"; -import {P256} from "../utils/cryptography/P256.sol"; -import {Panic} from "../utils/Panic.sol"; -import {Packing} from "../utils/Packing.sol"; -import {RSA} from "../utils/cryptography/RSA.sol"; -import {SafeCast} from "../utils/math/SafeCast.sol"; -import {SafeERC20} from "../token/ERC20/utils/SafeERC20.sol"; -import {ShortStrings} from "../utils/ShortStrings.sol"; -import {SignatureChecker} from "../utils/cryptography/SignatureChecker.sol"; -import {SignedMath} from "../utils/math/SignedMath.sol"; -import {StorageSlot} from "../utils/StorageSlot.sol"; -import {Strings} from "../utils/Strings.sol"; -import {Time} from "../utils/types/Time.sol"; - -contract Dummy1234 {} diff --git a/lib/openzeppelin-contracts/contracts/mocks/StorageSlotMock.sol b/lib/openzeppelin-contracts/contracts/mocks/StorageSlotMock.sol deleted file mode 100644 index e69bd36..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/StorageSlotMock.sol +++ /dev/null @@ -1,137 +0,0 @@ -// SPDX-License-Identifier: MIT -// This file was procedurally generated from scripts/generate/templates/StorageSlotMock.js. - -pragma solidity ^0.8.24; - -import {Multicall} from "../utils/Multicall.sol"; -import {StorageSlot} from "../utils/StorageSlot.sol"; - -contract StorageSlotMock is Multicall { - using StorageSlot for *; - - function setAddressSlot(bytes32 slot, address value) public { - slot.getAddressSlot().value = value; - } - - function setBooleanSlot(bytes32 slot, bool value) public { - slot.getBooleanSlot().value = value; - } - - function setBytes32Slot(bytes32 slot, bytes32 value) public { - slot.getBytes32Slot().value = value; - } - - function setUint256Slot(bytes32 slot, uint256 value) public { - slot.getUint256Slot().value = value; - } - - function setInt256Slot(bytes32 slot, int256 value) public { - slot.getInt256Slot().value = value; - } - - function getAddressSlot(bytes32 slot) public view returns (address) { - return slot.getAddressSlot().value; - } - - function getBooleanSlot(bytes32 slot) public view returns (bool) { - return slot.getBooleanSlot().value; - } - - function getBytes32Slot(bytes32 slot) public view returns (bytes32) { - return slot.getBytes32Slot().value; - } - - function getUint256Slot(bytes32 slot) public view returns (uint256) { - return slot.getUint256Slot().value; - } - - function getInt256Slot(bytes32 slot) public view returns (int256) { - return slot.getInt256Slot().value; - } - - mapping(uint256 key => string) public stringMap; - - function setStringSlot(bytes32 slot, string calldata value) public { - slot.getStringSlot().value = value; - } - - function setStringStorage(uint256 key, string calldata value) public { - stringMap[key].getStringSlot().value = value; - } - - function getStringSlot(bytes32 slot) public view returns (string memory) { - return slot.getStringSlot().value; - } - - function getStringStorage(uint256 key) public view returns (string memory) { - return stringMap[key].getStringSlot().value; - } - - mapping(uint256 key => bytes) public bytesMap; - - function setBytesSlot(bytes32 slot, bytes calldata value) public { - slot.getBytesSlot().value = value; - } - - function setBytesStorage(uint256 key, bytes calldata value) public { - bytesMap[key].getBytesSlot().value = value; - } - - function getBytesSlot(bytes32 slot) public view returns (bytes memory) { - return slot.getBytesSlot().value; - } - - function getBytesStorage(uint256 key) public view returns (bytes memory) { - return bytesMap[key].getBytesSlot().value; - } - - event AddressValue(bytes32 slot, address value); - - function tloadAddress(bytes32 slot) public { - emit AddressValue(slot, slot.asAddress().tload()); - } - - function tstore(bytes32 slot, address value) public { - slot.asAddress().tstore(value); - } - - event BooleanValue(bytes32 slot, bool value); - - function tloadBoolean(bytes32 slot) public { - emit BooleanValue(slot, slot.asBoolean().tload()); - } - - function tstore(bytes32 slot, bool value) public { - slot.asBoolean().tstore(value); - } - - event Bytes32Value(bytes32 slot, bytes32 value); - - function tloadBytes32(bytes32 slot) public { - emit Bytes32Value(slot, slot.asBytes32().tload()); - } - - function tstore(bytes32 slot, bytes32 value) public { - slot.asBytes32().tstore(value); - } - - event Uint256Value(bytes32 slot, uint256 value); - - function tloadUint256(bytes32 slot) public { - emit Uint256Value(slot, slot.asUint256().tload()); - } - - function tstore(bytes32 slot, uint256 value) public { - slot.asUint256().tstore(value); - } - - event Int256Value(bytes32 slot, int256 value); - - function tloadInt256(bytes32 slot) public { - emit Int256Value(slot, slot.asInt256().tload()); - } - - function tstore(bytes32 slot, int256 value) public { - slot.asInt256().tstore(value); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/TimelockReentrant.sol b/lib/openzeppelin-contracts/contracts/mocks/TimelockReentrant.sol deleted file mode 100644 index aab676a..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/TimelockReentrant.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import {Address} from "../utils/Address.sol"; - -contract TimelockReentrant { - address private _reenterTarget; - bytes private _reenterData; - bool _reentered; - - function disableReentrancy() external { - _reentered = true; - } - - function enableRentrancy(address target, bytes calldata data) external { - _reenterTarget = target; - _reenterData = data; - } - - function reenter() external { - if (!_reentered) { - _reentered = true; - Address.functionCall(_reenterTarget, _reenterData); - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/UpgradeableBeaconMock.sol b/lib/openzeppelin-contracts/contracts/mocks/UpgradeableBeaconMock.sol deleted file mode 100644 index 354ac02..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/UpgradeableBeaconMock.sol +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import {IBeacon} from "../proxy/beacon/IBeacon.sol"; - -contract UpgradeableBeaconMock is IBeacon { - address public implementation; - - constructor(address impl) { - implementation = impl; - } -} - -interface IProxyExposed { - // solhint-disable-next-line func-name-mixedcase - function $getBeacon() external view returns (address); -} - -contract UpgradeableBeaconReentrantMock is IBeacon { - error BeaconProxyBeaconSlotAddress(address beacon); - - function implementation() external view override returns (address) { - // Revert with the beacon seen in the proxy at the moment of calling to check if it's - // set before the call. - revert BeaconProxyBeaconSlotAddress(IProxyExposed(msg.sender).$getBeacon()); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/VotesMock.sol b/lib/openzeppelin-contracts/contracts/mocks/VotesMock.sol deleted file mode 100644 index e28d6b5..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/VotesMock.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {Votes} from "../governance/utils/Votes.sol"; - -abstract contract VotesMock is Votes { - mapping(address voter => uint256) private _votingUnits; - - 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 _votingUnits[account]; - } - - function _mint(address account, uint256 votes) internal { - _votingUnits[account] += votes; - _transferVotingUnits(address(0), account, votes); - } - - function _burn(address account, uint256 votes) internal { - _votingUnits[account] += votes; - _transferVotingUnits(account, address(0), votes); - } -} - -abstract contract VotesTimestampMock is VotesMock { - function clock() public view override returns (uint48) { - return uint48(block.timestamp); - } - - // solhint-disable-next-line func-name-mixedcase - function CLOCK_MODE() public view virtual override returns (string memory) { - return "mode=timestamp"; - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/compound/CompTimelock.sol b/lib/openzeppelin-contracts/contracts/mocks/compound/CompTimelock.sol deleted file mode 100644 index c72ed08..0000000 --- a/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.20; - -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/openzeppelin-contracts/contracts/mocks/governance/GovernorFractionalMock.sol b/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorFractionalMock.sol deleted file mode 100644 index d6d6042..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorFractionalMock.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {Governor} from "../../governance/Governor.sol"; -import {GovernorSettings} from "../../governance/extensions/GovernorSettings.sol"; -import {GovernorCountingFractional} from "../../governance/extensions/GovernorCountingFractional.sol"; -import {GovernorVotesQuorumFraction} from "../../governance/extensions/GovernorVotesQuorumFraction.sol"; - -abstract contract GovernorFractionalMock is GovernorSettings, GovernorVotesQuorumFraction, GovernorCountingFractional { - function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) { - return super.proposalThreshold(); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorMock.sol b/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorMock.sol deleted file mode 100644 index 69668d2..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorMock.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {Governor} from "../../governance/Governor.sol"; -import {GovernorSettings} from "../../governance/extensions/GovernorSettings.sol"; -import {GovernorCountingSimple} from "../../governance/extensions/GovernorCountingSimple.sol"; -import {GovernorVotesQuorumFraction} from "../../governance/extensions/GovernorVotesQuorumFraction.sol"; - -abstract contract GovernorMock is GovernorSettings, GovernorVotesQuorumFraction, GovernorCountingSimple { - function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) { - return super.proposalThreshold(); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorPreventLateQuorumMock.sol b/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorPreventLateQuorumMock.sol deleted file mode 100644 index fde0863..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorPreventLateQuorumMock.sol +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {Governor} from "../../governance/Governor.sol"; -import {GovernorPreventLateQuorum} from "../../governance/extensions/GovernorPreventLateQuorum.sol"; -import {GovernorSettings} from "../../governance/extensions/GovernorSettings.sol"; -import {GovernorCountingSimple} from "../../governance/extensions/GovernorCountingSimple.sol"; -import {GovernorVotes} from "../../governance/extensions/GovernorVotes.sol"; - -abstract contract GovernorPreventLateQuorumMock is - GovernorSettings, - GovernorVotes, - GovernorCountingSimple, - GovernorPreventLateQuorum -{ - uint256 private _quorum; - - constructor(uint256 quorum_) { - _quorum = quorum_; - } - - function quorum(uint256) public view override returns (uint256) { - return _quorum; - } - - function proposalDeadline( - uint256 proposalId - ) public view override(Governor, GovernorPreventLateQuorum) returns (uint256) { - return super.proposalDeadline(proposalId); - } - - function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) { - return super.proposalThreshold(); - } - - function _castVote( - uint256 proposalId, - address account, - uint8 support, - string memory reason, - bytes memory params - ) internal override(Governor, GovernorPreventLateQuorum) returns (uint256) { - return super._castVote(proposalId, account, support, reason, params); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorStorageMock.sol b/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorStorageMock.sol deleted file mode 100644 index 88c6bf9..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorStorageMock.sol +++ /dev/null @@ -1,79 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.19; - -import {IGovernor, Governor} from "../../governance/Governor.sol"; -import {GovernorTimelockControl} from "../../governance/extensions/GovernorTimelockControl.sol"; -import {GovernorSettings} from "../../governance/extensions/GovernorSettings.sol"; -import {GovernorCountingSimple} from "../../governance/extensions/GovernorCountingSimple.sol"; -import {GovernorVotesQuorumFraction} from "../../governance/extensions/GovernorVotesQuorumFraction.sol"; -import {GovernorStorage} from "../../governance/extensions/GovernorStorage.sol"; - -abstract contract GovernorStorageMock is - GovernorSettings, - GovernorTimelockControl, - GovernorVotesQuorumFraction, - GovernorCountingSimple, - GovernorStorage -{ - function quorum(uint256 blockNumber) public view override(Governor, GovernorVotesQuorumFraction) returns (uint256) { - return super.quorum(blockNumber); - } - - function state(uint256 proposalId) public view override(Governor, GovernorTimelockControl) returns (ProposalState) { - return super.state(proposalId); - } - - function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) { - return super.proposalThreshold(); - } - - function proposalNeedsQueuing( - uint256 proposalId - ) public view virtual override(Governor, GovernorTimelockControl) returns (bool) { - return super.proposalNeedsQueuing(proposalId); - } - - function _propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description, - address proposer - ) internal virtual override(Governor, GovernorStorage) returns (uint256) { - return super._propose(targets, values, calldatas, description, proposer); - } - - function _queueOperations( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(Governor, GovernorTimelockControl) returns (uint48) { - return super._queueOperations(proposalId, targets, values, calldatas, descriptionHash); - } - - function _executeOperations( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(Governor, GovernorTimelockControl) { - super._executeOperations(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(); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorTimelockAccessMock.sol b/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorTimelockAccessMock.sol deleted file mode 100644 index 3d1bbee..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorTimelockAccessMock.sol +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {IGovernor, Governor} from "../../governance/Governor.sol"; -import {GovernorTimelockAccess} from "../../governance/extensions/GovernorTimelockAccess.sol"; -import {GovernorSettings} from "../../governance/extensions/GovernorSettings.sol"; -import {GovernorCountingSimple} from "../../governance/extensions/GovernorCountingSimple.sol"; -import {GovernorVotesQuorumFraction} from "../../governance/extensions/GovernorVotesQuorumFraction.sol"; - -abstract contract GovernorTimelockAccessMock is - GovernorSettings, - GovernorTimelockAccess, - GovernorVotesQuorumFraction, - GovernorCountingSimple -{ - function nonGovernanceFunction() external {} - - function quorum(uint256 blockNumber) public view override(Governor, GovernorVotesQuorumFraction) returns (uint256) { - return super.quorum(blockNumber); - } - - function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) { - return super.proposalThreshold(); - } - - function proposalNeedsQueuing( - uint256 proposalId - ) public view virtual override(Governor, GovernorTimelockAccess) returns (bool) { - return super.proposalNeedsQueuing(proposalId); - } - - function propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description - ) public override(Governor, GovernorTimelockAccess) returns (uint256) { - return super.propose(targets, values, calldatas, description); - } - - function _queueOperations( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(Governor, GovernorTimelockAccess) returns (uint48) { - return super._queueOperations(proposalId, targets, values, calldatas, descriptionHash); - } - - function _executeOperations( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(Governor, GovernorTimelockAccess) { - super._executeOperations(proposalId, targets, values, calldatas, descriptionHash); - } - - function _cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(Governor, GovernorTimelockAccess) returns (uint256) { - return super._cancel(targets, values, calldatas, descriptionHash); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorTimelockCompoundMock.sol b/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorTimelockCompoundMock.sol deleted file mode 100644 index 03ef625..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorTimelockCompoundMock.sol +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {IGovernor, Governor} from "../../governance/Governor.sol"; -import {GovernorTimelockCompound} from "../../governance/extensions/GovernorTimelockCompound.sol"; -import {GovernorSettings} from "../../governance/extensions/GovernorSettings.sol"; -import {GovernorCountingSimple} from "../../governance/extensions/GovernorCountingSimple.sol"; -import {GovernorVotesQuorumFraction} from "../../governance/extensions/GovernorVotesQuorumFraction.sol"; - -abstract contract GovernorTimelockCompoundMock is - GovernorSettings, - GovernorTimelockCompound, - GovernorVotesQuorumFraction, - GovernorCountingSimple -{ - function quorum(uint256 blockNumber) public view override(Governor, GovernorVotesQuorumFraction) returns (uint256) { - return super.quorum(blockNumber); - } - - function state( - uint256 proposalId - ) public view override(Governor, GovernorTimelockCompound) returns (ProposalState) { - return super.state(proposalId); - } - - function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) { - return super.proposalThreshold(); - } - - function proposalNeedsQueuing( - uint256 proposalId - ) public view virtual override(Governor, GovernorTimelockCompound) returns (bool) { - return super.proposalNeedsQueuing(proposalId); - } - - function _queueOperations( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(Governor, GovernorTimelockCompound) returns (uint48) { - return super._queueOperations(proposalId, targets, values, calldatas, descriptionHash); - } - - function _executeOperations( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(Governor, GovernorTimelockCompound) { - super._executeOperations(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(); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorTimelockControlMock.sol b/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorTimelockControlMock.sol deleted file mode 100644 index edaccc0..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorTimelockControlMock.sol +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {IGovernor, Governor} from "../../governance/Governor.sol"; -import {GovernorTimelockControl} from "../../governance/extensions/GovernorTimelockControl.sol"; -import {GovernorSettings} from "../../governance/extensions/GovernorSettings.sol"; -import {GovernorCountingSimple} from "../../governance/extensions/GovernorCountingSimple.sol"; -import {GovernorVotesQuorumFraction} from "../../governance/extensions/GovernorVotesQuorumFraction.sol"; - -abstract contract GovernorTimelockControlMock is - GovernorSettings, - GovernorTimelockControl, - GovernorVotesQuorumFraction, - GovernorCountingSimple -{ - function quorum(uint256 blockNumber) public view override(Governor, GovernorVotesQuorumFraction) returns (uint256) { - return super.quorum(blockNumber); - } - - function state(uint256 proposalId) public view override(Governor, GovernorTimelockControl) returns (ProposalState) { - return super.state(proposalId); - } - - function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) { - return super.proposalThreshold(); - } - - function proposalNeedsQueuing( - uint256 proposalId - ) public view virtual override(Governor, GovernorTimelockControl) returns (bool) { - return super.proposalNeedsQueuing(proposalId); - } - - function _queueOperations( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(Governor, GovernorTimelockControl) returns (uint48) { - return super._queueOperations(proposalId, targets, values, calldatas, descriptionHash); - } - - function _executeOperations( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(Governor, GovernorTimelockControl) { - super._executeOperations(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 nonGovernanceFunction() external {} -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorVoteMock.sol b/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorVoteMock.sol deleted file mode 100644 index e6949b5..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorVoteMock.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {GovernorCountingSimple} from "../../governance/extensions/GovernorCountingSimple.sol"; -import {GovernorVotes} from "../../governance/extensions/GovernorVotes.sol"; - -abstract contract GovernorVoteMocks is GovernorVotes, GovernorCountingSimple { - 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; - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorWithParamsMock.sol b/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorWithParamsMock.sol deleted file mode 100644 index 29b738e..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/governance/GovernorWithParamsMock.sol +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {Governor} from "../../governance/Governor.sol"; -import {GovernorCountingSimple} from "../../governance/extensions/GovernorCountingSimple.sol"; -import {GovernorVotes} from "../../governance/extensions/GovernorVotes.sol"; - -abstract contract GovernorWithParamsMock is GovernorVotes, GovernorCountingSimple { - event CountParams(uint256 uintParam, string strParam); - - 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(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 override(Governor, GovernorCountingSimple) returns (uint256) { - 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); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/proxy/BadBeacon.sol b/lib/openzeppelin-contracts/contracts/mocks/proxy/BadBeacon.sol deleted file mode 100644 index f3153a8..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/proxy/BadBeacon.sol +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -contract BadBeaconNoImpl {} - -contract BadBeaconNotContract { - function implementation() external pure returns (address) { - return address(0x1); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/proxy/ClashingImplementation.sol b/lib/openzeppelin-contracts/contracts/mocks/proxy/ClashingImplementation.sol deleted file mode 100644 index 43d5a34..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/proxy/ClashingImplementation.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -/** - * @dev Implementation contract with a payable changeAdmin(address) function made to clash with - * TransparentUpgradeableProxy's to test correct functioning of the Transparent Proxy feature. - */ -contract ClashingImplementation { - event ClashingImplementationCall(); - - function upgradeToAndCall(address, bytes calldata) external payable { - emit ClashingImplementationCall(); - } - - function delegatedFunction() external pure returns (bool) { - return true; - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/proxy/UUPSUpgradeableMock.sol b/lib/openzeppelin-contracts/contracts/mocks/proxy/UUPSUpgradeableMock.sol deleted file mode 100644 index a5f2d4a..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/proxy/UUPSUpgradeableMock.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {UUPSUpgradeable} from "../../proxy/utils/UUPSUpgradeable.sol"; -import {ERC1967Utils} from "../../proxy/ERC1967/ERC1967Utils.sol"; - -contract NonUpgradeableMock { - uint256 internal _counter; - - function current() external view returns (uint256) { - return _counter; - } - - function increment() external { - ++_counter; - } -} - -contract UUPSUpgradeableMock is NonUpgradeableMock, UUPSUpgradeable { - // Not having any checks in this function is dangerous! Do not do this outside tests! - function _authorizeUpgrade(address) internal override {} -} - -contract UUPSUpgradeableUnsafeMock is UUPSUpgradeableMock { - function upgradeToAndCall(address newImplementation, bytes memory data) public payable override { - ERC1967Utils.upgradeToAndCall(newImplementation, data); - } -} - -contract UUPSUnsupportedProxiableUUID is UUPSUpgradeableMock { - function proxiableUUID() external pure override returns (bytes32) { - return keccak256("invalid UUID"); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/token/ERC1155ReceiverMock.sol b/lib/openzeppelin-contracts/contracts/mocks/token/ERC1155ReceiverMock.sol deleted file mode 100644 index 2a85d1d..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/token/ERC1155ReceiverMock.sol +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {IERC1155Receiver} from "../../token/ERC1155/IERC1155Receiver.sol"; -import {ERC165} from "../../utils/introspection/ERC165.sol"; - -contract ERC1155ReceiverMock is ERC165, IERC1155Receiver { - enum RevertType { - None, - RevertWithoutMessage, - RevertWithMessage, - RevertWithCustomError, - Panic - } - - bytes4 private immutable _recRetval; - bytes4 private immutable _batRetval; - RevertType private immutable _error; - - 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); - error CustomError(bytes4); - - constructor(bytes4 recRetval, bytes4 batRetval, RevertType error) { - _recRetval = recRetval; - _batRetval = batRetval; - _error = error; - } - - function onERC1155Received( - address operator, - address from, - uint256 id, - uint256 value, - bytes calldata data - ) external returns (bytes4) { - if (_error == RevertType.RevertWithoutMessage) { - revert(); - } else if (_error == RevertType.RevertWithMessage) { - revert("ERC1155ReceiverMock: reverting on receive"); - } else if (_error == RevertType.RevertWithCustomError) { - revert CustomError(_recRetval); - } else if (_error == RevertType.Panic) { - uint256 a = uint256(0) / uint256(0); - a; - } - - 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 returns (bytes4) { - if (_error == RevertType.RevertWithoutMessage) { - revert(); - } else if (_error == RevertType.RevertWithMessage) { - revert("ERC1155ReceiverMock: reverting on batch receive"); - } else if (_error == RevertType.RevertWithCustomError) { - revert CustomError(_recRetval); - } else if (_error == RevertType.Panic) { - uint256 a = uint256(0) / uint256(0); - a; - } - - emit BatchReceived(operator, from, ids, values, data, gasleft()); - return _batRetval; - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/token/ERC1363ForceApproveMock.sol b/lib/openzeppelin-contracts/contracts/mocks/token/ERC1363ForceApproveMock.sol deleted file mode 100644 index d911a0a..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/token/ERC1363ForceApproveMock.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {IERC20} from "../../interfaces/IERC20.sol"; -import {ERC20, ERC1363} from "../../token/ERC20/extensions/ERC1363.sol"; - -// contract that replicate USDT approval behavior in approveAndCall -abstract contract ERC1363ForceApproveMock is ERC1363 { - function approveAndCall(address spender, uint256 amount, bytes memory data) public virtual override returns (bool) { - require(amount == 0 || allowance(msg.sender, spender) == 0, "USDT approval failure"); - return super.approveAndCall(spender, amount, data); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/token/ERC1363NoReturnMock.sol b/lib/openzeppelin-contracts/contracts/mocks/token/ERC1363NoReturnMock.sol deleted file mode 100644 index 748d234..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/token/ERC1363NoReturnMock.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {IERC20, ERC20} from "../../token/ERC20/ERC20.sol"; -import {ERC1363} from "../../token/ERC20/extensions/ERC1363.sol"; - -abstract contract ERC1363NoReturnMock is ERC1363 { - function transferAndCall(address to, uint256 value, bytes memory data) public override returns (bool) { - super.transferAndCall(to, value, data); - assembly { - return(0, 0) - } - } - - function transferFromAndCall( - address from, - address to, - uint256 value, - bytes memory data - ) public override returns (bool) { - super.transferFromAndCall(from, to, value, data); - assembly { - return(0, 0) - } - } - - function approveAndCall(address spender, uint256 value, bytes memory data) public override returns (bool) { - super.approveAndCall(spender, value, data); - assembly { - return(0, 0) - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/token/ERC1363ReceiverMock.sol b/lib/openzeppelin-contracts/contracts/mocks/token/ERC1363ReceiverMock.sol deleted file mode 100644 index d33e05e..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/token/ERC1363ReceiverMock.sol +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {IERC1363Receiver} from "../../interfaces/IERC1363Receiver.sol"; - -contract ERC1363ReceiverMock is IERC1363Receiver { - enum RevertType { - None, - RevertWithoutMessage, - RevertWithMessage, - RevertWithCustomError, - Panic - } - - bytes4 private _retval; - RevertType private _error; - - event Received(address operator, address from, uint256 value, bytes data); - error CustomError(bytes4); - - constructor() { - _retval = IERC1363Receiver.onTransferReceived.selector; - _error = RevertType.None; - } - - function setUp(bytes4 retval, RevertType error) public { - _retval = retval; - _error = error; - } - - function onTransferReceived( - address operator, - address from, - uint256 value, - bytes calldata data - ) external override returns (bytes4) { - if (_error == RevertType.RevertWithoutMessage) { - revert(); - } else if (_error == RevertType.RevertWithMessage) { - revert("ERC1363ReceiverMock: reverting"); - } else if (_error == RevertType.RevertWithCustomError) { - revert CustomError(_retval); - } else if (_error == RevertType.Panic) { - uint256 a = uint256(0) / uint256(0); - a; - } - - emit Received(operator, from, value, data); - return _retval; - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/token/ERC1363ReturnFalseMock.sol b/lib/openzeppelin-contracts/contracts/mocks/token/ERC1363ReturnFalseMock.sol deleted file mode 100644 index afdd01f..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/token/ERC1363ReturnFalseMock.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {IERC20, ERC20} from "../../token/ERC20/ERC20.sol"; -import {ERC1363} from "../../token/ERC20/extensions/ERC1363.sol"; - -abstract contract ERC1363ReturnFalseOnERC20Mock is ERC1363 { - function transfer(address, uint256) public pure override(IERC20, ERC20) returns (bool) { - return false; - } - - function transferFrom(address, address, uint256) public pure override(IERC20, ERC20) returns (bool) { - return false; - } - - function approve(address, uint256) public pure override(IERC20, ERC20) returns (bool) { - return false; - } -} - -abstract contract ERC1363ReturnFalseMock is ERC1363 { - function transferAndCall(address, uint256, bytes memory) public pure override returns (bool) { - return false; - } - - function transferFromAndCall(address, address, uint256, bytes memory) public pure override returns (bool) { - return false; - } - - function approveAndCall(address, uint256, bytes memory) public pure override returns (bool) { - return false; - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/token/ERC1363SpenderMock.sol b/lib/openzeppelin-contracts/contracts/mocks/token/ERC1363SpenderMock.sol deleted file mode 100644 index b12c4c1..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/token/ERC1363SpenderMock.sol +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {IERC1363Spender} from "../../interfaces/IERC1363Spender.sol"; - -contract ERC1363SpenderMock is IERC1363Spender { - enum RevertType { - None, - RevertWithoutMessage, - RevertWithMessage, - RevertWithCustomError, - Panic - } - - bytes4 private _retval; - RevertType private _error; - - event Approved(address owner, uint256 value, bytes data); - error CustomError(bytes4); - - constructor() { - _retval = IERC1363Spender.onApprovalReceived.selector; - _error = RevertType.None; - } - - function setUp(bytes4 retval, RevertType error) public { - _retval = retval; - _error = error; - } - - function onApprovalReceived(address owner, uint256 value, bytes calldata data) external override returns (bytes4) { - if (_error == RevertType.RevertWithoutMessage) { - revert(); - } else if (_error == RevertType.RevertWithMessage) { - revert("ERC1363SpenderMock: reverting"); - } else if (_error == RevertType.RevertWithCustomError) { - revert CustomError(_retval); - } else if (_error == RevertType.Panic) { - uint256 a = uint256(0) / uint256(0); - a; - } - - emit Approved(owner, value, data); - return _retval; - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/token/ERC20ApprovalMock.sol b/lib/openzeppelin-contracts/contracts/mocks/token/ERC20ApprovalMock.sol deleted file mode 100644 index ff33a36..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/token/ERC20ApprovalMock.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import {ERC20} from "../../token/ERC20/ERC20.sol"; - -abstract contract ERC20ApprovalMock is ERC20 { - function _approve(address owner, address spender, uint256 amount, bool) internal virtual override { - super._approve(owner, spender, amount, true); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/token/ERC20DecimalsMock.sol b/lib/openzeppelin-contracts/contracts/mocks/token/ERC20DecimalsMock.sol deleted file mode 100644 index a26e1f5..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/token/ERC20DecimalsMock.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {ERC20} from "../../token/ERC20/ERC20.sol"; - -abstract contract ERC20DecimalsMock is ERC20 { - uint8 private immutable _decimals; - - constructor(uint8 decimals_) { - _decimals = decimals_; - } - - function decimals() public view override returns (uint8) { - return _decimals; - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/token/ERC20ExcessDecimalsMock.sol b/lib/openzeppelin-contracts/contracts/mocks/token/ERC20ExcessDecimalsMock.sol deleted file mode 100644 index 4627efd..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/token/ERC20ExcessDecimalsMock.sol +++ /dev/null @@ -1,9 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -contract ERC20ExcessDecimalsMock { - function decimals() public pure returns (uint256) { - return type(uint256).max; - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/token/ERC20FlashMintMock.sol b/lib/openzeppelin-contracts/contracts/mocks/token/ERC20FlashMintMock.sol deleted file mode 100644 index 508573c..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/token/ERC20FlashMintMock.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {ERC20FlashMint} from "../../token/ERC20/extensions/ERC20FlashMint.sol"; - -abstract contract ERC20FlashMintMock is ERC20FlashMint { - uint256 _flashFeeAmount; - address _flashFeeReceiverAddress; - - 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() internal view override returns (address) { - return _flashFeeReceiverAddress; - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/token/ERC20ForceApproveMock.sol b/lib/openzeppelin-contracts/contracts/mocks/token/ERC20ForceApproveMock.sol deleted file mode 100644 index 36c0f57..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/token/ERC20ForceApproveMock.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {ERC20} from "../../token/ERC20/ERC20.sol"; - -// contract that replicate USDT (0xdac17f958d2ee523a2206206994597c13d831ec7) approval behavior -abstract contract ERC20ForceApproveMock is ERC20 { - function approve(address spender, uint256 amount) public virtual override returns (bool) { - require(amount == 0 || allowance(msg.sender, spender) == 0, "USDT approval failure"); - return super.approve(spender, amount); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/token/ERC20Mock.sol b/lib/openzeppelin-contracts/contracts/mocks/token/ERC20Mock.sol deleted file mode 100644 index 39ab129..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/token/ERC20Mock.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import {ERC20} from "../../token/ERC20/ERC20.sol"; - -contract ERC20Mock is ERC20 { - constructor() ERC20("ERC20Mock", "E20M") {} - - function mint(address account, uint256 amount) external { - _mint(account, amount); - } - - function burn(address account, uint256 amount) external { - _burn(account, amount); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/token/ERC20MulticallMock.sol b/lib/openzeppelin-contracts/contracts/mocks/token/ERC20MulticallMock.sol deleted file mode 100644 index dce3e70..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/token/ERC20MulticallMock.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {ERC20} from "../../token/ERC20/ERC20.sol"; -import {Multicall} from "../../utils/Multicall.sol"; - -abstract contract ERC20MulticallMock is ERC20, Multicall {} diff --git a/lib/openzeppelin-contracts/contracts/mocks/token/ERC20NoReturnMock.sol b/lib/openzeppelin-contracts/contracts/mocks/token/ERC20NoReturnMock.sol deleted file mode 100644 index 2129537..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/token/ERC20NoReturnMock.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {ERC20} from "../../token/ERC20/ERC20.sol"; - -abstract contract ERC20NoReturnMock is ERC20 { - function transfer(address to, uint256 amount) public override returns (bool) { - super.transfer(to, amount); - assembly { - return(0, 0) - } - } - - function transferFrom(address from, address to, uint256 amount) public override returns (bool) { - super.transferFrom(from, to, amount); - assembly { - return(0, 0) - } - } - - function approve(address spender, uint256 amount) public override returns (bool) { - super.approve(spender, amount); - assembly { - return(0, 0) - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/token/ERC20Reentrant.sol b/lib/openzeppelin-contracts/contracts/mocks/token/ERC20Reentrant.sol deleted file mode 100644 index 813913f..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/token/ERC20Reentrant.sol +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import {ERC20} from "../../token/ERC20/ERC20.sol"; -import {Address} from "../../utils/Address.sol"; - -contract ERC20Reentrant is ERC20("TEST", "TST") { - enum Type { - No, - Before, - After - } - - Type private _reenterType; - address private _reenterTarget; - bytes private _reenterData; - - function scheduleReenter(Type when, address target, bytes calldata data) external { - _reenterType = when; - _reenterTarget = target; - _reenterData = data; - } - - function functionCall(address target, bytes memory data) public returns (bytes memory) { - return Address.functionCall(target, data); - } - - function _update(address from, address to, uint256 amount) internal override { - if (_reenterType == Type.Before) { - _reenterType = Type.No; - functionCall(_reenterTarget, _reenterData); - } - super._update(from, to, amount); - if (_reenterType == Type.After) { - _reenterType = Type.No; - functionCall(_reenterTarget, _reenterData); - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/token/ERC20ReturnFalseMock.sol b/lib/openzeppelin-contracts/contracts/mocks/token/ERC20ReturnFalseMock.sol deleted file mode 100644 index 94bff32..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/token/ERC20ReturnFalseMock.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {ERC20} from "../../token/ERC20/ERC20.sol"; - -abstract contract ERC20ReturnFalseMock is ERC20 { - function transfer(address, uint256) public pure override returns (bool) { - return false; - } - - function transferFrom(address, address, uint256) public pure override returns (bool) { - return false; - } - - function approve(address, uint256) public pure override returns (bool) { - return false; - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/token/ERC20VotesLegacyMock.sol b/lib/openzeppelin-contracts/contracts/mocks/token/ERC20VotesLegacyMock.sol deleted file mode 100644 index 3246fd4..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/token/ERC20VotesLegacyMock.sol +++ /dev/null @@ -1,253 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {ERC20Permit} from "../../token/ERC20/extensions/ERC20Permit.sol"; -import {Math} from "../../utils/math/Math.sol"; -import {IVotes} from "../../governance/utils/IVotes.sol"; -import {SafeCast} from "../../utils/math/SafeCast.sol"; -import {ECDSA} from "../../utils/cryptography/ECDSA.sol"; - -/** - * @dev Copied from the master branch at commit 86de1e8b6c3fa6b4efa4a5435869d2521be0f5f5 - */ -abstract contract ERC20VotesLegacyMock is IVotes, ERC20Permit { - struct Checkpoint { - uint32 fromBlock; - uint224 votes; - } - - bytes32 private constant _DELEGATION_TYPEHASH = - keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); - - mapping(address account => address) private _delegatee; - mapping(address delegatee => 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 returns (address) { - return _delegatee[account]; - } - - /** - * @dev Gets the current votes balance for `account` - */ - function getVotes(address account) public view virtual returns (uint256) { - uint256 pos = _checkpoints[account].length; - unchecked { - 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 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 NOT the sum of all the delegated votes! - * - * Requirements: - * - * - `blockNumber` must have been already mined - */ - function getPastTotalSupply(uint256 blockNumber) public view virtual 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 - Math.sqrt(length); - if (_unsafeAccess(ckpts, mid).fromBlock > blockNumber) { - high = mid; - } else { - low = mid + 1; - } - } - - while (low < high) { - uint256 mid = Math.average(low, high); - if (_unsafeAccess(ckpts, mid).fromBlock > blockNumber) { - high = mid; - } else { - low = mid + 1; - } - } - - unchecked { - return high == 0 ? 0 : _unsafeAccess(ckpts, high - 1).votes; - } - } - - /** - * @dev Delegate votes from the sender to `delegatee`. - */ - function delegate(address delegatee) public virtual { - _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 { - 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 Move voting power when tokens are transferred. - * - * Emits a {IVotes-DelegateVotesChanged} event. - */ - function _update(address from, address to, uint256 amount) internal virtual override { - super._update(from, to, amount); - - if (from == address(0)) { - require(totalSupply() <= _maxSupply(), "ERC20Votes: total supply risks overflowing votes"); - _writeCheckpoint(_totalSupplyCheckpoints, _add, amount); - } - - if (to == address(0)) { - _writeCheckpoint(_totalSupplyCheckpoints, _subtract, 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); - _delegatee[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; - - unchecked { - 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 = 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; - } - - /** - * @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) - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/token/ERC20VotesTimestampMock.sol b/lib/openzeppelin-contracts/contracts/mocks/token/ERC20VotesTimestampMock.sol deleted file mode 100644 index 78fdfae..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/token/ERC20VotesTimestampMock.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {ERC20Votes} from "../../token/ERC20/extensions/ERC20Votes.sol"; -import {ERC721Votes} from "../../token/ERC721/extensions/ERC721Votes.sol"; -import {SafeCast} from "../../utils/math/SafeCast.sol"; - -abstract contract ERC20VotesTimestampMock is ERC20Votes { - function clock() public view virtual override returns (uint48) { - return SafeCast.toUint48(block.timestamp); - } - - // solhint-disable-next-line func-name-mixedcase - function CLOCK_MODE() public view virtual override returns (string memory) { - return "mode=timestamp"; - } -} - -abstract contract ERC721VotesTimestampMock is ERC721Votes { - function clock() public view virtual override returns (uint48) { - return SafeCast.toUint48(block.timestamp); - } - - // solhint-disable-next-line func-name-mixedcase - function CLOCK_MODE() public view virtual override returns (string memory) { - return "mode=timestamp"; - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/token/ERC4626LimitsMock.sol b/lib/openzeppelin-contracts/contracts/mocks/token/ERC4626LimitsMock.sol deleted file mode 100644 index a845365..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/token/ERC4626LimitsMock.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {ERC4626} from "../../token/ERC20/extensions/ERC4626.sol"; - -abstract contract ERC4626LimitsMock is ERC4626 { - uint256 _maxDeposit; - uint256 _maxMint; - - constructor() { - _maxDeposit = 100 ether; - _maxMint = 100 ether; - } - - function maxDeposit(address) public view override returns (uint256) { - return _maxDeposit; - } - - function maxMint(address) public view override returns (uint256) { - return _maxMint; - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/token/ERC4626Mock.sol b/lib/openzeppelin-contracts/contracts/mocks/token/ERC4626Mock.sol deleted file mode 100644 index 22ac5e8..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/token/ERC4626Mock.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import {IERC20, ERC20} from "../../token/ERC20/ERC20.sol"; -import {ERC4626} from "../../token/ERC20/extensions/ERC4626.sol"; - -contract ERC4626Mock is ERC4626 { - constructor(address underlying) ERC20("ERC4626Mock", "E4626M") ERC4626(IERC20(underlying)) {} - - function mint(address account, uint256 amount) external { - _mint(account, amount); - } - - function burn(address account, uint256 amount) external { - _burn(account, amount); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/token/ERC4626OffsetMock.sol b/lib/openzeppelin-contracts/contracts/mocks/token/ERC4626OffsetMock.sol deleted file mode 100644 index 3dde095..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/token/ERC4626OffsetMock.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {ERC4626} from "../../token/ERC20/extensions/ERC4626.sol"; - -abstract contract ERC4626OffsetMock is ERC4626 { - uint8 private immutable _offset; - - constructor(uint8 offset_) { - _offset = offset_; - } - - function _decimalsOffset() internal view virtual override returns (uint8) { - return _offset; - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/token/ERC4646FeesMock.sol b/lib/openzeppelin-contracts/contracts/mocks/token/ERC4646FeesMock.sol deleted file mode 100644 index 368b078..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/token/ERC4646FeesMock.sol +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {ERC4626Fees} from "../docs/ERC4626Fees.sol"; - -abstract contract ERC4626FeesMock is ERC4626Fees { - uint256 private immutable _entryFeeBasisPointValue; - address private immutable _entryFeeRecipientValue; - uint256 private immutable _exitFeeBasisPointValue; - address private immutable _exitFeeRecipientValue; - - constructor( - uint256 entryFeeBasisPoints, - address entryFeeRecipient, - uint256 exitFeeBasisPoints, - address exitFeeRecipient - ) { - _entryFeeBasisPointValue = entryFeeBasisPoints; - _entryFeeRecipientValue = entryFeeRecipient; - _exitFeeBasisPointValue = exitFeeBasisPoints; - _exitFeeRecipientValue = exitFeeRecipient; - } - - function _entryFeeBasisPoints() internal view virtual override returns (uint256) { - return _entryFeeBasisPointValue; - } - - function _entryFeeRecipient() internal view virtual override returns (address) { - return _entryFeeRecipientValue; - } - - function _exitFeeBasisPoints() internal view virtual override returns (uint256) { - return _exitFeeBasisPointValue; - } - - function _exitFeeRecipient() internal view virtual override returns (address) { - return _exitFeeRecipientValue; - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/token/ERC721ConsecutiveEnumerableMock.sol b/lib/openzeppelin-contracts/contracts/mocks/token/ERC721ConsecutiveEnumerableMock.sol deleted file mode 100644 index 7732ae4..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/token/ERC721ConsecutiveEnumerableMock.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {ERC721} from "../../token/ERC721/ERC721.sol"; -import {ERC721Consecutive} from "../../token/ERC721/extensions/ERC721Consecutive.sol"; -import {ERC721Enumerable} from "../../token/ERC721/extensions/ERC721Enumerable.sol"; - -contract ERC721ConsecutiveEnumerableMock is ERC721Consecutive, ERC721Enumerable { - constructor( - string memory name, - string memory symbol, - address[] memory receivers, - uint96[] memory amounts - ) ERC721(name, symbol) { - for (uint256 i = 0; i < receivers.length; ++i) { - _mintConsecutive(receivers[i], amounts[i]); - } - } - - function supportsInterface( - bytes4 interfaceId - ) public view virtual override(ERC721, ERC721Enumerable) returns (bool) { - return super.supportsInterface(interfaceId); - } - - function _ownerOf(uint256 tokenId) internal view virtual override(ERC721, ERC721Consecutive) returns (address) { - return super._ownerOf(tokenId); - } - - function _update( - address to, - uint256 tokenId, - address auth - ) internal virtual override(ERC721Consecutive, ERC721Enumerable) returns (address) { - return super._update(to, tokenId, auth); - } - - function _increaseBalance(address account, uint128 amount) internal virtual override(ERC721, ERC721Enumerable) { - super._increaseBalance(account, amount); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/token/ERC721ConsecutiveMock.sol b/lib/openzeppelin-contracts/contracts/mocks/token/ERC721ConsecutiveMock.sol deleted file mode 100644 index 1098647..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/token/ERC721ConsecutiveMock.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {ERC721} from "../../token/ERC721/ERC721.sol"; -import {ERC721Consecutive} from "../../token/ERC721/extensions/ERC721Consecutive.sol"; -import {ERC721Pausable} from "../../token/ERC721/extensions/ERC721Pausable.sol"; -import {ERC721Votes} from "../../token/ERC721/extensions/ERC721Votes.sol"; -import {EIP712} from "../../utils/cryptography/EIP712.sol"; - -/** - * @title ERC721ConsecutiveMock - */ -contract ERC721ConsecutiveMock is ERC721Consecutive, ERC721Pausable, ERC721Votes { - uint96 private immutable _offset; - - constructor( - string memory name, - string memory symbol, - uint96 offset, - address[] memory delegates, - address[] memory receivers, - uint96[] memory amounts - ) ERC721(name, symbol) EIP712(name, "1") { - _offset = offset; - - 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 _firstConsecutiveId() internal view virtual override returns (uint96) { - return _offset; - } - - function _ownerOf(uint256 tokenId) internal view virtual override(ERC721, ERC721Consecutive) returns (address) { - return super._ownerOf(tokenId); - } - - function _update( - address to, - uint256 tokenId, - address auth - ) internal virtual override(ERC721Consecutive, ERC721Pausable, ERC721Votes) returns (address) { - return super._update(to, tokenId, auth); - } - - function _increaseBalance(address account, uint128 amount) internal virtual override(ERC721, ERC721Votes) { - super._increaseBalance(account, amount); - } -} - -contract ERC721ConsecutiveNoConstructorMintMock is ERC721Consecutive { - constructor(string memory name, string memory symbol) ERC721(name, symbol) { - _mint(msg.sender, 0); - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/token/ERC721ReceiverMock.sol b/lib/openzeppelin-contracts/contracts/mocks/token/ERC721ReceiverMock.sol deleted file mode 100644 index 14120f5..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/token/ERC721ReceiverMock.sol +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {IERC721Receiver} from "../../token/ERC721/IERC721Receiver.sol"; - -contract ERC721ReceiverMock is IERC721Receiver { - enum RevertType { - None, - RevertWithoutMessage, - RevertWithMessage, - RevertWithCustomError, - Panic - } - - bytes4 private immutable _retval; - RevertType private immutable _error; - - event Received(address operator, address from, uint256 tokenId, bytes data, uint256 gas); - error CustomError(bytes4); - - constructor(bytes4 retval, RevertType error) { - _retval = retval; - _error = error; - } - - function onERC721Received( - address operator, - address from, - uint256 tokenId, - bytes memory data - ) public returns (bytes4) { - if (_error == RevertType.RevertWithoutMessage) { - revert(); - } else if (_error == RevertType.RevertWithMessage) { - revert("ERC721ReceiverMock: reverting"); - } else if (_error == RevertType.RevertWithCustomError) { - revert CustomError(_retval); - } else if (_error == RevertType.Panic) { - uint256 a = uint256(0) / uint256(0); - a; - } - - emit Received(operator, from, tokenId, data, gasleft()); - return _retval; - } -} diff --git a/lib/openzeppelin-contracts/contracts/mocks/token/ERC721URIStorageMock.sol b/lib/openzeppelin-contracts/contracts/mocks/token/ERC721URIStorageMock.sol deleted file mode 100644 index 254435e..0000000 --- a/lib/openzeppelin-contracts/contracts/mocks/token/ERC721URIStorageMock.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {ERC721URIStorage} from "../../token/ERC721/extensions/ERC721URIStorage.sol"; - -abstract contract ERC721URIStorageMock is ERC721URIStorage { - string private _baseTokenURI; - - function _baseURI() internal view virtual override returns (string memory) { - return _baseTokenURI; - } - - function setBaseURI(string calldata newBaseTokenURI) public { - _baseTokenURI = newBaseTokenURI; - } -} diff --git a/lib/openzeppelin-contracts/contracts/package.json b/lib/openzeppelin-contracts/contracts/package.json deleted file mode 100644 index 845e8c4..0000000 --- a/lib/openzeppelin-contracts/contracts/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "@openzeppelin/contracts", - "description": "Secure Smart Contract library for Solidity", - "version": "5.0.2", - "files": [ - "**/*.sol", - "/build/contracts/*.json", - "!/mocks/**/*" - ], - "scripts": { - "prepack": "bash ../scripts/prepack.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/openzeppelin-contracts/contracts/proxy/Clones.sol b/lib/openzeppelin-contracts/contracts/proxy/Clones.sol deleted file mode 100644 index d243d67..0000000 --- a/lib/openzeppelin-contracts/contracts/proxy/Clones.sol +++ /dev/null @@ -1,124 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (proxy/Clones.sol) - -pragma solidity ^0.8.20; - -import {Errors} from "../utils/Errors.sol"; - -/** - * @dev https://eips.ethereum.org/EIPS/eip-1167[ERC-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. - */ -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) { - return clone(implementation, 0); - } - - /** - * @dev Same as {xref-Clones-clone-address-}[clone], but with a `value` parameter to send native currency - * to the new contract. - * - * NOTE: Using a non-zero value at creation will require the contract using this function (e.g. a factory) - * to always have enough balance for new deployments. Consider exposing this function under a payable method. - */ - function clone(address implementation, uint256 value) internal returns (address instance) { - if (address(this).balance < value) { - revert Errors.InsufficientBalance(address(this).balance, value); - } - /// @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(value, 0x09, 0x37) - } - if (instance == address(0)) { - revert Errors.FailedDeployment(); - } - } - - /** - * @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) { - return cloneDeterministic(implementation, salt, 0); - } - - /** - * @dev Same as {xref-Clones-cloneDeterministic-address-bytes32-}[cloneDeterministic], but with - * a `value` parameter to send native currency to the new contract. - * - * NOTE: Using a non-zero value at creation will require the contract using this function (e.g. a factory) - * to always have enough balance for new deployments. Consider exposing this function under a payable method. - */ - function cloneDeterministic( - address implementation, - bytes32 salt, - uint256 value - ) internal returns (address instance) { - if (address(this).balance < value) { - revert Errors.InsufficientBalance(address(this).balance, value); - } - /// @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(value, 0x09, 0x37, salt) - } - if (instance == address(0)) { - revert Errors.FailedDeployment(); - } - } - - /** - * @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 := and(keccak256(add(ptr, 0x43), 0x55), 0xffffffffffffffffffffffffffffffffffffffff) - } - } - - /** - * @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/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sol b/lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sol deleted file mode 100644 index 8f6b717..0000000 --- a/lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sol +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (proxy/ERC1967/ERC1967Proxy.sol) - -pragma solidity ^0.8.20; - -import {Proxy} from "../Proxy.sol"; -import {ERC1967Utils} from "./ERC1967Utils.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[ERC-1967], so that it doesn't conflict with the storage layout of the - * implementation behind the proxy. - */ -contract ERC1967Proxy is Proxy { - /** - * @dev Initializes the upgradeable proxy with an initial implementation specified by `implementation`. - * - * If `_data` is nonempty, it's used as data in a delegate call to `implementation`. This will typically be an - * encoded function call, and allows initializing the storage of the proxy like a Solidity constructor. - * - * Requirements: - * - * - If `data` is empty, `msg.value` must be zero. - */ - constructor(address implementation, bytes memory _data) payable { - ERC1967Utils.upgradeToAndCall(implementation, _data); - } - - /** - * @dev Returns the current implementation address. - * - * TIP: To get this value clients can read directly from the storage slot shown below (specified by ERC-1967) using - * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. - * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc` - */ - function _implementation() internal view virtual override returns (address) { - return ERC1967Utils.getImplementation(); - } -} diff --git a/lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Utils.sol b/lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Utils.sol deleted file mode 100644 index ce7c474..0000000 --- a/lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Utils.sol +++ /dev/null @@ -1,177 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (proxy/ERC1967/ERC1967Utils.sol) - -pragma solidity ^0.8.21; - -import {IBeacon} from "../beacon/IBeacon.sol"; -import {IERC1967} from "../../interfaces/IERC1967.sol"; -import {Address} from "../../utils/Address.sol"; -import {StorageSlot} from "../../utils/StorageSlot.sol"; - -/** - * @dev This abstract contract provides getters and event emitting update functions for - * https://eips.ethereum.org/EIPS/eip-1967[ERC-1967] slots. - */ -library ERC1967Utils { - /** - * @dev Storage slot with the address of the current implementation. - * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1. - */ - // solhint-disable-next-line private-vars-leading-underscore - bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; - - /** - * @dev The `implementation` of the proxy is invalid. - */ - error ERC1967InvalidImplementation(address implementation); - - /** - * @dev The `admin` of the proxy is invalid. - */ - error ERC1967InvalidAdmin(address admin); - - /** - * @dev The `beacon` of the proxy is invalid. - */ - error ERC1967InvalidBeacon(address beacon); - - /** - * @dev An upgrade function sees `msg.value > 0` that may be lost. - */ - error ERC1967NonPayable(); - - /** - * @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 ERC-1967 implementation slot. - */ - function _setImplementation(address newImplementation) private { - if (newImplementation.code.length == 0) { - revert ERC1967InvalidImplementation(newImplementation); - } - StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value = newImplementation; - } - - /** - * @dev Performs implementation upgrade with additional setup call if data is nonempty. - * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected - * to avoid stuck value in the contract. - * - * Emits an {IERC1967-Upgraded} event. - */ - function upgradeToAndCall(address newImplementation, bytes memory data) internal { - _setImplementation(newImplementation); - emit IERC1967.Upgraded(newImplementation); - - if (data.length > 0) { - Address.functionDelegateCall(newImplementation, data); - } else { - _checkNonPayable(); - } - } - - /** - * @dev Storage slot with the admin of the contract. - * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1. - */ - // solhint-disable-next-line private-vars-leading-underscore - bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; - - /** - * @dev Returns the current admin. - * - * TIP: To get this value clients can read directly from the storage slot shown below (specified by ERC-1967) using - * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. - * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103` - */ - function getAdmin() internal view returns (address) { - return StorageSlot.getAddressSlot(ADMIN_SLOT).value; - } - - /** - * @dev Stores a new address in the ERC-1967 admin slot. - */ - function _setAdmin(address newAdmin) private { - if (newAdmin == address(0)) { - revert ERC1967InvalidAdmin(address(0)); - } - StorageSlot.getAddressSlot(ADMIN_SLOT).value = newAdmin; - } - - /** - * @dev Changes the admin of the proxy. - * - * Emits an {IERC1967-AdminChanged} event. - */ - function changeAdmin(address newAdmin) internal { - emit IERC1967.AdminChanged(getAdmin(), newAdmin); - _setAdmin(newAdmin); - } - - /** - * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. - * This is the keccak-256 hash of "eip1967.proxy.beacon" subtracted by 1. - */ - // solhint-disable-next-line private-vars-leading-underscore - bytes32 internal constant BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; - - /** - * @dev Returns the current beacon. - */ - function getBeacon() internal view returns (address) { - return StorageSlot.getAddressSlot(BEACON_SLOT).value; - } - - /** - * @dev Stores a new beacon in the ERC-1967 beacon slot. - */ - function _setBeacon(address newBeacon) private { - if (newBeacon.code.length == 0) { - revert ERC1967InvalidBeacon(newBeacon); - } - - StorageSlot.getAddressSlot(BEACON_SLOT).value = newBeacon; - - address beaconImplementation = IBeacon(newBeacon).implementation(); - if (beaconImplementation.code.length == 0) { - revert ERC1967InvalidImplementation(beaconImplementation); - } - } - - /** - * @dev Change the beacon and trigger a setup call if data is nonempty. - * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected - * to avoid stuck value in the contract. - * - * Emits an {IERC1967-BeaconUpgraded} event. - * - * CAUTION: Invoking this function has no effect on an instance of {BeaconProxy} since v5, since - * it uses an immutable beacon without looking at the value of the ERC-1967 beacon slot for - * efficiency. - */ - function upgradeBeaconToAndCall(address newBeacon, bytes memory data) internal { - _setBeacon(newBeacon); - emit IERC1967.BeaconUpgraded(newBeacon); - - if (data.length > 0) { - Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data); - } else { - _checkNonPayable(); - } - } - - /** - * @dev Reverts if `msg.value` is not zero. It can be used to avoid `msg.value` stuck in the contract - * if an upgrade doesn't perform an initialization call. - */ - function _checkNonPayable() private { - if (msg.value > 0) { - revert ERC1967NonPayable(); - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/proxy/Proxy.sol b/lib/openzeppelin-contracts/contracts/proxy/Proxy.sol deleted file mode 100644 index 0e73651..0000000 --- a/lib/openzeppelin-contracts/contracts/proxy/Proxy.sol +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (proxy/Proxy.sol) - -pragma solidity ^0.8.20; - -/** - * @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 { - _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(); - } -} diff --git a/lib/openzeppelin-contracts/contracts/proxy/README.adoc b/lib/openzeppelin-contracts/contracts/proxy/README.adoc deleted file mode 100644 index 1c4d010..0000000 --- a/lib/openzeppelin-contracts/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[ERC-1967] storage slots. - -- {ERC1967Utils}: Internal functions to get and set the storage slots defined in ERC-1967. -- {ERC1967Proxy}: A proxy using ERC-1967 storage slots. Not upgradeable by default. - -There are two alternative ways to add upgradeability to an ERC-1967 proxy. Their differences are explained below in <>. - -- {TransparentUpgradeableProxy}: A proxy with a built-in immutable 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 Hardhat and Foundry. - -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 ERC-1967 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[ERC-1822], 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[ERC-1822] 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 ERC-1822 interface. - -== Core - -{{Proxy}} - -== ERC-1967 - -{{IERC1967}} - -{{ERC1967Proxy}} - -{{ERC1967Utils}} - -== Transparent Proxy - -{{TransparentUpgradeableProxy}} - -{{ProxyAdmin}} - -== Beacon - -{{BeaconProxy}} - -{{IBeacon}} - -{{UpgradeableBeacon}} - -== Minimal Clones - -{{Clones}} - -== Utils - -{{Initializable}} - -{{UUPSUpgradeable}} diff --git a/lib/openzeppelin-contracts/contracts/proxy/beacon/BeaconProxy.sol b/lib/openzeppelin-contracts/contracts/proxy/beacon/BeaconProxy.sol deleted file mode 100644 index 9b3f627..0000000 --- a/lib/openzeppelin-contracts/contracts/proxy/beacon/BeaconProxy.sol +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/BeaconProxy.sol) - -pragma solidity ^0.8.20; - -import {IBeacon} from "./IBeacon.sol"; -import {Proxy} from "../Proxy.sol"; -import {ERC1967Utils} from "../ERC1967/ERC1967Utils.sol"; - -/** - * @dev This contract implements a proxy that gets the implementation address for each call from an {UpgradeableBeacon}. - * - * The beacon address can only be set once during construction, and cannot be changed afterwards. It is stored in an - * immutable variable to avoid unnecessary storage reads, and also in the beacon storage slot specified by - * https://eips.ethereum.org/EIPS/eip-1967[ERC-1967] so that it can be accessed externally. - * - * CAUTION: Since the beacon address can never be changed, you must ensure that you either control the beacon, or trust - * the beacon to not upgrade the implementation maliciously. - * - * IMPORTANT: Do not use the implementation logic to modify the beacon storage slot. Doing so would leave the proxy in - * an inconsistent state where the beacon storage slot does not match the beacon address. - */ -contract BeaconProxy is Proxy { - // An immutable address for the beacon to avoid unnecessary SLOADs before each delegate call. - address private immutable _beacon; - - /** - * @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}. - * - If `data` is empty, `msg.value` must be zero. - */ - constructor(address beacon, bytes memory data) payable { - ERC1967Utils.upgradeBeaconToAndCall(beacon, data); - _beacon = beacon; - } - - /** - * @dev Returns the current implementation address of the associated beacon. - */ - function _implementation() internal view virtual override returns (address) { - return IBeacon(_getBeacon()).implementation(); - } - - /** - * @dev Returns the beacon. - */ - function _getBeacon() internal view virtual returns (address) { - return _beacon; - } -} diff --git a/lib/openzeppelin-contracts/contracts/proxy/beacon/IBeacon.sol b/lib/openzeppelin-contracts/contracts/proxy/beacon/IBeacon.sol deleted file mode 100644 index 36a3c76..0000000 --- a/lib/openzeppelin-contracts/contracts/proxy/beacon/IBeacon.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/IBeacon.sol) - -pragma solidity ^0.8.20; - -/** - * @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. - * - * {UpgradeableBeacon} will check that this address is a contract. - */ - function implementation() external view returns (address); -} diff --git a/lib/openzeppelin-contracts/contracts/proxy/beacon/UpgradeableBeacon.sol b/lib/openzeppelin-contracts/contracts/proxy/beacon/UpgradeableBeacon.sol deleted file mode 100644 index 8db9bd2..0000000 --- a/lib/openzeppelin-contracts/contracts/proxy/beacon/UpgradeableBeacon.sol +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/UpgradeableBeacon.sol) - -pragma solidity ^0.8.20; - -import {IBeacon} from "./IBeacon.sol"; -import {Ownable} from "../../access/Ownable.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 The `implementation` of the beacon is invalid. - */ - error BeaconInvalidImplementation(address 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 initial owner who can upgrade the beacon. - */ - constructor(address implementation_, address initialOwner) Ownable(initialOwner) { - _setImplementation(implementation_); - } - - /** - * @dev Returns the current implementation address. - */ - function implementation() public view virtual 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); - } - - /** - * @dev Sets the implementation contract address for this beacon - * - * Requirements: - * - * - `newImplementation` must be a contract. - */ - function _setImplementation(address newImplementation) private { - if (newImplementation.code.length == 0) { - revert BeaconInvalidImplementation(newImplementation); - } - _implementation = newImplementation; - emit Upgraded(newImplementation); - } -} diff --git a/lib/openzeppelin-contracts/contracts/proxy/transparent/ProxyAdmin.sol b/lib/openzeppelin-contracts/contracts/proxy/transparent/ProxyAdmin.sol deleted file mode 100644 index 7fbdca6..0000000 --- a/lib/openzeppelin-contracts/contracts/proxy/transparent/ProxyAdmin.sol +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (proxy/transparent/ProxyAdmin.sol) - -pragma solidity ^0.8.20; - -import {ITransparentUpgradeableProxy} from "./TransparentUpgradeableProxy.sol"; -import {Ownable} from "../../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 The version of the upgrade interface of the contract. If this getter is missing, both `upgrade(address,address)` - * and `upgradeAndCall(address,address,bytes)` are present, and `upgrade` must be used if no function should be called, - * while `upgradeAndCall` will invoke the `receive` function if the third argument is the empty byte string. - * If the getter returns `"5.0.0"`, only `upgradeAndCall(address,address,bytes)` is present, and the third argument must - * be the empty byte string if no function should be called, making it impossible to invoke the `receive` function - * during an upgrade. - */ - string public constant UPGRADE_INTERFACE_VERSION = "5.0.0"; - - /** - * @dev Sets the initial owner who can perform upgrades. - */ - constructor(address initialOwner) Ownable(initialOwner) {} - - /** - * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. - * See {TransparentUpgradeableProxy-_dispatchUpgradeToAndCall}. - * - * Requirements: - * - * - This contract must be the admin of `proxy`. - * - If `data` is empty, `msg.value` must be zero. - */ - function upgradeAndCall( - ITransparentUpgradeableProxy proxy, - address implementation, - bytes memory data - ) public payable virtual onlyOwner { - proxy.upgradeToAndCall{value: msg.value}(implementation, data); - } -} diff --git a/lib/openzeppelin-contracts/contracts/proxy/transparent/TransparentUpgradeableProxy.sol b/lib/openzeppelin-contracts/contracts/proxy/transparent/TransparentUpgradeableProxy.sol deleted file mode 100644 index 2e3fbc5..0000000 --- a/lib/openzeppelin-contracts/contracts/proxy/transparent/TransparentUpgradeableProxy.sol +++ /dev/null @@ -1,117 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (proxy/transparent/TransparentUpgradeableProxy.sol) - -pragma solidity ^0.8.20; - -import {ERC1967Utils} from "../ERC1967/ERC1967Utils.sol"; -import {ERC1967Proxy} from "../ERC1967/ERC1967Proxy.sol"; -import {IERC1967} from "../../interfaces/IERC1967.sol"; -import {ProxyAdmin} from "./ProxyAdmin.sol"; - -/** - * @dev Interface for {TransparentUpgradeableProxy}. In order to implement transparency, {TransparentUpgradeableProxy} - * does not implement this interface directly, and its upgradeability mechanism is implemented by an internal dispatch - * mechanism. The compiler is unaware that these functions are implemented by {TransparentUpgradeableProxy} and will not - * include them in the ABI so this interface must be used to interact with it. - */ -interface ITransparentUpgradeableProxy is IERC1967 { - function upgradeToAndCall(address, bytes calldata) external payable; -} - -/** - * @dev This contract implements a proxy that is upgradeable through an associated {ProxyAdmin} instance. - * - * 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 the {ITransparentUpgradeableProxy-upgradeToAndCall} function exposed by the proxy itself. - * 2. If the admin calls the proxy, it can call the `upgradeToAndCall` function but any other call won't be forwarded to - * the implementation. If the admin tries to call a function on the implementation it will fail with an error indicating - * the proxy admin cannot fallback to the target implementation. - * - * These properties mean that the admin account can only be used for upgrading the proxy, 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. For this reason, the proxy deploys an instance of {ProxyAdmin} and - * allows upgrades only if they come through it. You should think of the `ProxyAdmin` instance as the administrative - * interface of the proxy, including the ability to change who can trigger upgrades by transferring ownership. - * - * NOTE: The real interface of this proxy is that defined in `ITransparentUpgradeableProxy`. This contract does not - * inherit from that interface, and instead `upgradeToAndCall` is implicitly implemented using a custom dispatch - * mechanism in `_fallback`. Consequently, the compiler will not produce an ABI for this contract. This is necessary to - * fully implement transparency without decoding reverts caused by selector clashes between the proxy and the - * implementation. - * - * NOTE: This proxy does not inherit from {Context} deliberately. The {ProxyAdmin} of this contract won't send a - * meta-transaction in any way, and any other meta-transaction setup should be made in the implementation contract. - * - * IMPORTANT: This contract avoids unnecessary storage reads by setting the admin only during construction as an - * immutable variable, preventing any changes thereafter. However, the admin slot defined in ERC-1967 can still be - * overwritten by the implementation logic pointed to by this proxy. In such cases, the contract may end up in an - * undesirable state where the admin slot is different from the actual admin. Relying on the value of the admin slot - * is generally fine if the implementation is trusted. - * - * WARNING: It is not recommended to extend this contract to add additional external functions. If you do so, the - * compiler will not check that there are no selector conflicts, due to the note above. A selector clash between any new - * function and the functions declared in {ITransparentUpgradeableProxy} will be resolved in favor of the new one. This - * could render the `upgradeToAndCall` function inaccessible, preventing upgradeability and compromising transparency. - */ -contract TransparentUpgradeableProxy is ERC1967Proxy { - // An immutable address for the admin to avoid unnecessary SLOADs before each call - // at the expense of removing the ability to change the admin once it's set. - // This is acceptable if the admin is always a ProxyAdmin instance or similar contract - // with its own ability to transfer the permissions to another account. - address private immutable _admin; - - /** - * @dev The proxy caller is the current admin, and can't fallback to the proxy target. - */ - error ProxyDeniedAdminAccess(); - - /** - * @dev Initializes an upgradeable proxy managed by an instance of a {ProxyAdmin} with an `initialOwner`, - * backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in - * {ERC1967Proxy-constructor}. - */ - constructor(address _logic, address initialOwner, bytes memory _data) payable ERC1967Proxy(_logic, _data) { - _admin = address(new ProxyAdmin(initialOwner)); - // Set the storage value and emit an event for ERC-1967 compatibility - ERC1967Utils.changeAdmin(_proxyAdmin()); - } - - /** - * @dev Returns the admin of this proxy. - */ - function _proxyAdmin() internal view virtual returns (address) { - return _admin; - } - - /** - * @dev If caller is the admin process the call internally, otherwise transparently fallback to the proxy behavior. - */ - function _fallback() internal virtual override { - if (msg.sender == _proxyAdmin()) { - if (msg.sig != ITransparentUpgradeableProxy.upgradeToAndCall.selector) { - revert ProxyDeniedAdminAccess(); - } else { - _dispatchUpgradeToAndCall(); - } - } else { - super._fallback(); - } - } - - /** - * @dev Upgrade the implementation of the proxy. See {ERC1967Utils-upgradeToAndCall}. - * - * Requirements: - * - * - If `data` is empty, `msg.value` must be zero. - */ - function _dispatchUpgradeToAndCall() private { - (address newImplementation, bytes memory data) = abi.decode(msg.data[4:], (address, bytes)); - ERC1967Utils.upgradeToAndCall(newImplementation, data); - } -} diff --git a/lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol b/lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol deleted file mode 100644 index b3d82b5..0000000 --- a/lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol +++ /dev/null @@ -1,228 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol) - -pragma solidity ^0.8.20; - -/** - * @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] - * ```solidity - * 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 Storage of the initializable contract. - * - * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions - * when using with upgradeable contracts. - * - * @custom:storage-location erc7201:openzeppelin.storage.Initializable - */ - struct InitializableStorage { - /** - * @dev Indicates that the contract has been initialized. - */ - uint64 _initialized; - /** - * @dev Indicates that the contract is in the process of being initialized. - */ - bool _initializing; - } - - // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff)) - bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00; - - /** - * @dev The contract is already initialized. - */ - error InvalidInitialization(); - - /** - * @dev The contract is not initializing. - */ - error NotInitializing(); - - /** - * @dev Triggered when the contract has been initialized or reinitialized. - */ - event Initialized(uint64 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 in the context of a constructor an `initializer` may be invoked any - * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in - * production. - * - * Emits an {Initialized} event. - */ - modifier initializer() { - // solhint-disable-next-line var-name-mixedcase - InitializableStorage storage $ = _getInitializableStorage(); - - // Cache values to avoid duplicated sloads - bool isTopLevelCall = !$._initializing; - uint64 initialized = $._initialized; - - // Allowed calls: - // - initialSetup: the contract is not in the initializing state and no previous version was - // initialized - // - construction: the contract is initialized at version 1 (no reininitialization) and the - // current contract is just being deployed - bool initialSetup = initialized == 0 && isTopLevelCall; - bool construction = initialized == 1 && address(this).code.length == 0; - - if (!initialSetup && !construction) { - revert InvalidInitialization(); - } - $._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 2**64 - 1 will prevent any future reinitialization. - * - * Emits an {Initialized} event. - */ - modifier reinitializer(uint64 version) { - // solhint-disable-next-line var-name-mixedcase - InitializableStorage storage $ = _getInitializableStorage(); - - if ($._initializing || $._initialized >= version) { - revert InvalidInitialization(); - } - $._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() { - _checkInitializing(); - _; - } - - /** - * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}. - */ - function _checkInitializing() internal view virtual { - if (!_isInitializing()) { - revert NotInitializing(); - } - } - - /** - * @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 { - // solhint-disable-next-line var-name-mixedcase - InitializableStorage storage $ = _getInitializableStorage(); - - if ($._initializing) { - revert InvalidInitialization(); - } - if ($._initialized != type(uint64).max) { - $._initialized = type(uint64).max; - emit Initialized(type(uint64).max); - } - } - - /** - * @dev Returns the highest version that has been initialized. See {reinitializer}. - */ - function _getInitializedVersion() internal view returns (uint64) { - return _getInitializableStorage()._initialized; - } - - /** - * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. - */ - function _isInitializing() internal view returns (bool) { - return _getInitializableStorage()._initializing; - } - - /** - * @dev Returns a pointer to the storage namespace. - */ - // solhint-disable-next-line var-name-mixedcase - function _getInitializableStorage() private pure returns (InitializableStorage storage $) { - assembly { - $.slot := INITIALIZABLE_STORAGE - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/proxy/utils/UUPSUpgradeable.sol b/lib/openzeppelin-contracts/contracts/proxy/utils/UUPSUpgradeable.sol deleted file mode 100644 index 20eb1f7..0000000 --- a/lib/openzeppelin-contracts/contracts/proxy/utils/UUPSUpgradeable.sol +++ /dev/null @@ -1,147 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/UUPSUpgradeable.sol) - -pragma solidity ^0.8.20; - -import {IERC1822Proxiable} from "../../interfaces/draft-IERC1822.sol"; -import {ERC1967Utils} from "../ERC1967/ERC1967Utils.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. - */ -abstract contract UUPSUpgradeable is IERC1822Proxiable { - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable - address private immutable __self = address(this); - - /** - * @dev The version of the upgrade interface of the contract. If this getter is missing, both `upgradeTo(address)` - * and `upgradeToAndCall(address,bytes)` are present, and `upgradeTo` must be used if no function should be called, - * while `upgradeToAndCall` will invoke the `receive` function if the second argument is the empty byte string. - * If the getter returns `"5.0.0"`, only `upgradeToAndCall(address,bytes)` is present, and the second argument must - * be the empty byte string if no function should be called, making it impossible to invoke the `receive` function - * during an upgrade. - */ - string public constant UPGRADE_INTERFACE_VERSION = "5.0.0"; - - /** - * @dev The call is from an unauthorized context. - */ - error UUPSUnauthorizedCallContext(); - - /** - * @dev The storage `slot` is unsupported as a UUID. - */ - error UUPSUnsupportedProxiableUUID(bytes32 slot); - - /** - * @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 ERC-1967) 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 ERC-1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to - * fail. - */ - modifier onlyProxy() { - _checkProxy(); - _; - } - - /** - * @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() { - _checkNotDelegated(); - _; - } - - /** - * @dev Implementation of the ERC-1822 {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 notDelegated returns (bytes32) { - return ERC1967Utils.IMPLEMENTATION_SLOT; - } - - /** - * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call - * encoded in `data`. - * - * Calls {_authorizeUpgrade}. - * - * Emits an {Upgraded} event. - * - * @custom:oz-upgrades-unsafe-allow-reachable delegatecall - */ - function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy { - _authorizeUpgrade(newImplementation); - _upgradeToAndCallUUPS(newImplementation, data); - } - - /** - * @dev Reverts if the execution is not performed via delegatecall or the execution - * context is not of a proxy with an ERC-1967 compliant implementation pointing to self. - * See {_onlyProxy}. - */ - function _checkProxy() internal view virtual { - if ( - address(this) == __self || // Must be called through delegatecall - ERC1967Utils.getImplementation() != __self // Must be called through an active proxy - ) { - revert UUPSUnauthorizedCallContext(); - } - } - - /** - * @dev Reverts if the execution is performed via delegatecall. - * See {notDelegated}. - */ - function _checkNotDelegated() internal view virtual { - if (address(this) != __self) { - // Must not be called through delegatecall - revert UUPSUnauthorizedCallContext(); - } - } - - /** - * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by - * {upgradeToAndCall}. - * - * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. - * - * ```solidity - * function _authorizeUpgrade(address) internal onlyOwner {} - * ``` - */ - function _authorizeUpgrade(address newImplementation) internal virtual; - - /** - * @dev Performs an implementation upgrade with a security check for UUPS proxies, and additional setup call. - * - * As a security check, {proxiableUUID} is invoked in the new implementation, and the return value - * is expected to be the implementation slot in ERC-1967. - * - * Emits an {IERC1967-Upgraded} event. - */ - function _upgradeToAndCallUUPS(address newImplementation, bytes memory data) private { - try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) { - if (slot != ERC1967Utils.IMPLEMENTATION_SLOT) { - revert UUPSUnsupportedProxiableUUID(slot); - } - ERC1967Utils.upgradeToAndCall(newImplementation, data); - } catch { - // The implementation is not UUPS - revert ERC1967Utils.ERC1967InvalidImplementation(newImplementation); - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC1155/ERC1155.sol b/lib/openzeppelin-contracts/contracts/token/ERC1155/ERC1155.sol deleted file mode 100644 index 5e05e47..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC1155/ERC1155.sol +++ /dev/null @@ -1,402 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/ERC1155.sol) - -pragma solidity ^0.8.20; - -import {IERC1155} from "./IERC1155.sol"; -import {IERC1155MetadataURI} from "./extensions/IERC1155MetadataURI.sol"; -import {ERC1155Utils} from "./utils/ERC1155Utils.sol"; -import {Context} from "../../utils/Context.sol"; -import {IERC165, ERC165} from "../../utils/introspection/ERC165.sol"; -import {Arrays} from "../../utils/Arrays.sol"; -import {IERC1155Errors} from "../../interfaces/draft-IERC6093.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 - */ -abstract contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI, IERC1155Errors { - using Arrays for uint256[]; - using Arrays for address[]; - - mapping(uint256 id => mapping(address account => uint256)) private _balances; - - mapping(address account => mapping(address operator => 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 ERC]. - * - * Clients calling this function must replace the `\{id\}` substring with the - * actual token type ID. - */ - function uri(uint256 /* id */) public view virtual returns (string memory) { - return _uri; - } - - /** - * @dev See {IERC1155-balanceOf}. - */ - function balanceOf(address account, uint256 id) public view virtual returns (uint256) { - 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 returns (uint256[] memory) { - if (accounts.length != ids.length) { - revert ERC1155InvalidArrayLength(ids.length, accounts.length); - } - - uint256[] memory batchBalances = new uint256[](accounts.length); - - for (uint256 i = 0; i < accounts.length; ++i) { - batchBalances[i] = balanceOf(accounts.unsafeMemoryAccess(i), ids.unsafeMemoryAccess(i)); - } - - return batchBalances; - } - - /** - * @dev See {IERC1155-setApprovalForAll}. - */ - function setApprovalForAll(address operator, bool approved) public virtual { - _setApprovalForAll(_msgSender(), operator, approved); - } - - /** - * @dev See {IERC1155-isApprovedForAll}. - */ - function isApprovedForAll(address account, address operator) public view virtual returns (bool) { - return _operatorApprovals[account][operator]; - } - - /** - * @dev See {IERC1155-safeTransferFrom}. - */ - function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes memory data) public virtual { - address sender = _msgSender(); - if (from != sender && !isApprovedForAll(from, sender)) { - revert ERC1155MissingApprovalForAll(sender, from); - } - _safeTransferFrom(from, to, id, value, data); - } - - /** - * @dev See {IERC1155-safeBatchTransferFrom}. - */ - function safeBatchTransferFrom( - address from, - address to, - uint256[] memory ids, - uint256[] memory values, - bytes memory data - ) public virtual { - address sender = _msgSender(); - if (from != sender && !isApprovedForAll(from, sender)) { - revert ERC1155MissingApprovalForAll(sender, from); - } - _safeBatchTransferFrom(from, to, ids, values, data); - } - - /** - * @dev Transfers a `value` amount of tokens of type `id` from `from` to `to`. Will mint (or burn) if `from` - * (or `to`) is the zero address. - * - * Emits a {TransferSingle} event if the arrays contain one element, and {TransferBatch} otherwise. - * - * Requirements: - * - * - If `to` refers to a smart contract, it must implement either {IERC1155Receiver-onERC1155Received} - * or {IERC1155Receiver-onERC1155BatchReceived} and return the acceptance magic value. - * - `ids` and `values` must have the same length. - * - * NOTE: The ERC-1155 acceptance check is not performed in this function. See {_updateWithAcceptanceCheck} instead. - */ - function _update(address from, address to, uint256[] memory ids, uint256[] memory values) internal virtual { - if (ids.length != values.length) { - revert ERC1155InvalidArrayLength(ids.length, values.length); - } - - address operator = _msgSender(); - - for (uint256 i = 0; i < ids.length; ++i) { - uint256 id = ids.unsafeMemoryAccess(i); - uint256 value = values.unsafeMemoryAccess(i); - - if (from != address(0)) { - uint256 fromBalance = _balances[id][from]; - if (fromBalance < value) { - revert ERC1155InsufficientBalance(from, fromBalance, value, id); - } - unchecked { - // Overflow not possible: value <= fromBalance - _balances[id][from] = fromBalance - value; - } - } - - if (to != address(0)) { - _balances[id][to] += value; - } - } - - if (ids.length == 1) { - uint256 id = ids.unsafeMemoryAccess(0); - uint256 value = values.unsafeMemoryAccess(0); - emit TransferSingle(operator, from, to, id, value); - } else { - emit TransferBatch(operator, from, to, ids, values); - } - } - - /** - * @dev Version of {_update} that performs the token acceptance check by calling - * {IERC1155Receiver-onERC1155Received} or {IERC1155Receiver-onERC1155BatchReceived} on the receiver address if it - * contains code (eg. is a smart contract at the moment of execution). - * - * IMPORTANT: Overriding this function is discouraged because it poses a reentrancy risk from the receiver. So any - * update to the contract state after this function would break the check-effect-interaction pattern. Consider - * overriding {_update} instead. - */ - function _updateWithAcceptanceCheck( - address from, - address to, - uint256[] memory ids, - uint256[] memory values, - bytes memory data - ) internal virtual { - _update(from, to, ids, values); - if (to != address(0)) { - address operator = _msgSender(); - if (ids.length == 1) { - uint256 id = ids.unsafeMemoryAccess(0); - uint256 value = values.unsafeMemoryAccess(0); - ERC1155Utils.checkOnERC1155Received(operator, from, to, id, value, data); - } else { - ERC1155Utils.checkOnERC1155BatchReceived(operator, from, to, ids, values, data); - } - } - } - - /** - * @dev Transfers a `value` 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 `value` 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 value, bytes memory data) internal { - if (to == address(0)) { - revert ERC1155InvalidReceiver(address(0)); - } - if (from == address(0)) { - revert ERC1155InvalidSender(address(0)); - } - (uint256[] memory ids, uint256[] memory values) = _asSingletonArrays(id, value); - _updateWithAcceptanceCheck(from, to, ids, values, 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. - * - `ids` and `values` must have the same length. - */ - function _safeBatchTransferFrom( - address from, - address to, - uint256[] memory ids, - uint256[] memory values, - bytes memory data - ) internal { - if (to == address(0)) { - revert ERC1155InvalidReceiver(address(0)); - } - if (from == address(0)) { - revert ERC1155InvalidSender(address(0)); - } - _updateWithAcceptanceCheck(from, to, ids, values, 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 ERC]. - * - * By this mechanism, any occurrence of the `\{id\}` substring in either the - * URI or any of the values 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 a `value` amount of tokens of 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 value, bytes memory data) internal { - if (to == address(0)) { - revert ERC1155InvalidReceiver(address(0)); - } - (uint256[] memory ids, uint256[] memory values) = _asSingletonArrays(id, value); - _updateWithAcceptanceCheck(address(0), to, ids, values, data); - } - - /** - * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}. - * - * Emits a {TransferBatch} event. - * - * Requirements: - * - * - `ids` and `values` must have the same length. - * - `to` cannot be the zero address. - * - 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 values, bytes memory data) internal { - if (to == address(0)) { - revert ERC1155InvalidReceiver(address(0)); - } - _updateWithAcceptanceCheck(address(0), to, ids, values, data); - } - - /** - * @dev Destroys a `value` amount of tokens of type `id` from `from` - * - * Emits a {TransferSingle} event. - * - * Requirements: - * - * - `from` cannot be the zero address. - * - `from` must have at least `value` amount of tokens of type `id`. - */ - function _burn(address from, uint256 id, uint256 value) internal { - if (from == address(0)) { - revert ERC1155InvalidSender(address(0)); - } - (uint256[] memory ids, uint256[] memory values) = _asSingletonArrays(id, value); - _updateWithAcceptanceCheck(from, address(0), ids, values, ""); - } - - /** - * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}. - * - * Emits a {TransferBatch} event. - * - * Requirements: - * - * - `from` cannot be the zero address. - * - `from` must have at least `value` amount of tokens of type `id`. - * - `ids` and `values` must have the same length. - */ - function _burnBatch(address from, uint256[] memory ids, uint256[] memory values) internal { - if (from == address(0)) { - revert ERC1155InvalidSender(address(0)); - } - _updateWithAcceptanceCheck(from, address(0), ids, values, ""); - } - - /** - * @dev Approve `operator` to operate on all of `owner` tokens - * - * Emits an {ApprovalForAll} event. - * - * Requirements: - * - * - `operator` cannot be the zero address. - */ - function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { - if (operator == address(0)) { - revert ERC1155InvalidOperator(address(0)); - } - _operatorApprovals[owner][operator] = approved; - emit ApprovalForAll(owner, operator, approved); - } - - /** - * @dev Creates an array in memory with only one value for each of the elements provided. - */ - function _asSingletonArrays( - uint256 element1, - uint256 element2 - ) private pure returns (uint256[] memory array1, uint256[] memory array2) { - /// @solidity memory-safe-assembly - assembly { - // Load the free memory pointer - array1 := mload(0x40) - // Set array length to 1 - mstore(array1, 1) - // Store the single element at the next word after the length (where content starts) - mstore(add(array1, 0x20), element1) - - // Repeat for next array locating it right after the first array - array2 := add(array1, 0x40) - mstore(array2, 1) - mstore(add(array2, 0x20), element2) - - // Update the free memory pointer by pointing after the second array - mstore(0x40, add(array2, 0x40)) - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol b/lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol deleted file mode 100644 index 5a1805f..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol +++ /dev/null @@ -1,123 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.1) (token/ERC1155/IERC1155.sol) - -pragma solidity ^0.8.20; - -import {IERC165} from "../../utils/introspection/IERC165.sol"; - -/** - * @dev Required interface of an ERC-1155 compliant contract, as defined in the - * https://eips.ethereum.org/EIPS/eip-1155[ERC]. - */ -interface IERC1155 is IERC165 { - /** - * @dev Emitted when `value` amount of tokens of 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 value of tokens of token type `id` owned by `account`. - */ - 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 zero address. - */ - 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 a `value` amount of tokens of type `id` from `from` to `to`. - * - * WARNING: This function can potentially allow a reentrancy attack when transferring tokens - * to an untrusted contract, when invoking {onERC1155Received} on the receiver. - * Ensure to follow the checks-effects-interactions pattern and consider employing - * reentrancy guards when interacting with untrusted contracts. - * - * 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 `value` 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 value, bytes calldata data) external; - - /** - * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. - * - * WARNING: This function can potentially allow a reentrancy attack when transferring tokens - * to an untrusted contract, when invoking {onERC1155BatchReceived} on the receiver. - * Ensure to follow the checks-effects-interactions pattern and consider employing - * reentrancy guards when interacting with untrusted contracts. - * - * Emits either a {TransferSingle} or a {TransferBatch} event, depending on the length of the array arguments. - * - * Requirements: - * - * - `ids` and `values` 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 values, - bytes calldata data - ) external; -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol b/lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol deleted file mode 100644 index 36ad4c7..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/IERC1155Receiver.sol) - -pragma solidity ^0.8.20; - -import {IERC165} from "../../utils/introspection/IERC165.sol"; - -/** - * @dev Interface that must be implemented by smart contracts in order to receive - * ERC-1155 token transfers. - */ -interface IERC1155Receiver is IERC165 { - /** - * @dev Handles the receipt of a single ERC-1155 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 ERC-1155 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/openzeppelin-contracts/contracts/token/ERC1155/README.adoc b/lib/openzeppelin-contracts/contracts/token/ERC1155/README.adoc deleted file mode 100644 index d911d78..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC1155/README.adoc +++ /dev/null @@ -1,41 +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[ERC-1155 Multi Token Standard]. - -The ERC 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 ERC-1155 (such as <>) and expose them as external functions in the way they prefer. - -== Core - -{{IERC1155}} - -{{IERC1155MetadataURI}} - -{{ERC1155}} - -{{IERC1155Receiver}} - -== Extensions - -{{ERC1155Pausable}} - -{{ERC1155Burnable}} - -{{ERC1155Supply}} - -{{ERC1155URIStorage}} - -== Utilities - -{{ERC1155Holder}} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Burnable.sol b/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Burnable.sol deleted file mode 100644 index fd6ad61..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Burnable.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/extensions/ERC1155Burnable.sol) - -pragma solidity ^0.8.20; - -import {ERC1155} from "../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. - */ -abstract contract ERC1155Burnable is ERC1155 { - function burn(address account, uint256 id, uint256 value) public virtual { - if (account != _msgSender() && !isApprovedForAll(account, _msgSender())) { - revert ERC1155MissingApprovalForAll(_msgSender(), account); - } - - _burn(account, id, value); - } - - function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual { - if (account != _msgSender() && !isApprovedForAll(account, _msgSender())) { - revert ERC1155MissingApprovalForAll(_msgSender(), account); - } - - _burnBatch(account, ids, values); - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Pausable.sol b/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Pausable.sol deleted file mode 100644 index e99cf2a..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Pausable.sol +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/extensions/ERC1155Pausable.sol) - -pragma solidity ^0.8.20; - -import {ERC1155} from "../ERC1155.sol"; -import {Pausable} from "../../../utils/Pausable.sol"; - -/** - * @dev ERC-1155 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 pause mechanism of the contract unreachable, and thus unusable. - */ -abstract contract ERC1155Pausable is ERC1155, Pausable { - /** - * @dev See {ERC1155-_update}. - * - * Requirements: - * - * - the contract must not be paused. - */ - function _update( - address from, - address to, - uint256[] memory ids, - uint256[] memory values - ) internal virtual override whenNotPaused { - super._update(from, to, ids, values); - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Supply.sol b/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Supply.sol deleted file mode 100644 index 33c5b10..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Supply.sol +++ /dev/null @@ -1,90 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/extensions/ERC1155Supply.sol) - -pragma solidity ^0.8.20; - -import {ERC1155} from "../ERC1155.sol"; -import {Arrays} from "../../../utils/Arrays.sol"; - -/** - * @dev Extension of ERC-1155 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. - * - * NOTE: This contract implies a global limit of 2**256 - 1 to the number of tokens - * that can be minted. - * - * CAUTION: This extension should not be added in an upgrade to an already deployed contract. - */ -abstract contract ERC1155Supply is ERC1155 { - using Arrays for uint256[]; - - mapping(uint256 id => uint256) private _totalSupply; - uint256 private _totalSupplyAll; - - /** - * @dev Total value of tokens in with a given id. - */ - function totalSupply(uint256 id) public view virtual returns (uint256) { - return _totalSupply[id]; - } - - /** - * @dev Total value of tokens. - */ - function totalSupply() public view virtual returns (uint256) { - return _totalSupplyAll; - } - - /** - * @dev Indicates whether any token exist with a given id, or not. - */ - function exists(uint256 id) public view virtual returns (bool) { - return totalSupply(id) > 0; - } - - /** - * @dev See {ERC1155-_update}. - */ - function _update( - address from, - address to, - uint256[] memory ids, - uint256[] memory values - ) internal virtual override { - super._update(from, to, ids, values); - - if (from == address(0)) { - uint256 totalMintValue = 0; - for (uint256 i = 0; i < ids.length; ++i) { - uint256 value = values.unsafeMemoryAccess(i); - // Overflow check required: The rest of the code assumes that totalSupply never overflows - _totalSupply[ids.unsafeMemoryAccess(i)] += value; - totalMintValue += value; - } - // Overflow check required: The rest of the code assumes that totalSupplyAll never overflows - _totalSupplyAll += totalMintValue; - } - - if (to == address(0)) { - uint256 totalBurnValue = 0; - for (uint256 i = 0; i < ids.length; ++i) { - uint256 value = values.unsafeMemoryAccess(i); - - unchecked { - // Overflow not possible: values[i] <= balanceOf(from, ids[i]) <= totalSupply(ids[i]) - _totalSupply[ids.unsafeMemoryAccess(i)] -= value; - // Overflow not possible: sum_i(values[i]) <= sum_i(totalSupply(ids[i])) <= totalSupplyAll - totalBurnValue += value; - } - } - unchecked { - // Overflow not possible: totalBurnValue = sum_i(values[i]) <= sum_i(totalSupply(ids[i])) <= totalSupplyAll - _totalSupplyAll -= totalBurnValue; - } - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155URIStorage.sol b/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155URIStorage.sol deleted file mode 100644 index e8436e8..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155URIStorage.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/extensions/ERC1155URIStorage.sol) - -pragma solidity ^0.8.20; - -import {Strings} from "../../../utils/Strings.sol"; -import {ERC1155} from "../ERC1155.sol"; - -/** - * @dev ERC-1155 token with storage based token URI management. - * Inspired by the {ERC721URIStorage} extension - */ -abstract contract ERC1155URIStorage is ERC1155 { - using Strings for uint256; - - // Optional base URI - string private _baseURI = ""; - - // Optional mapping for token URIs - mapping(uint256 tokenId => 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 string.concat). - return bytes(tokenURI).length > 0 ? string.concat(_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/openzeppelin-contracts/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol b/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol deleted file mode 100644 index ea07897..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/extensions/IERC1155MetadataURI.sol) - -pragma solidity ^0.8.20; - -import {IERC1155} from "../IERC1155.sol"; - -/** - * @dev Interface of the optional ERC1155MetadataExtension interface, as defined - * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[ERC]. - */ -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/openzeppelin-contracts/contracts/token/ERC1155/utils/ERC1155Holder.sol b/lib/openzeppelin-contracts/contracts/token/ERC1155/utils/ERC1155Holder.sol deleted file mode 100644 index 35be58c..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC1155/utils/ERC1155Holder.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/utils/ERC1155Holder.sol) - -pragma solidity ^0.8.20; - -import {IERC165, ERC165} from "../../../utils/introspection/ERC165.sol"; -import {IERC1155Receiver} from "../IERC1155Receiver.sol"; - -/** - * @dev Simple implementation of `IERC1155Receiver` that will allow a contract to hold ERC-1155 tokens. - * - * IMPORTANT: When inheriting this contract, you must include a way to use the received tokens, otherwise they will be - * stuck. - */ -abstract contract ERC1155Holder 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); - } - - 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/openzeppelin-contracts/contracts/token/ERC1155/utils/ERC1155Utils.sol b/lib/openzeppelin-contracts/contracts/token/ERC1155/utils/ERC1155Utils.sol deleted file mode 100644 index 0ff2bf1..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC1155/utils/ERC1155Utils.sol +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {IERC1155Receiver} from "../IERC1155Receiver.sol"; -import {IERC1155Errors} from "../../../interfaces/draft-IERC6093.sol"; - -/** - * @dev Library that provide common ERC-1155 utility functions. - * - * See https://eips.ethereum.org/EIPS/eip-1155[ERC-1155]. - */ -library ERC1155Utils { - /** - * @dev Performs an acceptance check for the provided `operator` by calling {IERC1155-onERC1155Received} - * on the `to` address. The `operator` is generally the address that initiated the token transfer (i.e. `msg.sender`). - * - * The acceptance call is not executed and treated as a no-op if the target address is doesn't contain code (i.e. an EOA). - * Otherwise, the recipient must implement {IERC1155Receiver-onERC1155Received} and return the acceptance magic value to accept - * the transfer. - */ - function checkOnERC1155Received( - address operator, - address from, - address to, - uint256 id, - uint256 value, - bytes memory data - ) internal { - if (to.code.length > 0) { - try IERC1155Receiver(to).onERC1155Received(operator, from, id, value, data) returns (bytes4 response) { - if (response != IERC1155Receiver.onERC1155Received.selector) { - // Tokens rejected - revert IERC1155Errors.ERC1155InvalidReceiver(to); - } - } catch (bytes memory reason) { - if (reason.length == 0) { - // non-IERC1155Receiver implementer - revert IERC1155Errors.ERC1155InvalidReceiver(to); - } else { - /// @solidity memory-safe-assembly - assembly { - revert(add(32, reason), mload(reason)) - } - } - } - } - } - - /** - * @dev Performs a batch acceptance check for the provided `operator` by calling {IERC1155-onERC1155BatchReceived} - * on the `to` address. The `operator` is generally the address that initiated the token transfer (i.e. `msg.sender`). - * - * The acceptance call is not executed and treated as a no-op if the target address is doesn't contain code (i.e. an EOA). - * Otherwise, the recipient must implement {IERC1155Receiver-onERC1155Received} and return the acceptance magic value to accept - * the transfer. - */ - function checkOnERC1155BatchReceived( - address operator, - address from, - address to, - uint256[] memory ids, - uint256[] memory values, - bytes memory data - ) internal { - if (to.code.length > 0) { - try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, values, data) returns ( - bytes4 response - ) { - if (response != IERC1155Receiver.onERC1155BatchReceived.selector) { - // Tokens rejected - revert IERC1155Errors.ERC1155InvalidReceiver(to); - } - } catch (bytes memory reason) { - if (reason.length == 0) { - // non-IERC1155Receiver implementer - revert IERC1155Errors.ERC1155InvalidReceiver(to); - } else { - /// @solidity memory-safe-assembly - assembly { - revert(add(32, reason), mload(reason)) - } - } - } - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol b/lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol deleted file mode 100644 index 9885eaa..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol +++ /dev/null @@ -1,312 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol) - -pragma solidity ^0.8.20; - -import {IERC20} from "./IERC20.sol"; -import {IERC20Metadata} from "./extensions/IERC20Metadata.sol"; -import {Context} from "../../utils/Context.sol"; -import {IERC20Errors} from "../../interfaces/draft-IERC6093.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}. - * - * 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]. - * - * The default value of {decimals} is 18. To change this, you should override - * this function so it returns a different value. - * - * 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 ERC-20 - * applications. - */ -abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors { - mapping(address account => uint256) private _balances; - - mapping(address account => mapping(address spender => uint256)) private _allowances; - - uint256 private _totalSupply; - - string private _name; - string private _symbol; - - /** - * @dev Sets the values for {name} and {symbol}. - * - * 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 returns (string memory) { - return _name; - } - - /** - * @dev Returns the symbol of the token, usually a shorter version of the - * name. - */ - function symbol() public view virtual 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 default value returned by this function, unless - * it's 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 returns (uint8) { - return 18; - } - - /** - * @dev See {IERC20-totalSupply}. - */ - function totalSupply() public view virtual returns (uint256) { - return _totalSupply; - } - - /** - * @dev See {IERC20-balanceOf}. - */ - function balanceOf(address account) public view virtual 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 `value`. - */ - function transfer(address to, uint256 value) public virtual returns (bool) { - address owner = _msgSender(); - _transfer(owner, to, value); - return true; - } - - /** - * @dev See {IERC20-allowance}. - */ - function allowance(address owner, address spender) public view virtual returns (uint256) { - return _allowances[owner][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. - * - * Requirements: - * - * - `spender` cannot be the zero address. - */ - function approve(address spender, uint256 value) public virtual returns (bool) { - address owner = _msgSender(); - _approve(owner, spender, value); - return true; - } - - /** - * @dev See {IERC20-transferFrom}. - * - * Skips emitting an {Approval} event indicating an allowance update. This is not - * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve]. - * - * 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 `value`. - * - the caller must have allowance for ``from``'s tokens of at least - * `value`. - */ - function transferFrom(address from, address to, uint256 value) public virtual returns (bool) { - address spender = _msgSender(); - _spendAllowance(from, spender, value); - _transfer(from, to, value); - return true; - } - - /** - * @dev Moves a `value` 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. - * - * NOTE: This function is not virtual, {_update} should be overridden instead. - */ - function _transfer(address from, address to, uint256 value) internal { - if (from == address(0)) { - revert ERC20InvalidSender(address(0)); - } - if (to == address(0)) { - revert ERC20InvalidReceiver(address(0)); - } - _update(from, to, value); - } - - /** - * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from` - * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding - * this function. - * - * Emits a {Transfer} event. - */ - function _update(address from, address to, uint256 value) internal virtual { - if (from == address(0)) { - // Overflow check required: The rest of the code assumes that totalSupply never overflows - _totalSupply += value; - } else { - uint256 fromBalance = _balances[from]; - if (fromBalance < value) { - revert ERC20InsufficientBalance(from, fromBalance, value); - } - unchecked { - // Overflow not possible: value <= fromBalance <= totalSupply. - _balances[from] = fromBalance - value; - } - } - - if (to == address(0)) { - unchecked { - // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply. - _totalSupply -= value; - } - } else { - unchecked { - // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256. - _balances[to] += value; - } - } - - emit Transfer(from, to, value); - } - - /** - * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0). - * Relies on the `_update` mechanism - * - * Emits a {Transfer} event with `from` set to the zero address. - * - * NOTE: This function is not virtual, {_update} should be overridden instead. - */ - function _mint(address account, uint256 value) internal { - if (account == address(0)) { - revert ERC20InvalidReceiver(address(0)); - } - _update(address(0), account, value); - } - - /** - * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply. - * Relies on the `_update` mechanism. - * - * Emits a {Transfer} event with `to` set to the zero address. - * - * NOTE: This function is not virtual, {_update} should be overridden instead - */ - function _burn(address account, uint256 value) internal { - if (account == address(0)) { - revert ERC20InvalidSender(address(0)); - } - _update(account, address(0), value); - } - - /** - * @dev Sets `value` 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. - * - * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. - */ - function _approve(address owner, address spender, uint256 value) internal { - _approve(owner, spender, value, true); - } - - /** - * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event. - * - * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by - * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any - * `Approval` event during `transferFrom` operations. - * - * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to - * true using the following override: - * - * ```solidity - * function _approve(address owner, address spender, uint256 value, bool) internal virtual override { - * super._approve(owner, spender, value, true); - * } - * ``` - * - * Requirements are the same as {_approve}. - */ - function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual { - if (owner == address(0)) { - revert ERC20InvalidApprover(address(0)); - } - if (spender == address(0)) { - revert ERC20InvalidSpender(address(0)); - } - _allowances[owner][spender] = value; - if (emitEvent) { - emit Approval(owner, spender, value); - } - } - - /** - * @dev Updates `owner` s allowance for `spender` based on spent `value`. - * - * Does not update the allowance value in case of infinite allowance. - * Revert if not enough allowance is available. - * - * Does not emit an {Approval} event. - */ - function _spendAllowance(address owner, address spender, uint256 value) internal virtual { - uint256 currentAllowance = allowance(owner, spender); - if (currentAllowance != type(uint256).max) { - if (currentAllowance < value) { - revert ERC20InsufficientAllowance(spender, currentAllowance, value); - } - unchecked { - _approve(owner, spender, currentAllowance - value, false); - } - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol b/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol deleted file mode 100644 index d890721..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol +++ /dev/null @@ -1,79 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) - -pragma solidity ^0.8.20; - -/** - * @dev Interface of the ERC-20 standard as defined in the ERC. - */ -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 value of tokens in existence. - */ - function totalSupply() external view returns (uint256); - - /** - * @dev Returns the value of tokens owned by `account`. - */ - function balanceOf(address account) external view returns (uint256); - - /** - * @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool); - - /** - * @dev Moves a `value` amount of tokens from `from` to `to` using the - * allowance mechanism. `value` 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 value) external returns (bool); -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC20/README.adoc b/lib/openzeppelin-contracts/contracts/token/ERC20/README.adoc deleted file mode 100644 index 938784f..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC20/README.adoc +++ /dev/null @@ -1,70 +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[ERC-20 Token Standard]. - -TIP: For an overview of ERC-20 tokens and a walk through on how to create a token contract read our xref:ROOT:erc20.adoc[ERC-20 guide]. - -There are a few core contracts that implement the behavior specified in the ERC: - -* {IERC20}: the interface all ERC-20 implementations should conform to. -* {IERC20Metadata}: the extended ERC-20 interface including the <>, <> and <> functions. -* {ERC20}: the implementation of the ERC-20 interface, including the <>, <> and <> optional standard extension to the base interface. - -Additionally there are multiple custom extensions, including: - -* {ERC20Permit}: gasless approval of tokens (standardized as ERC-2612). -* {ERC20Burnable}: destruction of own tokens. -* {ERC20Capped}: enforcement of a cap to the total supply when minting tokens. -* {ERC20Pausable}: ability to pause token transfers. -* {ERC20FlashMint}: token level support for flash loans through the minting and burning of ephemeral tokens (standardized as ERC-3156). -* {ERC20Votes}: support for voting and vote delegation. -* {ERC20Wrapper}: wrapper to create an ERC-20 backed by another ERC-20, with deposit and withdraw methods. Useful in conjunction with {ERC20Votes}. -* {ERC1363}: support for calling the target of a transfer or approval, enabling code execution on the receiver within a single transaction. -* {ERC4626}: tokenized vault that manages shares (represented as ERC-20) that are backed by assets (another ERC-20). - -Finally, there are some utilities to interact with ERC-20 contracts in various ways: - -* {SafeERC20}: a wrapper around the interface that eliminates the need to handle boolean return values. - -Other utilities that support ERC-20 assets can be found in codebase: - -* ERC-20 tokens can be timelocked (held tokens for a beneficiary until a specified time) or vested (released following a given schedule) using a {VestingWallet}. - -NOTE: This core set of contracts is designed to be unopinionated, allowing developers to access the internal functions in ERC-20 (such as <>) and expose them as external functions in the way they prefer. - -== Core - -{{IERC20}} - -{{IERC20Metadata}} - -{{ERC20}} - -== Extensions - -{{IERC20Permit}} - -{{ERC20Permit}} - -{{ERC20Burnable}} - -{{ERC20Capped}} - -{{ERC20Pausable}} - -{{ERC20Votes}} - -{{ERC20Wrapper}} - -{{ERC20FlashMint}} - -{{ERC1363}} - -{{ERC4626}} - -== Utilities - -{{SafeERC20}} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC1363.sol b/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC1363.sol deleted file mode 100644 index 1852ffa..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC1363.sol +++ /dev/null @@ -1,205 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {ERC20} from "../ERC20.sol"; -import {IERC165, ERC165} from "../../../utils/introspection/ERC165.sol"; - -import {IERC1363} from "../../../interfaces/IERC1363.sol"; -import {IERC1363Receiver} from "../../../interfaces/IERC1363Receiver.sol"; -import {IERC1363Spender} from "../../../interfaces/IERC1363Spender.sol"; - -/** - * @title ERC1363 - * @dev Extension of {ERC20} tokens that adds support for code execution after transfers and approvals - * on recipient contracts. Calls after transfers are enabled through the {ERC1363-transferAndCall} and - * {ERC1363-transferFromAndCall} methods while calls after approvals can be made with {ERC1363-approveAndCall} - */ -abstract contract ERC1363 is ERC20, ERC165, IERC1363 { - /** - * @dev Indicates a failure with the token `receiver`. Used in transfers. - * @param receiver Address to which tokens are being transferred. - */ - error ERC1363InvalidReceiver(address receiver); - - /** - * @dev Indicates a failure with the token `spender`. Used in approvals. - * @param spender Address that may be allowed to operate on tokens without being their owner. - */ - error ERC1363InvalidSpender(address spender); - - /** - * @dev Indicates a failure within the {transfer} part of a transferAndCall operation. - * @param receiver Address to which tokens are being transferred. - * @param value Amount of tokens to be transferred. - */ - error ERC1363TransferFailed(address receiver, uint256 value); - - /** - * @dev Indicates a failure within the {transferFrom} part of a transferFromAndCall operation. - * @param sender Address from which to send tokens. - * @param receiver Address to which tokens are being transferred. - * @param value Amount of tokens to be transferred. - */ - error ERC1363TransferFromFailed(address sender, address receiver, uint256 value); - - /** - * @dev Indicates a failure within the {approve} part of a approveAndCall operation. - * @param spender Address which will spend the funds. - * @param value Amount of tokens to be spent. - */ - error ERC1363ApproveFailed(address spender, uint256 value); - - /** - * @inheritdoc IERC165 - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { - return interfaceId == type(IERC1363).interfaceId || super.supportsInterface(interfaceId); - } - - /** - * @dev Moves a `value` amount of tokens from the caller's account to `to` - * and then calls {IERC1363Receiver-onTransferReceived} on `to`. - * - * Requirements: - * - * - The target has code (i.e. is a contract). - * - The target `to` must implement the {IERC1363Receiver} interface. - * - The target must return the {IERC1363Receiver-onTransferReceived} selector to accept the transfer. - * - The internal {transfer} must succeed (returned `true`). - */ - function transferAndCall(address to, uint256 value) public returns (bool) { - return transferAndCall(to, value, ""); - } - - /** - * @dev Variant of {transferAndCall} that accepts an additional `data` parameter with - * no specified format. - */ - function transferAndCall(address to, uint256 value, bytes memory data) public virtual returns (bool) { - if (!transfer(to, value)) { - revert ERC1363TransferFailed(to, value); - } - _checkOnTransferReceived(_msgSender(), to, value, data); - return true; - } - - /** - * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism - * and then calls {IERC1363Receiver-onTransferReceived} on `to`. - * - * Requirements: - * - * - The target has code (i.e. is a contract). - * - The target `to` must implement the {IERC1363Receiver} interface. - * - The target must return the {IERC1363Receiver-onTransferReceived} selector to accept the transfer. - * - The internal {transferFrom} must succeed (returned `true`). - */ - function transferFromAndCall(address from, address to, uint256 value) public returns (bool) { - return transferFromAndCall(from, to, value, ""); - } - - /** - * @dev Variant of {transferFromAndCall} that accepts an additional `data` parameter with - * no specified format. - */ - function transferFromAndCall( - address from, - address to, - uint256 value, - bytes memory data - ) public virtual returns (bool) { - if (!transferFrom(from, to, value)) { - revert ERC1363TransferFromFailed(from, to, value); - } - _checkOnTransferReceived(from, to, value, data); - return true; - } - - /** - * @dev Sets a `value` amount of tokens as the allowance of `spender` over the - * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. - * - * Requirements: - * - * - The target has code (i.e. is a contract). - * - The target `spender` must implement the {IERC1363Spender} interface. - * - The target must return the {IERC1363Spender-onApprovalReceived} selector to accept the approval. - * - The internal {approve} must succeed (returned `true`). - */ - function approveAndCall(address spender, uint256 value) public returns (bool) { - return approveAndCall(spender, value, ""); - } - - /** - * @dev Variant of {approveAndCall} that accepts an additional `data` parameter with - * no specified format. - */ - function approveAndCall(address spender, uint256 value, bytes memory data) public virtual returns (bool) { - if (!approve(spender, value)) { - revert ERC1363ApproveFailed(spender, value); - } - _checkOnApprovalReceived(spender, value, data); - return true; - } - - /** - * @dev Performs a call to {IERC1363Receiver-onTransferReceived} on a target address. - * - * Requirements: - * - * - The target has code (i.e. is a contract). - * - The target `to` must implement the {IERC1363Receiver} interface. - * - The target must return the {IERC1363Receiver-onTransferReceived} selector to accept the transfer. - */ - function _checkOnTransferReceived(address from, address to, uint256 value, bytes memory data) private { - if (to.code.length == 0) { - revert ERC1363InvalidReceiver(to); - } - - try IERC1363Receiver(to).onTransferReceived(_msgSender(), from, value, data) returns (bytes4 retval) { - if (retval != IERC1363Receiver.onTransferReceived.selector) { - revert ERC1363InvalidReceiver(to); - } - } catch (bytes memory reason) { - if (reason.length == 0) { - revert ERC1363InvalidReceiver(to); - } else { - /// @solidity memory-safe-assembly - assembly { - revert(add(32, reason), mload(reason)) - } - } - } - } - - /** - * @dev Performs a call to {IERC1363Spender-onApprovalReceived} on a target address. - * - * Requirements: - * - * - The target has code (i.e. is a contract). - * - The target `spender` must implement the {IERC1363Spender} interface. - * - The target must return the {IERC1363Spender-onApprovalReceived} selector to accept the approval. - */ - function _checkOnApprovalReceived(address spender, uint256 value, bytes memory data) private { - if (spender.code.length == 0) { - revert ERC1363InvalidSpender(spender); - } - - try IERC1363Spender(spender).onApprovalReceived(_msgSender(), value, data) returns (bytes4 retval) { - if (retval != IERC1363Spender.onApprovalReceived.selector) { - revert ERC1363InvalidSpender(spender); - } - } catch (bytes memory reason) { - if (reason.length == 0) { - revert ERC1363InvalidSpender(spender); - } else { - /// @solidity memory-safe-assembly - assembly { - revert(add(32, reason), mload(reason)) - } - } - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Burnable.sol b/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Burnable.sol deleted file mode 100644 index 4d482d8..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Burnable.sol +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Burnable.sol) - -pragma solidity ^0.8.20; - -import {ERC20} from "../ERC20.sol"; -import {Context} from "../../../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 a `value` amount of tokens from the caller. - * - * See {ERC20-_burn}. - */ - function burn(uint256 value) public virtual { - _burn(_msgSender(), value); - } - - /** - * @dev Destroys a `value` amount of 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 - * `value`. - */ - function burnFrom(address account, uint256 value) public virtual { - _spendAllowance(account, _msgSender(), value); - _burn(account, value); - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Capped.sol b/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Capped.sol deleted file mode 100644 index 56bafb3..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Capped.sol +++ /dev/null @@ -1,56 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Capped.sol) - -pragma solidity ^0.8.20; - -import {ERC20} from "../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 Total supply cap has been exceeded. - */ - error ERC20ExceededCap(uint256 increasedSupply, uint256 cap); - - /** - * @dev The supplied cap is not a valid cap. - */ - error ERC20InvalidCap(uint256 cap); - - /** - * @dev Sets the value of the `cap`. This value is immutable, it can only be - * set once during construction. - */ - constructor(uint256 cap_) { - if (cap_ == 0) { - revert ERC20InvalidCap(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-_update}. - */ - function _update(address from, address to, uint256 value) internal virtual override { - super._update(from, to, value); - - if (from == address(0)) { - uint256 maxSupply = cap(); - uint256 supply = totalSupply(); - if (supply > maxSupply) { - revert ERC20ExceededCap(supply, maxSupply); - } - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20FlashMint.sol b/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20FlashMint.sol deleted file mode 100644 index fd8ff0b..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20FlashMint.sol +++ /dev/null @@ -1,134 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20FlashMint.sol) - -pragma solidity ^0.8.20; - -import {IERC3156FlashBorrower} from "../../../interfaces/IERC3156FlashBorrower.sol"; -import {IERC3156FlashLender} from "../../../interfaces/IERC3156FlashLender.sol"; -import {ERC20} from "../ERC20.sol"; - -/** - * @dev Implementation of the ERC-3156 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}. - * - * NOTE: When this extension is used along with the {ERC20Capped} or {ERC20Votes} extensions, - * {maxFlashLoan} will not correctly reflect the maximum that can be flash minted. We recommend - * overriding {maxFlashLoan} so that it correctly reflects the supply cap. - */ -abstract contract ERC20FlashMint is ERC20, IERC3156FlashLender { - bytes32 private constant RETURN_VALUE = keccak256("ERC3156FlashBorrower.onFlashLoan"); - - /** - * @dev The loan token is not valid. - */ - error ERC3156UnsupportedToken(address token); - - /** - * @dev The requested loan exceeds the max loan value for `token`. - */ - error ERC3156ExceededMaxLoan(uint256 maxLoan); - - /** - * @dev The receiver of a flashloan is not a valid {IERC3156FlashBorrower-onFlashLoan} implementer. - */ - error ERC3156InvalidReceiver(address receiver); - - /** - * @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. - * - * NOTE: This function does not consider any form of supply cap, so in case - * it's used in a token with a cap like {ERC20Capped}, make sure to override this - * function to integrate the cap instead of `type(uint256).max`. - */ - function maxFlashLoan(address token) public view virtual returns (uint256) { - return token == address(this) ? type(uint256).max - 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 value The amount of tokens to be loaned. - * @return The fees applied to the corresponding flash loan. - */ - function flashFee(address token, uint256 value) public view virtual returns (uint256) { - if (token != address(this)) { - revert ERC3156UnsupportedToken(token); - } - return _flashFee(token, value); - } - - /** - * @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 value The amount of tokens to be loaned. - * @return The fees applied to the corresponding flash loan. - */ - function _flashFee(address token, uint256 value) internal view virtual returns (uint256) { - // silence warning about unused variable without the addition of bytecode. - token; - value; - 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 - * value + 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 value 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 value, - bytes calldata data - ) public virtual returns (bool) { - uint256 maxLoan = maxFlashLoan(token); - if (value > maxLoan) { - revert ERC3156ExceededMaxLoan(maxLoan); - } - uint256 fee = flashFee(token, value); - _mint(address(receiver), value); - if (receiver.onFlashLoan(_msgSender(), token, value, fee, data) != RETURN_VALUE) { - revert ERC3156InvalidReceiver(address(receiver)); - } - address flashFeeReceiver = _flashFeeReceiver(); - _spendAllowance(address(receiver), address(this), value + fee); - if (fee == 0 || flashFeeReceiver == address(0)) { - _burn(address(receiver), value + fee); - } else { - _burn(address(receiver), value); - _transfer(address(receiver), flashFeeReceiver, fee); - } - return true; - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Pausable.sol b/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Pausable.sol deleted file mode 100644 index 9b56f05..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Pausable.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Pausable.sol) - -pragma solidity ^0.8.20; - -import {ERC20} from "../ERC20.sol"; -import {Pausable} from "../../../utils/Pausable.sol"; - -/** - * @dev ERC-20 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 pause mechanism of the contract unreachable, and thus unusable. - */ -abstract contract ERC20Pausable is ERC20, Pausable { - /** - * @dev See {ERC20-_update}. - * - * Requirements: - * - * - the contract must not be paused. - */ - function _update(address from, address to, uint256 value) internal virtual override whenNotPaused { - super._update(from, to, value); - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Permit.sol b/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Permit.sol deleted file mode 100644 index 22b19dc..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Permit.sol +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Permit.sol) - -pragma solidity ^0.8.20; - -import {IERC20Permit} from "./IERC20Permit.sol"; -import {ERC20} from "../ERC20.sol"; -import {ECDSA} from "../../../utils/cryptography/ECDSA.sol"; -import {EIP712} from "../../../utils/cryptography/EIP712.sol"; -import {Nonces} from "../../../utils/Nonces.sol"; - -/** - * @dev Implementation of the ERC-20 Permit extension allowing approvals to be made via signatures, as defined in - * https://eips.ethereum.org/EIPS/eip-2612[ERC-2612]. - * - * Adds the {permit} method, which can be used to change an account's ERC-20 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. - */ -abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712, Nonces { - bytes32 private constant PERMIT_TYPEHASH = - keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); - - /** - * @dev Permit deadline has expired. - */ - error ERC2612ExpiredSignature(uint256 deadline); - - /** - * @dev Mismatched signature. - */ - error ERC2612InvalidSigner(address signer, address owner); - - /** - * @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 ERC-20 token name. - */ - constructor(string memory name) EIP712(name, "1") {} - - /** - * @inheritdoc IERC20Permit - */ - function permit( - address owner, - address spender, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual { - if (block.timestamp > deadline) { - revert ERC2612ExpiredSignature(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); - if (signer != owner) { - revert ERC2612InvalidSigner(signer, owner); - } - - _approve(owner, spender, value); - } - - /** - * @inheritdoc IERC20Permit - */ - function nonces(address owner) public view virtual override(IERC20Permit, Nonces) returns (uint256) { - return super.nonces(owner); - } - - /** - * @inheritdoc IERC20Permit - */ - // solhint-disable-next-line func-name-mixedcase - function DOMAIN_SEPARATOR() external view virtual returns (bytes32) { - return _domainSeparatorV4(); - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Votes.sol b/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Votes.sol deleted file mode 100644 index 7680293..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Votes.sol +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Votes.sol) - -pragma solidity ^0.8.20; - -import {ERC20} from "../ERC20.sol"; -import {Votes} from "../../../governance/utils/Votes.sol"; -import {Checkpoints} from "../../../utils/structs/Checkpoints.sol"; - -/** - * @dev Extension of ERC-20 to support Compound-like voting and delegation. This version is more generic than Compound's, - * and supports token supply up to 2^208^ - 1, while COMP is limited to 2^96^ - 1. - * - * NOTE: This contract does not provide interface compatibility with Compound's COMP token. - * - * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either - * by calling the {Votes-delegate} function directly, or by providing a signature to be used with {Votes-delegateBySig}. Voting - * power can be queried through the public accessors {Votes-getVotes} and {Votes-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. - */ -abstract contract ERC20Votes is ERC20, Votes { - /** - * @dev Total supply cap has been exceeded, introducing a risk of votes overflowing. - */ - error ERC20ExceededSafeSupply(uint256 increasedSupply, uint256 cap); - - /** - * @dev Maximum token supply. Defaults to `type(uint208).max` (2^208^ - 1). - * - * This maximum is enforced in {_update}. It limits the total supply of the token, which is otherwise a uint256, - * so that checkpoints can be stored in the Trace208 structure used by {Votes}. Increasing this value will not - * remove the underlying limitation, and will cause {_update} to fail because of a math overflow in - * {Votes-_transferVotingUnits}. An override could be used to further restrict the total supply (to a lower value) if - * additional logic requires it. When resolving override conflicts on this function, the minimum should be - * returned. - */ - function _maxSupply() internal view virtual returns (uint256) { - return type(uint208).max; - } - - /** - * @dev Move voting power when tokens are transferred. - * - * Emits a {IVotes-DelegateVotesChanged} event. - */ - function _update(address from, address to, uint256 value) internal virtual override { - super._update(from, to, value); - if (from == address(0)) { - uint256 supply = totalSupply(); - uint256 cap = _maxSupply(); - if (supply > cap) { - revert ERC20ExceededSafeSupply(supply, cap); - } - } - _transferVotingUnits(from, to, value); - } - - /** - * @dev Returns the voting units of an `account`. - * - * WARNING: Overriding this function may compromise the internal vote accounting. - * `ERC20Votes` assumes tokens map to voting units 1:1 and this is not easy to change. - */ - function _getVotingUnits(address account) internal view virtual override returns (uint256) { - return balanceOf(account); - } - - /** - * @dev Get number of checkpoints for `account`. - */ - function numCheckpoints(address account) public view virtual returns (uint32) { - return _numCheckpoints(account); - } - - /** - * @dev Get the `pos`-th checkpoint for `account`. - */ - function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoints.Checkpoint208 memory) { - return _checkpoints(account, pos); - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Wrapper.sol b/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Wrapper.sol deleted file mode 100644 index eecd6ab..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Wrapper.sol +++ /dev/null @@ -1,91 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Wrapper.sol) - -pragma solidity ^0.8.20; - -import {IERC20, IERC20Metadata, ERC20} from "../ERC20.sol"; -import {SafeERC20} from "../utils/SafeERC20.sol"; - -/** - * @dev Extension of the ERC-20 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" ERC-20 into a governance token. - * - * WARNING: Any mechanism in which the underlying token changes the {balanceOf} of an account without an explicit transfer - * may desynchronize this contract's supply and its underlying balance. Please exercise caution when wrapping tokens that - * may undercollateralize the wrapper (i.e. wrapper's total supply is higher than its underlying balance). See {_recover} - * for recovering value accrued to the wrapper. - */ -abstract contract ERC20Wrapper is ERC20 { - IERC20 private immutable _underlying; - - /** - * @dev The underlying token couldn't be wrapped. - */ - error ERC20InvalidUnderlying(address token); - - constructor(IERC20 underlyingToken) { - if (underlyingToken == this) { - revert ERC20InvalidUnderlying(address(this)); - } - _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 Returns the address of the underlying ERC-20 token that is being wrapped. - */ - function underlying() public view returns (IERC20) { - return _underlying; - } - - /** - * @dev Allow a user to deposit underlying tokens and mint the corresponding number of wrapped tokens. - */ - function depositFor(address account, uint256 value) public virtual returns (bool) { - address sender = _msgSender(); - if (sender == address(this)) { - revert ERC20InvalidSender(address(this)); - } - if (account == address(this)) { - revert ERC20InvalidReceiver(account); - } - SafeERC20.safeTransferFrom(_underlying, sender, address(this), value); - _mint(account, value); - 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 value) public virtual returns (bool) { - if (account == address(this)) { - revert ERC20InvalidReceiver(account); - } - _burn(_msgSender(), value); - SafeERC20.safeTransfer(_underlying, account, value); - return true; - } - - /** - * @dev Mint wrapped token to cover any underlyingTokens that would have been transferred by mistake or acquired from - * rebasing mechanisms. 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/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC4626.sol b/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC4626.sol deleted file mode 100644 index c71b14a..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC4626.sol +++ /dev/null @@ -1,282 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC4626.sol) - -pragma solidity ^0.8.20; - -import {IERC20, IERC20Metadata, ERC20} from "../ERC20.sol"; -import {SafeERC20} from "../utils/SafeERC20.sol"; -import {IERC4626} from "../../../interfaces/IERC4626.sol"; -import {Math} from "../../../utils/math/Math.sol"; - -/** - * @dev Implementation of the ERC-4626 "Tokenized Vault Standard" as defined in - * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626]. - * - * This extension allows the minting and burning of "shares" (represented using the ERC-20 inheritance) in exchange for - * underlying "assets" through standardized {deposit}, {mint}, {redeem} and {burn} workflows. This contract extends - * the ERC-20 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] - * ==== - * In empty (or nearly empty) ERC-4626 vaults, 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 as 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]. - * - * Since v4.9, this implementation introduces configurable virtual assets and shares to help developers mitigate that risk. - * The `_decimalsOffset()` corresponds to an offset in the decimal representation between the underlying asset's decimals - * and the vault decimals. This offset also determines the rate of virtual shares to virtual assets in the vault, which - * itself determines the initial exchange rate. While not fully preventing the attack, analysis shows that the default - * offset (0) makes it non-profitable even if an attacker is able to capture value from multiple user deposits, as a result - * of the value being captured by the virtual shares (out of the attacker's donation) matching the attacker's expected gains. - * With a larger offset, the attack becomes orders of magnitude more expensive than it is profitable. More details about the - * underlying math can be found xref:erc4626.adoc#inflation-attack[here]. - * - * The drawback of this approach is that the virtual shares do capture (a very small) part of the value being accrued - * to the vault. Also, if the vault experiences losses, the users try to exit the vault, the virtual shares and assets - * will cause the first user to exit to experience reduced losses in detriment to the last users that will experience - * bigger losses. Developers willing to revert back to the pre-v4.9 behavior just need to override the - * `_convertToShares` and `_convertToAssets` functions. - * - * To learn more, check out our xref:ROOT:erc4626.adoc[ERC-4626 guide]. - * ==== - */ -abstract contract ERC4626 is ERC20, IERC4626 { - using Math for uint256; - - IERC20 private immutable _asset; - uint8 private immutable _underlyingDecimals; - - /** - * @dev Attempted to deposit more assets than the max amount for `receiver`. - */ - error ERC4626ExceededMaxDeposit(address receiver, uint256 assets, uint256 max); - - /** - * @dev Attempted to mint more shares than the max amount for `receiver`. - */ - error ERC4626ExceededMaxMint(address receiver, uint256 shares, uint256 max); - - /** - * @dev Attempted to withdraw more assets than the max amount for `receiver`. - */ - error ERC4626ExceededMaxWithdraw(address owner, uint256 assets, uint256 max); - - /** - * @dev Attempted to redeem more shares than the max amount for `receiver`. - */ - error ERC4626ExceededMaxRedeem(address owner, uint256 shares, uint256 max); - - /** - * @dev Set the underlying asset contract. This must be an ERC20-compatible contract (ERC-20 or ERC-777). - */ - constructor(IERC20 asset_) { - (bool success, uint8 assetDecimals) = _tryGetAssetDecimals(asset_); - _underlyingDecimals = success ? assetDecimals : 18; - _asset = asset_; - } - - /** - * @dev Attempts to fetch the asset decimals. A return value of false indicates that the attempt failed in some way. - */ - function _tryGetAssetDecimals(IERC20 asset_) private view returns (bool, uint8) { - (bool success, bytes memory encodedDecimals) = address(asset_).staticcall( - abi.encodeCall(IERC20Metadata.decimals, ()) - ); - 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 computed by adding the decimal offset on top of the underlying asset's decimals. This - * "original" value is cached during construction of the vault contract. If this read operation fails (e.g., the - * asset has not been created yet), a default of 18 is used to represent the underlying asset's decimals. - * - * See {IERC20Metadata-decimals}. - */ - function decimals() public view virtual override(IERC20Metadata, ERC20) returns (uint8) { - return _underlyingDecimals + _decimalsOffset(); - } - - /** @dev See {IERC4626-asset}. */ - function asset() public view virtual returns (address) { - return address(_asset); - } - - /** @dev See {IERC4626-totalAssets}. */ - function totalAssets() public view virtual returns (uint256) { - return _asset.balanceOf(address(this)); - } - - /** @dev See {IERC4626-convertToShares}. */ - function convertToShares(uint256 assets) public view virtual returns (uint256) { - return _convertToShares(assets, Math.Rounding.Floor); - } - - /** @dev See {IERC4626-convertToAssets}. */ - function convertToAssets(uint256 shares) public view virtual returns (uint256) { - return _convertToAssets(shares, Math.Rounding.Floor); - } - - /** @dev See {IERC4626-maxDeposit}. */ - function maxDeposit(address) public view virtual returns (uint256) { - return type(uint256).max; - } - - /** @dev See {IERC4626-maxMint}. */ - function maxMint(address) public view virtual returns (uint256) { - return type(uint256).max; - } - - /** @dev See {IERC4626-maxWithdraw}. */ - function maxWithdraw(address owner) public view virtual returns (uint256) { - return _convertToAssets(balanceOf(owner), Math.Rounding.Floor); - } - - /** @dev See {IERC4626-maxRedeem}. */ - function maxRedeem(address owner) public view virtual returns (uint256) { - return balanceOf(owner); - } - - /** @dev See {IERC4626-previewDeposit}. */ - function previewDeposit(uint256 assets) public view virtual returns (uint256) { - return _convertToShares(assets, Math.Rounding.Floor); - } - - /** @dev See {IERC4626-previewMint}. */ - function previewMint(uint256 shares) public view virtual returns (uint256) { - return _convertToAssets(shares, Math.Rounding.Ceil); - } - - /** @dev See {IERC4626-previewWithdraw}. */ - function previewWithdraw(uint256 assets) public view virtual returns (uint256) { - return _convertToShares(assets, Math.Rounding.Ceil); - } - - /** @dev See {IERC4626-previewRedeem}. */ - function previewRedeem(uint256 shares) public view virtual returns (uint256) { - return _convertToAssets(shares, Math.Rounding.Floor); - } - - /** @dev See {IERC4626-deposit}. */ - function deposit(uint256 assets, address receiver) public virtual returns (uint256) { - uint256 maxAssets = maxDeposit(receiver); - if (assets > maxAssets) { - revert ERC4626ExceededMaxDeposit(receiver, assets, maxAssets); - } - - uint256 shares = previewDeposit(assets); - _deposit(_msgSender(), receiver, assets, shares); - - return shares; - } - - /** @dev See {IERC4626-mint}. */ - function mint(uint256 shares, address receiver) public virtual returns (uint256) { - uint256 maxShares = maxMint(receiver); - if (shares > maxShares) { - revert ERC4626ExceededMaxMint(receiver, shares, maxShares); - } - - 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 returns (uint256) { - uint256 maxAssets = maxWithdraw(owner); - if (assets > maxAssets) { - revert ERC4626ExceededMaxWithdraw(owner, assets, maxAssets); - } - - 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 returns (uint256) { - uint256 maxShares = maxRedeem(owner); - if (shares > maxShares) { - revert ERC4626ExceededMaxRedeem(owner, shares, maxShares); - } - - 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. - */ - function _convertToShares(uint256 assets, Math.Rounding rounding) internal view virtual returns (uint256) { - return assets.mulDiv(totalSupply() + 10 ** _decimalsOffset(), totalAssets() + 1, 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) { - return shares.mulDiv(totalAssets() + 1, totalSupply() + 10 ** _decimalsOffset(), rounding); - } - - /** - * @dev Deposit/mint common workflow. - */ - function _deposit(address caller, address receiver, uint256 assets, uint256 shares) internal virtual { - // If _asset is ERC-777, `transferFrom` can trigger a reentrancy 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 - 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 ERC-777, `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); - SafeERC20.safeTransfer(_asset, receiver, assets); - - emit Withdraw(caller, receiver, owner, assets, shares); - } - - function _decimalsOffset() internal view virtual returns (uint8) { - return 0; - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol b/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol deleted file mode 100644 index e8c020b..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol) - -pragma solidity ^0.8.20; - -import {IERC20} from "../IERC20.sol"; - -/** - * @dev Interface for the optional metadata functions from the ERC-20 standard. - */ -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/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol b/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol deleted file mode 100644 index a8ad26e..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol +++ /dev/null @@ -1,90 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol) - -pragma solidity ^0.8.20; - -/** - * @dev Interface of the ERC-20 Permit extension allowing approvals to be made via signatures, as defined in - * https://eips.ethereum.org/EIPS/eip-2612[ERC-2612]. - * - * Adds the {permit} method, which can be used to change an account's ERC-20 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. - * - * ==== Security Considerations - * - * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature - * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be - * considered as an intention to spend the allowance in any specific way. The second is that because permits have - * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should - * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be - * generally recommended is: - * - * ```solidity - * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { - * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} - * doThing(..., value); - * } - * - * function doThing(..., uint256 value) public { - * token.safeTransferFrom(msg.sender, address(this), value); - * ... - * } - * ``` - * - * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of - * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also - * {SafeERC20-safeTransferFrom}). - * - * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so - * contracts should have entry points that don't rely on permit. - */ -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]. - * - * CAUTION: See Security Considerations above. - */ - 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/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol b/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol deleted file mode 100644 index ed41fb0..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol +++ /dev/null @@ -1,185 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol) - -pragma solidity ^0.8.20; - -import {IERC20} from "../IERC20.sol"; -import {IERC1363} from "../../../interfaces/IERC1363.sol"; -import {Address} from "../../../utils/Address.sol"; - -/** - * @title SafeERC20 - * @dev Wrappers around ERC-20 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 { - /** - * @dev An operation with an ERC-20 token failed. - */ - error SafeERC20FailedOperation(address token); - - /** - * @dev Indicates a failed `decreaseAllowance` request. - */ - error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); - - /** - * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, - * non-reverting calls are assumed to be successful. - */ - function safeTransfer(IERC20 token, address to, uint256 value) internal { - _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); - } - - /** - * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the - * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. - */ - function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { - _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); - } - - /** - * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, - * non-reverting calls are assumed to be successful. - */ - function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { - uint256 oldAllowance = token.allowance(address(this), spender); - forceApprove(token, spender, oldAllowance + value); - } - - /** - * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no - * value, non-reverting calls are assumed to be successful. - */ - function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { - unchecked { - uint256 currentAllowance = token.allowance(address(this), spender); - if (currentAllowance < requestedDecrease) { - revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); - } - forceApprove(token, spender, currentAllowance - requestedDecrease); - } - } - - /** - * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, - * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval - * to be set to zero before setting it to a non-zero value, such as USDT. - */ - function forceApprove(IERC20 token, address spender, uint256 value) internal { - bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); - - if (!_callOptionalReturnBool(token, approvalCall)) { - _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); - _callOptionalReturn(token, approvalCall); - } - } - - /** - * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no - * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when - * targeting contracts. - * - * Reverts if the returned value is other than `true`. - */ - function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { - if (to.code.length == 0) { - safeTransfer(token, to, value); - } else if (!token.transferAndCall(to, value, data)) { - revert SafeERC20FailedOperation(address(token)); - } - } - - /** - * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target - * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when - * targeting contracts. - * - * Reverts if the returned value is other than `true`. - */ - function transferFromAndCallRelaxed( - IERC1363 token, - address from, - address to, - uint256 value, - bytes memory data - ) internal { - if (to.code.length == 0) { - safeTransferFrom(token, from, to, value); - } else if (!token.transferFromAndCall(from, to, value, data)) { - revert SafeERC20FailedOperation(address(token)); - } - } - - /** - * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no - * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when - * targeting contracts. - * - * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}. - * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall} - * once without retrying, and relies on the returned value to be true. - * - * Reverts if the returned value is other than `true`. - */ - function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { - if (to.code.length == 0) { - forceApprove(token, to, value); - } else if (!token.approveAndCall(to, value, data)) { - revert SafeERC20FailedOperation(address(token)); - } - } - - /** - * @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). - * - * This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements. - */ - function _callOptionalReturn(IERC20 token, bytes memory data) private { - uint256 returnSize; - uint256 returnValue; - assembly ("memory-safe") { - let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) - // bubble errors - if iszero(success) { - let ptr := mload(0x40) - returndatacopy(ptr, 0, returndatasize()) - revert(ptr, returndatasize()) - } - returnSize := returndatasize() - returnValue := mload(0) - } - - if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) { - revert SafeERC20FailedOperation(address(token)); - } - } - - /** - * @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). - * - * This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead. - */ - function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { - bool success; - uint256 returnSize; - uint256 returnValue; - assembly ("memory-safe") { - success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) - returnSize := returndatasize() - returnValue := mload(0) - } - return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1); - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol b/lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol deleted file mode 100644 index df7ff50..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol +++ /dev/null @@ -1,456 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/ERC721.sol) - -pragma solidity ^0.8.20; - -import {IERC721} from "./IERC721.sol"; -import {IERC721Metadata} from "./extensions/IERC721Metadata.sol"; -import {ERC721Utils} from "./utils/ERC721Utils.sol"; -import {Context} from "../../utils/Context.sol"; -import {Strings} from "../../utils/Strings.sol"; -import {IERC165, ERC165} from "../../utils/introspection/ERC165.sol"; -import {IERC721Errors} from "../../interfaces/draft-IERC6093.sol"; - -/** - * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC-721] Non-Fungible Token Standard, including - * the Metadata extension, but not including the Enumerable extension, which is available separately as - * {ERC721Enumerable}. - */ -abstract contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Errors { - using Strings for uint256; - - // Token name - string private _name; - - // Token symbol - string private _symbol; - - mapping(uint256 tokenId => address) private _owners; - - mapping(address owner => uint256) private _balances; - - mapping(uint256 tokenId => address) private _tokenApprovals; - - mapping(address owner => mapping(address operator => 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 returns (uint256) { - if (owner == address(0)) { - revert ERC721InvalidOwner(address(0)); - } - return _balances[owner]; - } - - /** - * @dev See {IERC721-ownerOf}. - */ - function ownerOf(uint256 tokenId) public view virtual returns (address) { - return _requireOwned(tokenId); - } - - /** - * @dev See {IERC721Metadata-name}. - */ - function name() public view virtual returns (string memory) { - return _name; - } - - /** - * @dev See {IERC721Metadata-symbol}. - */ - function symbol() public view virtual returns (string memory) { - return _symbol; - } - - /** - * @dev See {IERC721Metadata-tokenURI}. - */ - function tokenURI(uint256 tokenId) public view virtual returns (string memory) { - _requireOwned(tokenId); - - string memory baseURI = _baseURI(); - return bytes(baseURI).length > 0 ? string.concat(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 { - _approve(to, tokenId, _msgSender()); - } - - /** - * @dev See {IERC721-getApproved}. - */ - function getApproved(uint256 tokenId) public view virtual returns (address) { - _requireOwned(tokenId); - - return _getApproved(tokenId); - } - - /** - * @dev See {IERC721-setApprovalForAll}. - */ - function setApprovalForAll(address operator, bool approved) public virtual { - _setApprovalForAll(_msgSender(), operator, approved); - } - - /** - * @dev See {IERC721-isApprovedForAll}. - */ - function isApprovedForAll(address owner, address operator) public view virtual returns (bool) { - return _operatorApprovals[owner][operator]; - } - - /** - * @dev See {IERC721-transferFrom}. - */ - function transferFrom(address from, address to, uint256 tokenId) public virtual { - if (to == address(0)) { - revert ERC721InvalidReceiver(address(0)); - } - // Setting an "auth" arguments enables the `_isAuthorized` check which verifies that the token exists - // (from != 0). Therefore, it is not needed to verify that the return value is not 0 here. - address previousOwner = _update(to, tokenId, _msgSender()); - if (previousOwner != from) { - revert ERC721IncorrectOwner(from, tokenId, previousOwner); - } - } - - /** - * @dev See {IERC721-safeTransferFrom}. - */ - function safeTransferFrom(address from, address to, uint256 tokenId) public { - safeTransferFrom(from, to, tokenId, ""); - } - - /** - * @dev See {IERC721-safeTransferFrom}. - */ - function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual { - transferFrom(from, to, tokenId); - ERC721Utils.checkOnERC721Received(_msgSender(), from, to, tokenId, data); - } - - /** - * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist - * - * IMPORTANT: Any overrides to this function that add ownership of tokens not tracked by the - * core ERC-721 logic MUST be matched with the use of {_increaseBalance} to keep balances - * consistent with ownership. The invariant to preserve is 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`. - */ - function _ownerOf(uint256 tokenId) internal view virtual returns (address) { - return _owners[tokenId]; - } - - /** - * @dev Returns the approved address for `tokenId`. Returns 0 if `tokenId` is not minted. - */ - function _getApproved(uint256 tokenId) internal view virtual returns (address) { - return _tokenApprovals[tokenId]; - } - - /** - * @dev Returns whether `spender` is allowed to manage `owner`'s tokens, or `tokenId` in - * particular (ignoring whether it is owned by `owner`). - * - * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this - * assumption. - */ - function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool) { - return - spender != address(0) && - (owner == spender || isApprovedForAll(owner, spender) || _getApproved(tokenId) == spender); - } - - /** - * @dev Checks if `spender` can operate on `tokenId`, assuming the provided `owner` is the actual owner. - * Reverts if: - * - `spender` does not have approval from `owner` for `tokenId`. - * - `spender` does not have approval to manage all of `owner`'s assets. - * - * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this - * assumption. - */ - function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual { - if (!_isAuthorized(owner, spender, tokenId)) { - if (owner == address(0)) { - revert ERC721NonexistentToken(tokenId); - } else { - revert ERC721InsufficientApproval(spender, tokenId); - } - } - } - - /** - * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override. - * - * NOTE: the value is limited to type(uint128).max. This protect against _balance overflow. It is unrealistic that - * a uint256 would ever overflow from increments when these increments are bounded to uint128 values. - * - * WARNING: Increasing an account's balance using this function tends to be paired with an override of the - * {_ownerOf} function to resolve the ownership of the corresponding tokens so that balances and ownership - * remain consistent with one another. - */ - function _increaseBalance(address account, uint128 value) internal virtual { - unchecked { - _balances[account] += value; - } - } - - /** - * @dev Transfers `tokenId` from its current owner to `to`, or alternatively mints (or burns) if the current owner - * (or `to`) is the zero address. Returns the owner of the `tokenId` before the update. - * - * The `auth` argument is optional. If the value passed is non 0, then this function will check that - * `auth` is either the owner of the token, or approved to operate on the token (by the owner). - * - * Emits a {Transfer} event. - * - * NOTE: If overriding this function in a way that tracks balances, see also {_increaseBalance}. - */ - function _update(address to, uint256 tokenId, address auth) internal virtual returns (address) { - address from = _ownerOf(tokenId); - - // Perform (optional) operator check - if (auth != address(0)) { - _checkAuthorized(from, auth, tokenId); - } - - // Execute the update - if (from != address(0)) { - // Clear approval. No need to re-authorize or emit the Approval event - _approve(address(0), tokenId, address(0), false); - - unchecked { - _balances[from] -= 1; - } - } - - if (to != address(0)) { - unchecked { - _balances[to] += 1; - } - } - - _owners[tokenId] = to; - - emit Transfer(from, to, tokenId); - - return from; - } - - /** - * @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 { - if (to == address(0)) { - revert ERC721InvalidReceiver(address(0)); - } - address previousOwner = _update(to, tokenId, address(0)); - if (previousOwner != address(0)) { - revert ERC721InvalidSender(address(0)); - } - } - - /** - * @dev Mints `tokenId`, transfers it to `to` and checks for `to` acceptance. - * - * 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 { - _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); - ERC721Utils.checkOnERC721Received(_msgSender(), address(0), to, tokenId, data); - } - - /** - * @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 { - address previousOwner = _update(address(0), tokenId, address(0)); - if (previousOwner == address(0)) { - revert ERC721NonexistentToken(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 { - if (to == address(0)) { - revert ERC721InvalidReceiver(address(0)); - } - address previousOwner = _update(to, tokenId, address(0)); - if (previousOwner == address(0)) { - revert ERC721NonexistentToken(tokenId); - } else if (previousOwner != from) { - revert ERC721IncorrectOwner(from, tokenId, previousOwner); - } - } - - /** - * @dev Safely transfers `tokenId` token from `from` to `to`, checking that contract recipients - * are aware of the ERC-721 standard 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 like {safeTransferFrom} in the sense that it invokes - * {IERC721Receiver-onERC721Received} on the receiver, and can be used to e.g. - * implement alternative mechanisms to perform token transfer, such as signature-based. - * - * Requirements: - * - * - `tokenId` token must exist and be owned by `from`. - * - `to` cannot be the zero address. - * - `from` cannot be the zero address. - * - 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) internal { - _safeTransfer(from, to, tokenId, ""); - } - - /** - * @dev Same as {xref-ERC721-_safeTransfer-address-address-uint256-}[`_safeTransfer`], with an additional `data` parameter which is - * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. - */ - function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual { - _transfer(from, to, tokenId); - ERC721Utils.checkOnERC721Received(_msgSender(), from, to, tokenId, data); - } - - /** - * @dev Approve `to` to operate on `tokenId` - * - * The `auth` argument is optional. If the value passed is non 0, then this function will check that `auth` is - * either the owner of the token, or approved to operate on all tokens held by this owner. - * - * Emits an {Approval} event. - * - * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. - */ - function _approve(address to, uint256 tokenId, address auth) internal { - _approve(to, tokenId, auth, true); - } - - /** - * @dev Variant of `_approve` with an optional flag to enable or disable the {Approval} event. The event is not - * emitted in the context of transfers. - */ - function _approve(address to, uint256 tokenId, address auth, bool emitEvent) internal virtual { - // Avoid reading the owner unless necessary - if (emitEvent || auth != address(0)) { - address owner = _requireOwned(tokenId); - - // We do not use _isAuthorized because single-token approvals should not be able to call approve - if (auth != address(0) && owner != auth && !isApprovedForAll(owner, auth)) { - revert ERC721InvalidApprover(auth); - } - - if (emitEvent) { - emit Approval(owner, to, tokenId); - } - } - - _tokenApprovals[tokenId] = to; - } - - /** - * @dev Approve `operator` to operate on all of `owner` tokens - * - * Requirements: - * - operator can't be the address zero. - * - * Emits an {ApprovalForAll} event. - */ - function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { - if (operator == address(0)) { - revert ERC721InvalidOperator(operator); - } - _operatorApprovals[owner][operator] = approved; - emit ApprovalForAll(owner, operator, approved); - } - - /** - * @dev Reverts if the `tokenId` doesn't have a current owner (it hasn't been minted, or it has been burned). - * Returns the owner. - * - * Overrides to ownership logic should be done to {_ownerOf}. - */ - function _requireOwned(uint256 tokenId) internal view returns (address) { - address owner = _ownerOf(tokenId); - if (owner == address(0)) { - revert ERC721NonexistentToken(tokenId); - } - return owner; - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol b/lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol deleted file mode 100644 index d6ab6a4..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol +++ /dev/null @@ -1,135 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol) - -pragma solidity ^0.8.20; - -import {IERC165} from "../../utils/introspection/IERC165.sol"; - -/** - * @dev Required interface of an ERC-721 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 ERC-721 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 ERC-721 - * 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 address zero. - * - * 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/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol b/lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol deleted file mode 100644 index a53d077..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721Receiver.sol) - -pragma solidity ^0.8.20; - -/** - * @title ERC-721 token receiver interface - * @dev Interface for any contract that wants to support safeTransfers - * from ERC-721 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/openzeppelin-contracts/contracts/token/ERC721/README.adoc b/lib/openzeppelin-contracts/contracts/token/ERC721/README.adoc deleted file mode 100644 index 0f87916..0000000 --- a/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[ERC-721 Non-Fungible Token Standard]. - -TIP: For a walk through on how to create an ERC-721 token read our xref:ROOT:erc721.adoc[ERC-721 guide]. - -The ERC 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[ERC-2309] for minting batchs of tokens during construction, in accordance with ERC-721. -* {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 ERC-2981. -* {ERC721Pausable}: A primitive to pause contract operation. -* {ERC721Burnable}: A way for token holders to burn their own tokens. -* {ERC721Wrapper}: Wrapper to create an ERC-721 backed by another ERC-721, with deposit and withdraw methods. Useful in conjunction with {ERC721Votes}. - -NOTE: This core set of contracts is designed to be unopinionated, allowing developers to access the internal functions in ERC-721 (such as <>) and expose them as external functions in the way they prefer. - -== Core - -{{IERC721}} - -{{IERC721Metadata}} - -{{IERC721Enumerable}} - -{{ERC721}} - -{{ERC721Enumerable}} - -{{IERC721Receiver}} - -== Extensions - -{{ERC721Pausable}} - -{{ERC721Burnable}} - -{{ERC721Consecutive}} - -{{ERC721URIStorage}} - -{{ERC721Votes}} - -{{ERC721Royalty}} - -{{ERC721Wrapper}} - -== Utilities - -{{ERC721Holder}} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Burnable.sol b/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Burnable.sol deleted file mode 100644 index 65cfc74..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Burnable.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/ERC721Burnable.sol) - -pragma solidity ^0.8.20; - -import {ERC721} from "../ERC721.sol"; -import {Context} from "../../../utils/Context.sol"; - -/** - * @title ERC-721 Burnable Token - * @dev ERC-721 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 { - // Setting an "auth" arguments enables the `_isAuthorized` check which verifies that the token exists - // (from != 0). Therefore, it is not needed to verify that the return value is not 0 here. - _update(address(0), tokenId, _msgSender()); - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Consecutive.sol b/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Consecutive.sol deleted file mode 100644 index 8508a79..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Consecutive.sol +++ /dev/null @@ -1,176 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/ERC721Consecutive.sol) - -pragma solidity ^0.8.20; - -import {ERC721} from "../ERC721.sol"; -import {IERC2309} from "../../../interfaces/IERC2309.sol"; -import {BitMaps} from "../../../utils/structs/BitMaps.sol"; -import {Checkpoints} from "../../../utils/structs/Checkpoints.sol"; - -/** - * @dev Implementation of the ERC-2309 "Consecutive Transfer Extension" as defined in - * https://eips.ethereum.org/EIPS/eip-2309[ERC-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 does not call the {_update} function for tokens minted in batch. Any logic added to this - * function through overrides will not be triggered when token are minted in batch. You may want to also override - * {_increaseBalance} or {_mintConsecutive} to account for these mints. - * - * IMPORTANT: When overriding {_mintConsecutive}, be careful about call ordering. {ownerOf} may return invalid - * values during the {_mintConsecutive} execution if the super call is not called first. To be safe, execute the - * super call before your custom logic. - */ -abstract contract ERC721Consecutive is IERC2309, ERC721 { - using BitMaps for BitMaps.BitMap; - using Checkpoints for Checkpoints.Trace160; - - Checkpoints.Trace160 private _sequentialOwnership; - BitMaps.BitMap private _sequentialBurn; - - /** - * @dev Batch mint is restricted to the constructor. - * Any batch mint not emitting the {IERC721-Transfer} event outside of the constructor - * is non ERC-721 compliant. - */ - error ERC721ForbiddenBatchMint(); - - /** - * @dev Exceeds the max amount of mints per batch. - */ - error ERC721ExceededMaxBatchMint(uint256 batchSize, uint256 maxBatch); - - /** - * @dev Individual minting is not allowed. - */ - error ERC721ForbiddenMint(); - - /** - * @dev Batch burn is not supported. - */ - error ERC721ForbiddenBatchBurn(); - - /** - * @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 || tokenId < _firstConsecutiveId()) { - 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 ERC-721 compliant as long as it is done inside 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 next = _nextConsecutiveId(); - - // minting a batch of size 0 is a no-op - if (batchSize > 0) { - if (address(this).code.length > 0) { - revert ERC721ForbiddenBatchMint(); - } - if (to == address(0)) { - revert ERC721InvalidReceiver(address(0)); - } - - uint256 maxBatchSize = _maxBatchSize(); - if (batchSize > maxBatchSize) { - revert ERC721ExceededMaxBatchMint(batchSize, maxBatchSize); - } - - // push an ownership checkpoint & emit event - uint96 last = next + 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`. - _increaseBalance(to, batchSize); - - emit ConsecutiveTransfer(next, last, address(0), to); - } - - return next; - } - - /** - * @dev See {ERC721-_update}. Override version that restricts normal minting to after construction. - * - * WARNING: Using {ERC721Consecutive} prevents minting during construction in favor of {_mintConsecutive}. - * After construction, {_mintConsecutive} is no longer available and minting through {_update} becomes available. - */ - function _update(address to, uint256 tokenId, address auth) internal virtual override returns (address) { - address previousOwner = super._update(to, tokenId, auth); - - // only mint after construction - if (previousOwner == address(0) && address(this).code.length == 0) { - revert ERC721ForbiddenMint(); - } - - // record burn - if ( - to == address(0) && // if we burn - tokenId < _nextConsecutiveId() && // and the tokenId was minted in a batch - !_sequentialBurn.get(tokenId) // and the token was never marked as burnt - ) { - _sequentialBurn.set(tokenId); - } - - return previousOwner; - } - - /** - * @dev Used to offset the first token id in {_nextConsecutiveId} - */ - function _firstConsecutiveId() internal view virtual returns (uint96) { - return 0; - } - - /** - * @dev Returns the next tokenId to mint using {_mintConsecutive}. It will return {_firstConsecutiveId} - * if no consecutive tokenId has been minted before. - */ - function _nextConsecutiveId() private view returns (uint96) { - (bool exists, uint96 latestId, ) = _sequentialOwnership.latestCheckpoint(); - return exists ? latestId + 1 : _firstConsecutiveId(); - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Enumerable.sol b/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Enumerable.sol deleted file mode 100644 index 1bd4375..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Enumerable.sol +++ /dev/null @@ -1,174 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/ERC721Enumerable.sol) - -pragma solidity ^0.8.20; - -import {ERC721} from "../ERC721.sol"; -import {IERC721Enumerable} from "./IERC721Enumerable.sol"; -import {IERC165} from "../../../utils/introspection/ERC165.sol"; - -/** - * @dev This implements an optional extension of {ERC721} defined in the ERC that adds enumerability - * of all the token ids in the contract as well as all token ids owned by each account. - * - * CAUTION: {ERC721} extensions that implement custom `balanceOf` logic, such as {ERC721Consecutive}, - * interfere with enumerability and should not be used together with {ERC721Enumerable}. - */ -abstract contract ERC721Enumerable is ERC721, IERC721Enumerable { - mapping(address owner => mapping(uint256 index => uint256)) private _ownedTokens; - mapping(uint256 tokenId => uint256) private _ownedTokensIndex; - - uint256[] private _allTokens; - mapping(uint256 tokenId => uint256) private _allTokensIndex; - - /** - * @dev An `owner`'s token query was out of bounds for `index`. - * - * NOTE: The owner being `address(0)` indicates a global out of bounds index. - */ - error ERC721OutOfBoundsIndex(address owner, uint256 index); - - /** - * @dev Batch mint is not allowed. - */ - error ERC721EnumerableForbiddenBatchMint(); - - /** - * @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 returns (uint256) { - if (index >= balanceOf(owner)) { - revert ERC721OutOfBoundsIndex(owner, index); - } - return _ownedTokens[owner][index]; - } - - /** - * @dev See {IERC721Enumerable-totalSupply}. - */ - function totalSupply() public view virtual returns (uint256) { - return _allTokens.length; - } - - /** - * @dev See {IERC721Enumerable-tokenByIndex}. - */ - function tokenByIndex(uint256 index) public view virtual returns (uint256) { - if (index >= totalSupply()) { - revert ERC721OutOfBoundsIndex(address(0), index); - } - return _allTokens[index]; - } - - /** - * @dev See {ERC721-_update}. - */ - function _update(address to, uint256 tokenId, address auth) internal virtual override returns (address) { - address previousOwner = super._update(to, tokenId, auth); - - if (previousOwner == address(0)) { - _addTokenToAllTokensEnumeration(tokenId); - } else if (previousOwner != to) { - _removeTokenFromOwnerEnumeration(previousOwner, tokenId); - } - if (to == address(0)) { - _removeTokenFromAllTokensEnumeration(tokenId); - } else if (previousOwner != to) { - _addTokenToOwnerEnumeration(to, tokenId); - } - - return previousOwner; - } - - /** - * @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 = balanceOf(to) - 1; - _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 = balanceOf(from); - uint256 tokenIndex = _ownedTokensIndex[tokenId]; - - mapping(uint256 index => uint256) storage _ownedTokensByOwner = _ownedTokens[from]; - - // When the token to delete is the last token, the swap operation is unnecessary - if (tokenIndex != lastTokenIndex) { - uint256 lastTokenId = _ownedTokensByOwner[lastTokenIndex]; - - _ownedTokensByOwner[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 _ownedTokensByOwner[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(); - } - - /** - * See {ERC721-_increaseBalance}. We need that to account tokens that were minted in batch - */ - function _increaseBalance(address account, uint128 amount) internal virtual override { - if (amount > 0) { - revert ERC721EnumerableForbiddenBatchMint(); - } - super._increaseBalance(account, amount); - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Pausable.sol b/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Pausable.sol deleted file mode 100644 index 81619c7..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Pausable.sol +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/ERC721Pausable.sol) - -pragma solidity ^0.8.20; - -import {ERC721} from "../ERC721.sol"; -import {Pausable} from "../../../utils/Pausable.sol"; - -/** - * @dev ERC-721 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 pause mechanism of the contract unreachable, and thus unusable. - */ -abstract contract ERC721Pausable is ERC721, Pausable { - /** - * @dev See {ERC721-_update}. - * - * Requirements: - * - * - the contract must not be paused. - */ - function _update( - address to, - uint256 tokenId, - address auth - ) internal virtual override whenNotPaused returns (address) { - return super._update(to, tokenId, auth); - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Royalty.sol b/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Royalty.sol deleted file mode 100644 index 1e0b25a..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Royalty.sol +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/ERC721Royalty.sol) - -pragma solidity ^0.8.20; - -import {ERC721} from "../ERC721.sol"; -import {ERC2981} from "../../common/ERC2981.sol"; - -/** - * @dev Extension of ERC-721 with the ERC-2981 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 ERC. Marketplaces are expected to - * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported. - */ -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); - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721URIStorage.sol b/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721URIStorage.sol deleted file mode 100644 index 562f815..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721URIStorage.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/ERC721URIStorage.sol) - -pragma solidity ^0.8.20; - -import {ERC721} from "../ERC721.sol"; -import {Strings} from "../../../utils/Strings.sol"; -import {IERC4906} from "../../../interfaces/IERC4906.sol"; -import {IERC165} from "../../../interfaces/IERC165.sol"; - -/** - * @dev ERC-721 token with storage based token URI management. - */ -abstract contract ERC721URIStorage is IERC4906, ERC721 { - using Strings for uint256; - - // Interface ID as defined in ERC-4906. This does not correspond to a traditional interface ID as ERC-4906 only - // defines events and does not include any external function. - bytes4 private constant ERC4906_INTERFACE_ID = bytes4(0x49064906); - - // Optional mapping for token URIs - mapping(uint256 tokenId => string) private _tokenURIs; - - /** - * @dev See {IERC165-supportsInterface} - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, IERC165) returns (bool) { - return interfaceId == ERC4906_INTERFACE_ID || super.supportsInterface(interfaceId); - } - - /** - * @dev See {IERC721Metadata-tokenURI}. - */ - function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { - _requireOwned(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 string.concat). - if (bytes(_tokenURI).length > 0) { - return string.concat(base, _tokenURI); - } - - return super.tokenURI(tokenId); - } - - /** - * @dev Sets `_tokenURI` as the tokenURI of `tokenId`. - * - * Emits {MetadataUpdate}. - */ - function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual { - _tokenURIs[tokenId] = _tokenURI; - emit MetadataUpdate(tokenId); - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Votes.sol b/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Votes.sol deleted file mode 100644 index 4962cb0..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Votes.sol +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/ERC721Votes.sol) - -pragma solidity ^0.8.20; - -import {ERC721} from "../ERC721.sol"; -import {Votes} from "../../../governance/utils/Votes.sol"; - -/** - * @dev Extension of ERC-721 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. - */ -abstract contract ERC721Votes is ERC721, Votes { - /** - * @dev See {ERC721-_update}. Adjusts votes when tokens are transferred. - * - * Emits a {IVotes-DelegateVotesChanged} event. - */ - function _update(address to, uint256 tokenId, address auth) internal virtual override returns (address) { - address previousOwner = super._update(to, tokenId, auth); - - _transferVotingUnits(previousOwner, to, 1); - - return previousOwner; - } - - /** - * @dev Returns the balance of `account`. - * - * WARNING: Overriding this function will likely result in incorrect vote tracking. - */ - function _getVotingUnits(address account) internal view virtual override returns (uint256) { - return balanceOf(account); - } - - /** - * @dev See {ERC721-_increaseBalance}. We need that to account tokens that were minted in batch. - */ - function _increaseBalance(address account, uint128 amount) internal virtual override { - super._increaseBalance(account, amount); - _transferVotingUnits(address(0), account, amount); - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Wrapper.sol b/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Wrapper.sol deleted file mode 100644 index 0a8acac..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Wrapper.sol +++ /dev/null @@ -1,102 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/ERC721Wrapper.sol) - -pragma solidity ^0.8.20; - -import {IERC721, ERC721} from "../ERC721.sol"; -import {IERC721Receiver} from "../IERC721Receiver.sol"; - -/** - * @dev Extension of the ERC-721 token contract to support token wrapping. - * - * Users can deposit and withdraw an "underlying token" and receive a "wrapped token" with a matching tokenId. This is - * useful in conjunction with other modules. For example, combining this wrapping mechanism with {ERC721Votes} will allow - * the wrapping of an existing "basic" ERC-721 into a governance token. - */ -abstract contract ERC721Wrapper is ERC721, IERC721Receiver { - IERC721 private immutable _underlying; - - /** - * @dev The received ERC-721 token couldn't be wrapped. - */ - error ERC721UnsupportedToken(address token); - - constructor(IERC721 underlyingToken) { - _underlying = underlyingToken; - } - - /** - * @dev Allow a user to deposit underlying tokens and mint the corresponding tokenIds. - */ - function depositFor(address account, uint256[] memory tokenIds) public virtual returns (bool) { - uint256 length = tokenIds.length; - for (uint256 i = 0; i < length; ++i) { - uint256 tokenId = tokenIds[i]; - - // This is an "unsafe" transfer that doesn't call any hook on the receiver. With underlying() being trusted - // (by design of this contract) and no other contracts expected to be called from there, we are safe. - // slither-disable-next-line reentrancy-no-eth - underlying().transferFrom(_msgSender(), address(this), tokenId); - _safeMint(account, tokenId); - } - - return true; - } - - /** - * @dev Allow a user to burn wrapped tokens and withdraw the corresponding tokenIds of the underlying tokens. - */ - function withdrawTo(address account, uint256[] memory tokenIds) public virtual returns (bool) { - uint256 length = tokenIds.length; - for (uint256 i = 0; i < length; ++i) { - uint256 tokenId = tokenIds[i]; - // Setting an "auth" arguments enables the `_isAuthorized` check which verifies that the token exists - // (from != 0). Therefore, it is not needed to verify that the return value is not 0 here. - _update(address(0), tokenId, _msgSender()); - // Checks were already performed at this point, and there's no way to retake ownership or approval from - // the wrapped tokenId after this point, so it's safe to remove the reentrancy check for the next line. - // slither-disable-next-line reentrancy-no-eth - underlying().safeTransferFrom(address(this), account, tokenId); - } - - return true; - } - - /** - * @dev Overrides {IERC721Receiver-onERC721Received} to allow minting on direct ERC-721 transfers to - * this contract. - * - * In case there's data attached, it validates that the operator is this contract, so only trusted data - * is accepted from {depositFor}. - * - * WARNING: Doesn't work with unsafe transfers (eg. {IERC721-transferFrom}). Use {ERC721Wrapper-_recover} - * for recovering in that scenario. - */ - function onERC721Received(address, address from, uint256 tokenId, bytes memory) public virtual returns (bytes4) { - if (address(underlying()) != _msgSender()) { - revert ERC721UnsupportedToken(_msgSender()); - } - _safeMint(from, tokenId); - return IERC721Receiver.onERC721Received.selector; - } - - /** - * @dev Mint a wrapped token to cover any underlyingToken that would have been transferred by mistake. Internal - * function that can be exposed with access control if desired. - */ - function _recover(address account, uint256 tokenId) internal virtual returns (uint256) { - address owner = underlying().ownerOf(tokenId); - if (owner != address(this)) { - revert ERC721IncorrectOwner(address(this), tokenId, owner); - } - _safeMint(account, tokenId); - return tokenId; - } - - /** - * @dev Returns the underlying token. - */ - function underlying() public view virtual returns (IERC721) { - return _underlying; - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Enumerable.sol b/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Enumerable.sol deleted file mode 100644 index 7a09cc6..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Enumerable.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Enumerable.sol) - -pragma solidity ^0.8.20; - -import {IERC721} from "../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/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol b/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol deleted file mode 100644 index e9e00fa..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol) - -pragma solidity ^0.8.20; - -import {IERC721} from "../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/openzeppelin-contracts/contracts/token/ERC721/utils/ERC721Holder.sol b/lib/openzeppelin-contracts/contracts/token/ERC721/utils/ERC721Holder.sol deleted file mode 100644 index 6bb23ac..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC721/utils/ERC721Holder.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/utils/ERC721Holder.sol) - -pragma solidity ^0.8.20; - -import {IERC721Receiver} from "../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}. - */ -abstract contract ERC721Holder is IERC721Receiver { - /** - * @dev See {IERC721Receiver-onERC721Received}. - * - * Always returns `IERC721Receiver.onERC721Received.selector`. - */ - function onERC721Received(address, address, uint256, bytes memory) public virtual returns (bytes4) { - return this.onERC721Received.selector; - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/ERC721/utils/ERC721Utils.sol b/lib/openzeppelin-contracts/contracts/token/ERC721/utils/ERC721Utils.sol deleted file mode 100644 index 43dd107..0000000 --- a/lib/openzeppelin-contracts/contracts/token/ERC721/utils/ERC721Utils.sol +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {IERC721Receiver} from "../IERC721Receiver.sol"; -import {IERC721Errors} from "../../../interfaces/draft-IERC6093.sol"; - -/** - * @dev Library that provide common ERC-721 utility functions. - * - * See https://eips.ethereum.org/EIPS/eip-721[ERC-721]. - */ -library ERC721Utils { - /** - * @dev Performs an acceptance check for the provided `operator` by calling {IERC721-onERC721Received} - * on the `to` address. The `operator` is generally the address that initiated the token transfer (i.e. `msg.sender`). - * - * The acceptance call is not executed and treated as a no-op if the target address doesn't contain code (i.e. an EOA). - * Otherwise, the recipient must implement {IERC721Receiver-onERC721Received} and return the acceptance magic value to accept - * the transfer. - */ - function checkOnERC721Received( - address operator, - address from, - address to, - uint256 tokenId, - bytes memory data - ) internal { - if (to.code.length > 0) { - try IERC721Receiver(to).onERC721Received(operator, from, tokenId, data) returns (bytes4 retval) { - if (retval != IERC721Receiver.onERC721Received.selector) { - // Token rejected - revert IERC721Errors.ERC721InvalidReceiver(to); - } - } catch (bytes memory reason) { - if (reason.length == 0) { - // non-IERC721Receiver implementer - revert IERC721Errors.ERC721InvalidReceiver(to); - } else { - /// @solidity memory-safe-assembly - assembly { - revert(add(32, reason), mload(reason)) - } - } - } - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/token/common/ERC2981.sol b/lib/openzeppelin-contracts/contracts/token/common/ERC2981.sol deleted file mode 100644 index 70e8f46..0000000 --- a/lib/openzeppelin-contracts/contracts/token/common/ERC2981.sol +++ /dev/null @@ -1,140 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (token/common/ERC2981.sol) - -pragma solidity ^0.8.20; - -import {IERC2981} from "../../interfaces/IERC2981.sol"; -import {IERC165, ERC165} from "../../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 ERC. Marketplaces are expected to - * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported. - */ -abstract contract ERC2981 is IERC2981, ERC165 { - struct RoyaltyInfo { - address receiver; - uint96 royaltyFraction; - } - - RoyaltyInfo private _defaultRoyaltyInfo; - mapping(uint256 tokenId => RoyaltyInfo) private _tokenRoyaltyInfo; - - /** - * @dev The default royalty set is invalid (eg. (numerator / denominator) >= 1). - */ - error ERC2981InvalidDefaultRoyalty(uint256 numerator, uint256 denominator); - - /** - * @dev The default royalty receiver is invalid. - */ - error ERC2981InvalidDefaultRoyaltyReceiver(address receiver); - - /** - * @dev The royalty set for an specific `tokenId` is invalid (eg. (numerator / denominator) >= 1). - */ - error ERC2981InvalidTokenRoyalty(uint256 tokenId, uint256 numerator, uint256 denominator); - - /** - * @dev The royalty receiver for `tokenId` is invalid. - */ - error ERC2981InvalidTokenRoyaltyReceiver(uint256 tokenId, address receiver); - - /** - * @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 returns (address, uint256) { - RoyaltyInfo storage _royaltyInfo = _tokenRoyaltyInfo[tokenId]; - address royaltyReceiver = _royaltyInfo.receiver; - uint96 royaltyFraction = _royaltyInfo.royaltyFraction; - - if (royaltyReceiver == address(0)) { - royaltyReceiver = _defaultRoyaltyInfo.receiver; - royaltyFraction = _defaultRoyaltyInfo.royaltyFraction; - } - - uint256 royaltyAmount = (salePrice * royaltyFraction) / _feeDenominator(); - - return (royaltyReceiver, 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 { - uint256 denominator = _feeDenominator(); - if (feeNumerator > denominator) { - // Royalty fee will exceed the sale price - revert ERC2981InvalidDefaultRoyalty(feeNumerator, denominator); - } - if (receiver == address(0)) { - revert ERC2981InvalidDefaultRoyaltyReceiver(address(0)); - } - - _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 { - uint256 denominator = _feeDenominator(); - if (feeNumerator > denominator) { - // Royalty fee will exceed the sale price - revert ERC2981InvalidTokenRoyalty(tokenId, feeNumerator, denominator); - } - if (receiver == address(0)) { - revert ERC2981InvalidTokenRoyaltyReceiver(tokenId, address(0)); - } - - _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/openzeppelin-contracts/contracts/token/common/README.adoc b/lib/openzeppelin-contracts/contracts/token/common/README.adoc deleted file mode 100644 index a70d90d..0000000 --- a/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 ERC-721 and ERC-1155. -** For ERC-721 consider {ERC721Royalty} which clears the royalty information from storage on burn. - -== Contracts - -{{ERC2981}} diff --git a/lib/openzeppelin-contracts/contracts/utils/Address.sol b/lib/openzeppelin-contracts/contracts/utils/Address.sol deleted file mode 100644 index 53a3c44..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/Address.sol +++ /dev/null @@ -1,151 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol) - -pragma solidity ^0.8.20; - -import {Errors} from "./Errors.sol"; - -/** - * @dev Collection of functions related to the address type - */ -library Address { - /** - * @dev There's no code at `target` (it is not a contract). - */ - error AddressEmptyCode(address target); - - /** - * @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://consensys.net/diligence/blog/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.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. - */ - function sendValue(address payable recipient, uint256 amount) internal { - if (address(this).balance < amount) { - revert Errors.InsufficientBalance(address(this).balance, amount); - } - - (bool success, ) = recipient.call{value: amount}(""); - if (!success) { - revert Errors.FailedCall(); - } - } - - /** - * @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 or custom error, it is bubbled - * up by this function (like regular Solidity function calls). However, if - * the call reverted with no returned reason, this function reverts with a - * {Errors.FailedCall} error. - * - * 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. - */ - function functionCall(address target, bytes memory data) internal returns (bytes memory) { - return functionCallWithValue(target, data, 0); - } - - /** - * @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`. - */ - function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { - if (address(this).balance < value) { - revert Errors.InsufficientBalance(address(this).balance, value); - } - (bool success, bytes memory returndata) = target.call{value: value}(data); - return verifyCallResultFromTarget(target, success, returndata); - } - - /** - * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], - * but performing a static call. - */ - function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { - (bool success, bytes memory returndata) = target.staticcall(data); - return verifyCallResultFromTarget(target, success, returndata); - } - - /** - * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], - * but performing a delegate call. - */ - function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { - (bool success, bytes memory returndata) = target.delegatecall(data); - return verifyCallResultFromTarget(target, success, returndata); - } - - /** - * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target - * was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case - * of an unsuccessful call. - */ - function verifyCallResultFromTarget( - address target, - bool success, - bytes memory returndata - ) internal view returns (bytes memory) { - if (!success) { - _revert(returndata); - } else { - // only check if target is a contract if the call was successful and the return data is empty - // otherwise we already know that it was a contract - if (returndata.length == 0 && target.code.length == 0) { - revert AddressEmptyCode(target); - } - return returndata; - } - } - - /** - * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the - * revert reason or with a default {Errors.FailedCall} error. - */ - function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { - if (!success) { - _revert(returndata); - } else { - return returndata; - } - } - - /** - * @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}. - */ - function _revert(bytes memory returndata) 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 Errors.FailedCall(); - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/Arrays.sol b/lib/openzeppelin-contracts/contracts/utils/Arrays.sol deleted file mode 100644 index d67ae90..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/Arrays.sol +++ /dev/null @@ -1,487 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/Arrays.sol) -// This file was procedurally generated from scripts/generate/templates/Arrays.js. - -pragma solidity ^0.8.20; - -import {SlotDerivation} from "./SlotDerivation.sol"; -import {StorageSlot} from "./StorageSlot.sol"; -import {Math} from "./math/Math.sol"; - -/** - * @dev Collection of functions related to array types. - */ -library Arrays { - using SlotDerivation for bytes32; - using StorageSlot for bytes32; - - /** - * @dev Sort an array of bytes32 (in memory) following the provided comparator function. - * - * This function does the sorting "in place", meaning that it overrides the input. The object is returned for - * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array. - * - * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the - * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful - * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may - * consume more gas than is available in a block, leading to potential DoS. - */ - function sort( - bytes32[] memory array, - function(bytes32, bytes32) pure returns (bool) comp - ) internal pure returns (bytes32[] memory) { - _quickSort(_begin(array), _end(array), comp); - return array; - } - - /** - * @dev Variant of {sort} that sorts an array of bytes32 in increasing order. - */ - function sort(bytes32[] memory array) internal pure returns (bytes32[] memory) { - sort(array, _defaultComp); - return array; - } - - /** - * @dev Sort an array of address (in memory) following the provided comparator function. - * - * This function does the sorting "in place", meaning that it overrides the input. The object is returned for - * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array. - * - * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the - * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful - * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may - * consume more gas than is available in a block, leading to potential DoS. - */ - function sort( - address[] memory array, - function(address, address) pure returns (bool) comp - ) internal pure returns (address[] memory) { - sort(_castToBytes32Array(array), _castToBytes32Comp(comp)); - return array; - } - - /** - * @dev Variant of {sort} that sorts an array of address in increasing order. - */ - function sort(address[] memory array) internal pure returns (address[] memory) { - sort(_castToBytes32Array(array), _defaultComp); - return array; - } - - /** - * @dev Sort an array of uint256 (in memory) following the provided comparator function. - * - * This function does the sorting "in place", meaning that it overrides the input. The object is returned for - * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array. - * - * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the - * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful - * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may - * consume more gas than is available in a block, leading to potential DoS. - */ - function sort( - uint256[] memory array, - function(uint256, uint256) pure returns (bool) comp - ) internal pure returns (uint256[] memory) { - sort(_castToBytes32Array(array), _castToBytes32Comp(comp)); - return array; - } - - /** - * @dev Variant of {sort} that sorts an array of uint256 in increasing order. - */ - function sort(uint256[] memory array) internal pure returns (uint256[] memory) { - sort(_castToBytes32Array(array), _defaultComp); - return array; - } - - /** - * @dev Performs a quick sort of a segment of memory. The segment sorted starts at `begin` (inclusive), and stops - * at end (exclusive). Sorting follows the `comp` comparator. - * - * Invariant: `begin <= end`. This is the case when initially called by {sort} and is preserved in subcalls. - * - * IMPORTANT: Memory locations between `begin` and `end` are not validated/zeroed. This function should - * be used only if the limits are within a memory array. - */ - function _quickSort(uint256 begin, uint256 end, function(bytes32, bytes32) pure returns (bool) comp) private pure { - unchecked { - if (end - begin < 0x40) return; - - // Use first element as pivot - bytes32 pivot = _mload(begin); - // Position where the pivot should be at the end of the loop - uint256 pos = begin; - - for (uint256 it = begin + 0x20; it < end; it += 0x20) { - if (comp(_mload(it), pivot)) { - // If the value stored at the iterator's position comes before the pivot, we increment the - // position of the pivot and move the value there. - pos += 0x20; - _swap(pos, it); - } - } - - _swap(begin, pos); // Swap pivot into place - _quickSort(begin, pos, comp); // Sort the left side of the pivot - _quickSort(pos + 0x20, end, comp); // Sort the right side of the pivot - } - } - - /** - * @dev Pointer to the memory location of the first element of `array`. - */ - function _begin(bytes32[] memory array) private pure returns (uint256 ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr := add(array, 0x20) - } - } - - /** - * @dev Pointer to the memory location of the first memory word (32bytes) after `array`. This is the memory word - * that comes just after the last element of the array. - */ - function _end(bytes32[] memory array) private pure returns (uint256 ptr) { - unchecked { - return _begin(array) + array.length * 0x20; - } - } - - /** - * @dev Load memory word (as a bytes32) at location `ptr`. - */ - function _mload(uint256 ptr) private pure returns (bytes32 value) { - assembly { - value := mload(ptr) - } - } - - /** - * @dev Swaps the elements memory location `ptr1` and `ptr2`. - */ - function _swap(uint256 ptr1, uint256 ptr2) private pure { - assembly { - let value1 := mload(ptr1) - let value2 := mload(ptr2) - mstore(ptr1, value2) - mstore(ptr2, value1) - } - } - - /// @dev Comparator for sorting arrays in increasing order. - function _defaultComp(bytes32 a, bytes32 b) private pure returns (bool) { - return a < b; - } - - /// @dev Helper: low level cast address memory array to uint256 memory array - function _castToBytes32Array(address[] memory input) private pure returns (bytes32[] memory output) { - assembly { - output := input - } - } - - /// @dev Helper: low level cast uint256 memory array to uint256 memory array - function _castToBytes32Array(uint256[] memory input) private pure returns (bytes32[] memory output) { - assembly { - output := input - } - } - - /// @dev Helper: low level cast address comp function to bytes32 comp function - function _castToBytes32Comp( - function(address, address) pure returns (bool) input - ) private pure returns (function(bytes32, bytes32) pure returns (bool) output) { - assembly { - output := input - } - } - - /// @dev Helper: low level cast uint256 comp function to bytes32 comp function - function _castToBytes32Comp( - function(uint256, uint256) pure returns (bool) input - ) private pure returns (function(bytes32, bytes32) pure returns (bool) output) { - assembly { - output := input - } - } - - /** - * @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). - * - * NOTE: The `array` is expected to be sorted in ascending order, and to - * contain no repeated elements. - * - * IMPORTANT: Deprecated. This implementation behaves as {lowerBound} but lacks - * support for repeated elements in the array. The {lowerBound} function should - * be used instead. - */ - function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) { - uint256 low = 0; - uint256 high = array.length; - - if (high == 0) { - return 0; - } - - 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 towards zero (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 Searches an `array` sorted in ascending order and returns the first - * index that contains a value greater or equal than `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). - * - * See C++'s https://en.cppreference.com/w/cpp/algorithm/lower_bound[lower_bound]. - */ - function lowerBound(uint256[] storage array, uint256 element) internal view returns (uint256) { - uint256 low = 0; - uint256 high = array.length; - - if (high == 0) { - return 0; - } - - 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 towards zero (it does integer division with truncation). - if (unsafeAccess(array, mid).value < element) { - // this cannot overflow because mid < high - unchecked { - low = mid + 1; - } - } else { - high = mid; - } - } - - return low; - } - - /** - * @dev Searches an `array` sorted in ascending order and returns the first - * index that contains a value strictly greater than `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). - * - * See C++'s https://en.cppreference.com/w/cpp/algorithm/upper_bound[upper_bound]. - */ - function upperBound(uint256[] storage array, uint256 element) internal view returns (uint256) { - uint256 low = 0; - uint256 high = array.length; - - if (high == 0) { - return 0; - } - - 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 towards zero (it does integer division with truncation). - if (unsafeAccess(array, mid).value > element) { - high = mid; - } else { - // this cannot overflow because mid < high - unchecked { - low = mid + 1; - } - } - } - - return low; - } - - /** - * @dev Same as {lowerBound}, but with an array in memory. - */ - function lowerBoundMemory(uint256[] memory array, uint256 element) internal pure returns (uint256) { - uint256 low = 0; - uint256 high = array.length; - - if (high == 0) { - return 0; - } - - 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 towards zero (it does integer division with truncation). - if (unsafeMemoryAccess(array, mid) < element) { - // this cannot overflow because mid < high - unchecked { - low = mid + 1; - } - } else { - high = mid; - } - } - - return low; - } - - /** - * @dev Same as {upperBound}, but with an array in memory. - */ - function upperBoundMemory(uint256[] memory array, uint256 element) internal pure returns (uint256) { - uint256 low = 0; - uint256 high = array.length; - - if (high == 0) { - return 0; - } - - 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 towards zero (it does integer division with truncation). - if (unsafeMemoryAccess(array, mid) > element) { - high = mid; - } else { - // this cannot overflow because mid < high - unchecked { - low = mid + 1; - } - } - } - - 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 (StorageSlot.AddressSlot storage) { - bytes32 slot; - /// @solidity memory-safe-assembly - assembly { - slot := arr.slot - } - return slot.deriveArray().offset(pos).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 (StorageSlot.Bytes32Slot storage) { - bytes32 slot; - /// @solidity memory-safe-assembly - assembly { - slot := arr.slot - } - return slot.deriveArray().offset(pos).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 (StorageSlot.Uint256Slot storage) { - bytes32 slot; - /// @solidity memory-safe-assembly - assembly { - slot := arr.slot - } - return slot.deriveArray().offset(pos).getUint256Slot(); - } - - /** - * @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 unsafeMemoryAccess(address[] memory arr, uint256 pos) internal pure returns (address res) { - assembly { - res := mload(add(add(arr, 0x20), mul(pos, 0x20))) - } - } - - /** - * @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 unsafeMemoryAccess(bytes32[] memory arr, uint256 pos) internal pure returns (bytes32 res) { - assembly { - res := mload(add(add(arr, 0x20), mul(pos, 0x20))) - } - } - - /** - * @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 unsafeMemoryAccess(uint256[] memory arr, uint256 pos) internal pure returns (uint256 res) { - assembly { - res := mload(add(add(arr, 0x20), mul(pos, 0x20))) - } - } - - /** - * @dev Helper to set the length of an dynamic array. Directly writing to `.length` is forbidden. - * - * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased. - */ - function unsafeSetLength(address[] storage array, uint256 len) internal { - /// @solidity memory-safe-assembly - assembly { - sstore(array.slot, len) - } - } - - /** - * @dev Helper to set the length of an dynamic array. Directly writing to `.length` is forbidden. - * - * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased. - */ - function unsafeSetLength(bytes32[] storage array, uint256 len) internal { - /// @solidity memory-safe-assembly - assembly { - sstore(array.slot, len) - } - } - - /** - * @dev Helper to set the length of an dynamic array. Directly writing to `.length` is forbidden. - * - * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased. - */ - function unsafeSetLength(uint256[] storage array, uint256 len) internal { - /// @solidity memory-safe-assembly - assembly { - sstore(array.slot, len) - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/Base64.sol b/lib/openzeppelin-contracts/contracts/utils/Base64.sol deleted file mode 100644 index 4a0b313..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/Base64.sol +++ /dev/null @@ -1,120 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.2) (utils/Base64.sol) - -pragma solidity ^0.8.20; - -/** - * @dev Provides a set of functions to operate with Base64 strings. - */ -library Base64 { - /** - * @dev Base64 Encoding/Decoding Table - * See sections 4 and 5 of https://datatracker.ietf.org/doc/html/rfc4648 - */ - string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - string internal constant _TABLE_URL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; - - /** - * @dev Converts a `bytes` to its Bytes64 `string` representation. - */ - function encode(bytes memory data) internal pure returns (string memory) { - return _encode(data, _TABLE, true); - } - - /** - * @dev Converts a `bytes` to its Bytes64Url `string` representation. - */ - function encodeURL(bytes memory data) internal pure returns (string memory) { - return _encode(data, _TABLE_URL, false); - } - - /** - * @dev Internal table-agnostic conversion - */ - function _encode(bytes memory data, string memory table, bool withPadding) private 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 ""; - - // If padding is enabled, the final length should be `bytes` data length divided by 3 rounded up and then - // multiplied by 4 so that it leaves room for padding the last chunk - // - `data.length + 2` -> Round up - // - `/ 3` -> Number of 3-bytes chunks - // - `4 *` -> 4 characters for each chunk - // If padding is disabled, the final length should be `bytes` data length multiplied by 4/3 rounded up as - // opposed to when padding is required to fill the last chunk. - // - `4 *` -> 4 characters for each chunk - // - `data.length + 2` -> Round up - // - `/ 3` -> Number of 3-bytes chunks - uint256 resultLength = withPadding ? 4 * ((data.length + 2) / 3) : (4 * data.length + 2) / 3; - - string memory result = new string(resultLength); - - /// @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, 0x20) - let dataPtr := data - let endPtr := add(data, mload(data)) - - // In some cases, the last iteration will read bytes after the end of the data. We cache the value, and - // set it to zero to make sure no dirty bytes are read in that section. - let afterPtr := add(endPtr, 0x20) - let afterCache := mload(afterPtr) - mstore(afterPtr, 0x00) - - // Run over the input, 3 bytes at a time - for { - - } lt(dataPtr, endPtr) { - - } { - // Advance 3 bytes - dataPtr := add(dataPtr, 3) - let input := mload(dataPtr) - - // To write each character, shift the 3 byte (24 bits) chunk - // 4 times in blocks of 6 bits for each character (18, 12, 6, 0) - // and apply logical AND with 0x3F to bitmask the least significant 6 bits. - // Use this as an index into the lookup table, mload an entire word - // so the desired character is in the least significant byte, and - // mstore8 this least significant byte into the result and continue. - - 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 - } - - // Reset the value that was cached - mstore(afterPtr, afterCache) - - if withPadding { - // 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/openzeppelin-contracts/contracts/utils/Context.sol b/lib/openzeppelin-contracts/contracts/utils/Context.sol deleted file mode 100644 index 4e535fe..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/Context.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) - -pragma solidity ^0.8.20; - -/** - * @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; - } - - function _contextSuffixLength() internal view virtual returns (uint256) { - return 0; - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/Create2.sol b/lib/openzeppelin-contracts/contracts/utils/Create2.sol deleted file mode 100644 index a88ce25..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/Create2.sol +++ /dev/null @@ -1,94 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/Create2.sol) - -pragma solidity ^0.8.20; - -import {Errors} from "./Errors.sol"; - -/** - * @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 There's no code to deploy. - */ - error Create2EmptyBytecode(); - - /** - * @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) { - if (address(this).balance < amount) { - revert Errors.InsufficientBalance(address(this).balance, amount); - } - if (bytecode.length == 0) { - revert Create2EmptyBytecode(); - } - /// @solidity memory-safe-assembly - assembly { - addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt) - // if no address was created, and returndata is not empty, bubble revert - if and(iszero(addr), not(iszero(returndatasize()))) { - let p := mload(0x40) - returndatacopy(p, 0, returndatasize()) - revert(p, returndatasize()) - } - } - if (addr == address(0)) { - revert Errors.FailedDeployment(); - } - } - - /** - * @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 := and(keccak256(start, 85), 0xffffffffffffffffffffffffffffffffffffffff) - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/Errors.sol b/lib/openzeppelin-contracts/contracts/utils/Errors.sol deleted file mode 100644 index 633d8c2..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/Errors.sol +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -/** - * @dev Collection of common custom errors used in multiple contracts - * - * IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library. - * It is recommended to avoid relying on the error API for critical functionality. - */ -library Errors { - /** - * @dev The ETH balance of the account is not enough to perform the operation. - */ - error InsufficientBalance(uint256 balance, uint256 needed); - - /** - * @dev A call to an address target failed. The target may have reverted. - */ - error FailedCall(); - - /** - * @dev The deployment failed. - */ - error FailedDeployment(); - - /** - * @dev A necessary precompile is missing. - */ - error MissingPrecompile(address); -} diff --git a/lib/openzeppelin-contracts/contracts/utils/Multicall.sol b/lib/openzeppelin-contracts/contracts/utils/Multicall.sol deleted file mode 100644 index 0dd5b4a..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/Multicall.sol +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.1) (utils/Multicall.sol) - -pragma solidity ^0.8.20; - -import {Address} from "./Address.sol"; -import {Context} from "./Context.sol"; - -/** - * @dev Provides a function to batch together multiple calls in a single external call. - * - * Consider any assumption about calldata validation performed by the sender may be violated if it's not especially - * careful about sending transactions invoking {multicall}. For example, a relay address that filters function - * selectors won't filter calls nested within a {multicall} operation. - * - * NOTE: Since 5.0.1 and 4.9.4, this contract identifies non-canonical contexts (i.e. `msg.sender` is not {_msgSender}). - * If a non-canonical context is identified, the following self `delegatecall` appends the last bytes of `msg.data` - * to the subcall. This makes it safe to use with {ERC2771Context}. Contexts that don't affect the resolution of - * {_msgSender} are not propagated to subcalls. - */ -abstract contract Multicall is Context { - /** - * @dev Receives and executes a batch of function calls on this contract. - * @custom:oz-upgrades-unsafe-allow-reachable delegatecall - */ - function multicall(bytes[] calldata data) external virtual returns (bytes[] memory results) { - bytes memory context = msg.sender == _msgSender() - ? new bytes(0) - : msg.data[msg.data.length - _contextSuffixLength():]; - - results = new bytes[](data.length); - for (uint256 i = 0; i < data.length; i++) { - results[i] = Address.functionDelegateCall(address(this), bytes.concat(data[i], context)); - } - return results; - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/Nonces.sol b/lib/openzeppelin-contracts/contracts/utils/Nonces.sol deleted file mode 100644 index 37451ff..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/Nonces.sol +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/Nonces.sol) -pragma solidity ^0.8.20; - -/** - * @dev Provides tracking nonces for addresses. Nonces will only increment. - */ -abstract contract Nonces { - /** - * @dev The nonce used for an `account` is not the expected current nonce. - */ - error InvalidAccountNonce(address account, uint256 currentNonce); - - mapping(address account => uint256) private _nonces; - - /** - * @dev Returns the next unused nonce for an address. - */ - function nonces(address owner) public view virtual returns (uint256) { - return _nonces[owner]; - } - - /** - * @dev Consumes a nonce. - * - * Returns the current value and increments nonce. - */ - function _useNonce(address owner) internal virtual returns (uint256) { - // For each account, the nonce has an initial value of 0, can only be incremented by one, and cannot be - // decremented or reset. This guarantees that the nonce never overflows. - unchecked { - // It is important to do x++ and not ++x here. - return _nonces[owner]++; - } - } - - /** - * @dev Same as {_useNonce} but checking that `nonce` is the next valid for `owner`. - */ - function _useCheckedNonce(address owner, uint256 nonce) internal virtual { - uint256 current = _useNonce(owner); - if (nonce != current) { - revert InvalidAccountNonce(owner, current); - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/Packing.sol b/lib/openzeppelin-contracts/contracts/utils/Packing.sol deleted file mode 100644 index a5a38b5..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/Packing.sol +++ /dev/null @@ -1,1015 +0,0 @@ -// SPDX-License-Identifier: MIT -// This file was procedurally generated from scripts/generate/templates/Packing.js. - -pragma solidity ^0.8.20; - -/** - * @dev Helper library packing and unpacking multiple values into bytesXX. - * - * Example usage: - * - * ```solidity - * library MyPacker { - * type MyType is bytes32; - * - * function _pack(address account, bytes4 selector, uint64 period) external pure returns (MyType) { - * bytes12 subpack = Packing.pack_4_8(selector, bytes8(period)); - * bytes32 pack = Packing.pack_20_12(bytes20(account), subpack); - * return MyType.wrap(pack); - * } - * - * function _unpack(MyType self) external pure returns (address, bytes4, uint64) { - * bytes32 pack = MyType.unwrap(self); - * return ( - * address(Packing.extract_32_20(pack, 0)), - * Packing.extract_32_4(pack, 20), - * uint64(Packing.extract_32_8(pack, 24)) - * ); - * } - * } - * ``` - */ -// solhint-disable func-name-mixedcase -library Packing { - error OutOfRangeAccess(); - - function pack_1_1(bytes1 left, bytes1 right) internal pure returns (bytes2 result) { - assembly ("memory-safe") { - result := or(left, shr(8, right)) - } - } - - function pack_2_2(bytes2 left, bytes2 right) internal pure returns (bytes4 result) { - assembly ("memory-safe") { - result := or(left, shr(16, right)) - } - } - - function pack_2_4(bytes2 left, bytes4 right) internal pure returns (bytes6 result) { - assembly ("memory-safe") { - result := or(left, shr(16, right)) - } - } - - function pack_2_6(bytes2 left, bytes6 right) internal pure returns (bytes8 result) { - assembly ("memory-safe") { - result := or(left, shr(16, right)) - } - } - - function pack_4_2(bytes4 left, bytes2 right) internal pure returns (bytes6 result) { - assembly ("memory-safe") { - result := or(left, shr(32, right)) - } - } - - function pack_4_4(bytes4 left, bytes4 right) internal pure returns (bytes8 result) { - assembly ("memory-safe") { - result := or(left, shr(32, right)) - } - } - - function pack_4_8(bytes4 left, bytes8 right) internal pure returns (bytes12 result) { - assembly ("memory-safe") { - result := or(left, shr(32, right)) - } - } - - function pack_4_12(bytes4 left, bytes12 right) internal pure returns (bytes16 result) { - assembly ("memory-safe") { - result := or(left, shr(32, right)) - } - } - - function pack_4_16(bytes4 left, bytes16 right) internal pure returns (bytes20 result) { - assembly ("memory-safe") { - result := or(left, shr(32, right)) - } - } - - function pack_4_20(bytes4 left, bytes20 right) internal pure returns (bytes24 result) { - assembly ("memory-safe") { - result := or(left, shr(32, right)) - } - } - - function pack_4_24(bytes4 left, bytes24 right) internal pure returns (bytes28 result) { - assembly ("memory-safe") { - result := or(left, shr(32, right)) - } - } - - function pack_4_28(bytes4 left, bytes28 right) internal pure returns (bytes32 result) { - assembly ("memory-safe") { - result := or(left, shr(32, right)) - } - } - - function pack_6_2(bytes6 left, bytes2 right) internal pure returns (bytes8 result) { - assembly ("memory-safe") { - result := or(left, shr(48, right)) - } - } - - function pack_6_6(bytes6 left, bytes6 right) internal pure returns (bytes12 result) { - assembly ("memory-safe") { - result := or(left, shr(48, right)) - } - } - - function pack_8_4(bytes8 left, bytes4 right) internal pure returns (bytes12 result) { - assembly ("memory-safe") { - result := or(left, shr(64, right)) - } - } - - function pack_8_8(bytes8 left, bytes8 right) internal pure returns (bytes16 result) { - assembly ("memory-safe") { - result := or(left, shr(64, right)) - } - } - - function pack_8_12(bytes8 left, bytes12 right) internal pure returns (bytes20 result) { - assembly ("memory-safe") { - result := or(left, shr(64, right)) - } - } - - function pack_8_16(bytes8 left, bytes16 right) internal pure returns (bytes24 result) { - assembly ("memory-safe") { - result := or(left, shr(64, right)) - } - } - - function pack_8_20(bytes8 left, bytes20 right) internal pure returns (bytes28 result) { - assembly ("memory-safe") { - result := or(left, shr(64, right)) - } - } - - function pack_8_24(bytes8 left, bytes24 right) internal pure returns (bytes32 result) { - assembly ("memory-safe") { - result := or(left, shr(64, right)) - } - } - - function pack_12_4(bytes12 left, bytes4 right) internal pure returns (bytes16 result) { - assembly ("memory-safe") { - result := or(left, shr(96, right)) - } - } - - function pack_12_8(bytes12 left, bytes8 right) internal pure returns (bytes20 result) { - assembly ("memory-safe") { - result := or(left, shr(96, right)) - } - } - - function pack_12_12(bytes12 left, bytes12 right) internal pure returns (bytes24 result) { - assembly ("memory-safe") { - result := or(left, shr(96, right)) - } - } - - function pack_12_16(bytes12 left, bytes16 right) internal pure returns (bytes28 result) { - assembly ("memory-safe") { - result := or(left, shr(96, right)) - } - } - - function pack_12_20(bytes12 left, bytes20 right) internal pure returns (bytes32 result) { - assembly ("memory-safe") { - result := or(left, shr(96, right)) - } - } - - function pack_16_4(bytes16 left, bytes4 right) internal pure returns (bytes20 result) { - assembly ("memory-safe") { - result := or(left, shr(128, right)) - } - } - - function pack_16_8(bytes16 left, bytes8 right) internal pure returns (bytes24 result) { - assembly ("memory-safe") { - result := or(left, shr(128, right)) - } - } - - function pack_16_12(bytes16 left, bytes12 right) internal pure returns (bytes28 result) { - assembly ("memory-safe") { - result := or(left, shr(128, right)) - } - } - - function pack_16_16(bytes16 left, bytes16 right) internal pure returns (bytes32 result) { - assembly ("memory-safe") { - result := or(left, shr(128, right)) - } - } - - function pack_20_4(bytes20 left, bytes4 right) internal pure returns (bytes24 result) { - assembly ("memory-safe") { - result := or(left, shr(160, right)) - } - } - - function pack_20_8(bytes20 left, bytes8 right) internal pure returns (bytes28 result) { - assembly ("memory-safe") { - result := or(left, shr(160, right)) - } - } - - function pack_20_12(bytes20 left, bytes12 right) internal pure returns (bytes32 result) { - assembly ("memory-safe") { - result := or(left, shr(160, right)) - } - } - - function pack_24_4(bytes24 left, bytes4 right) internal pure returns (bytes28 result) { - assembly ("memory-safe") { - result := or(left, shr(192, right)) - } - } - - function pack_24_8(bytes24 left, bytes8 right) internal pure returns (bytes32 result) { - assembly ("memory-safe") { - result := or(left, shr(192, right)) - } - } - - function pack_28_4(bytes28 left, bytes4 right) internal pure returns (bytes32 result) { - assembly ("memory-safe") { - result := or(left, shr(224, right)) - } - } - - function extract_2_1(bytes2 self, uint8 offset) internal pure returns (bytes1 result) { - if (offset > 1) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(248, not(0))) - } - } - - function replace_2_1(bytes2 self, bytes1 value, uint8 offset) internal pure returns (bytes2 result) { - bytes1 oldValue = extract_2_1(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_4_1(bytes4 self, uint8 offset) internal pure returns (bytes1 result) { - if (offset > 3) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(248, not(0))) - } - } - - function replace_4_1(bytes4 self, bytes1 value, uint8 offset) internal pure returns (bytes4 result) { - bytes1 oldValue = extract_4_1(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_4_2(bytes4 self, uint8 offset) internal pure returns (bytes2 result) { - if (offset > 2) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(240, not(0))) - } - } - - function replace_4_2(bytes4 self, bytes2 value, uint8 offset) internal pure returns (bytes4 result) { - bytes2 oldValue = extract_4_2(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_6_1(bytes6 self, uint8 offset) internal pure returns (bytes1 result) { - if (offset > 5) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(248, not(0))) - } - } - - function replace_6_1(bytes6 self, bytes1 value, uint8 offset) internal pure returns (bytes6 result) { - bytes1 oldValue = extract_6_1(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_6_2(bytes6 self, uint8 offset) internal pure returns (bytes2 result) { - if (offset > 4) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(240, not(0))) - } - } - - function replace_6_2(bytes6 self, bytes2 value, uint8 offset) internal pure returns (bytes6 result) { - bytes2 oldValue = extract_6_2(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_6_4(bytes6 self, uint8 offset) internal pure returns (bytes4 result) { - if (offset > 2) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(224, not(0))) - } - } - - function replace_6_4(bytes6 self, bytes4 value, uint8 offset) internal pure returns (bytes6 result) { - bytes4 oldValue = extract_6_4(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_8_1(bytes8 self, uint8 offset) internal pure returns (bytes1 result) { - if (offset > 7) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(248, not(0))) - } - } - - function replace_8_1(bytes8 self, bytes1 value, uint8 offset) internal pure returns (bytes8 result) { - bytes1 oldValue = extract_8_1(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_8_2(bytes8 self, uint8 offset) internal pure returns (bytes2 result) { - if (offset > 6) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(240, not(0))) - } - } - - function replace_8_2(bytes8 self, bytes2 value, uint8 offset) internal pure returns (bytes8 result) { - bytes2 oldValue = extract_8_2(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_8_4(bytes8 self, uint8 offset) internal pure returns (bytes4 result) { - if (offset > 4) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(224, not(0))) - } - } - - function replace_8_4(bytes8 self, bytes4 value, uint8 offset) internal pure returns (bytes8 result) { - bytes4 oldValue = extract_8_4(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_8_6(bytes8 self, uint8 offset) internal pure returns (bytes6 result) { - if (offset > 2) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(208, not(0))) - } - } - - function replace_8_6(bytes8 self, bytes6 value, uint8 offset) internal pure returns (bytes8 result) { - bytes6 oldValue = extract_8_6(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_12_1(bytes12 self, uint8 offset) internal pure returns (bytes1 result) { - if (offset > 11) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(248, not(0))) - } - } - - function replace_12_1(bytes12 self, bytes1 value, uint8 offset) internal pure returns (bytes12 result) { - bytes1 oldValue = extract_12_1(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_12_2(bytes12 self, uint8 offset) internal pure returns (bytes2 result) { - if (offset > 10) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(240, not(0))) - } - } - - function replace_12_2(bytes12 self, bytes2 value, uint8 offset) internal pure returns (bytes12 result) { - bytes2 oldValue = extract_12_2(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_12_4(bytes12 self, uint8 offset) internal pure returns (bytes4 result) { - if (offset > 8) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(224, not(0))) - } - } - - function replace_12_4(bytes12 self, bytes4 value, uint8 offset) internal pure returns (bytes12 result) { - bytes4 oldValue = extract_12_4(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_12_6(bytes12 self, uint8 offset) internal pure returns (bytes6 result) { - if (offset > 6) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(208, not(0))) - } - } - - function replace_12_6(bytes12 self, bytes6 value, uint8 offset) internal pure returns (bytes12 result) { - bytes6 oldValue = extract_12_6(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_12_8(bytes12 self, uint8 offset) internal pure returns (bytes8 result) { - if (offset > 4) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(192, not(0))) - } - } - - function replace_12_8(bytes12 self, bytes8 value, uint8 offset) internal pure returns (bytes12 result) { - bytes8 oldValue = extract_12_8(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_16_1(bytes16 self, uint8 offset) internal pure returns (bytes1 result) { - if (offset > 15) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(248, not(0))) - } - } - - function replace_16_1(bytes16 self, bytes1 value, uint8 offset) internal pure returns (bytes16 result) { - bytes1 oldValue = extract_16_1(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_16_2(bytes16 self, uint8 offset) internal pure returns (bytes2 result) { - if (offset > 14) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(240, not(0))) - } - } - - function replace_16_2(bytes16 self, bytes2 value, uint8 offset) internal pure returns (bytes16 result) { - bytes2 oldValue = extract_16_2(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_16_4(bytes16 self, uint8 offset) internal pure returns (bytes4 result) { - if (offset > 12) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(224, not(0))) - } - } - - function replace_16_4(bytes16 self, bytes4 value, uint8 offset) internal pure returns (bytes16 result) { - bytes4 oldValue = extract_16_4(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_16_6(bytes16 self, uint8 offset) internal pure returns (bytes6 result) { - if (offset > 10) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(208, not(0))) - } - } - - function replace_16_6(bytes16 self, bytes6 value, uint8 offset) internal pure returns (bytes16 result) { - bytes6 oldValue = extract_16_6(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_16_8(bytes16 self, uint8 offset) internal pure returns (bytes8 result) { - if (offset > 8) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(192, not(0))) - } - } - - function replace_16_8(bytes16 self, bytes8 value, uint8 offset) internal pure returns (bytes16 result) { - bytes8 oldValue = extract_16_8(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_16_12(bytes16 self, uint8 offset) internal pure returns (bytes12 result) { - if (offset > 4) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(160, not(0))) - } - } - - function replace_16_12(bytes16 self, bytes12 value, uint8 offset) internal pure returns (bytes16 result) { - bytes12 oldValue = extract_16_12(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_20_1(bytes20 self, uint8 offset) internal pure returns (bytes1 result) { - if (offset > 19) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(248, not(0))) - } - } - - function replace_20_1(bytes20 self, bytes1 value, uint8 offset) internal pure returns (bytes20 result) { - bytes1 oldValue = extract_20_1(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_20_2(bytes20 self, uint8 offset) internal pure returns (bytes2 result) { - if (offset > 18) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(240, not(0))) - } - } - - function replace_20_2(bytes20 self, bytes2 value, uint8 offset) internal pure returns (bytes20 result) { - bytes2 oldValue = extract_20_2(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_20_4(bytes20 self, uint8 offset) internal pure returns (bytes4 result) { - if (offset > 16) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(224, not(0))) - } - } - - function replace_20_4(bytes20 self, bytes4 value, uint8 offset) internal pure returns (bytes20 result) { - bytes4 oldValue = extract_20_4(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_20_6(bytes20 self, uint8 offset) internal pure returns (bytes6 result) { - if (offset > 14) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(208, not(0))) - } - } - - function replace_20_6(bytes20 self, bytes6 value, uint8 offset) internal pure returns (bytes20 result) { - bytes6 oldValue = extract_20_6(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_20_8(bytes20 self, uint8 offset) internal pure returns (bytes8 result) { - if (offset > 12) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(192, not(0))) - } - } - - function replace_20_8(bytes20 self, bytes8 value, uint8 offset) internal pure returns (bytes20 result) { - bytes8 oldValue = extract_20_8(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_20_12(bytes20 self, uint8 offset) internal pure returns (bytes12 result) { - if (offset > 8) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(160, not(0))) - } - } - - function replace_20_12(bytes20 self, bytes12 value, uint8 offset) internal pure returns (bytes20 result) { - bytes12 oldValue = extract_20_12(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_20_16(bytes20 self, uint8 offset) internal pure returns (bytes16 result) { - if (offset > 4) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(128, not(0))) - } - } - - function replace_20_16(bytes20 self, bytes16 value, uint8 offset) internal pure returns (bytes20 result) { - bytes16 oldValue = extract_20_16(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_24_1(bytes24 self, uint8 offset) internal pure returns (bytes1 result) { - if (offset > 23) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(248, not(0))) - } - } - - function replace_24_1(bytes24 self, bytes1 value, uint8 offset) internal pure returns (bytes24 result) { - bytes1 oldValue = extract_24_1(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_24_2(bytes24 self, uint8 offset) internal pure returns (bytes2 result) { - if (offset > 22) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(240, not(0))) - } - } - - function replace_24_2(bytes24 self, bytes2 value, uint8 offset) internal pure returns (bytes24 result) { - bytes2 oldValue = extract_24_2(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_24_4(bytes24 self, uint8 offset) internal pure returns (bytes4 result) { - if (offset > 20) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(224, not(0))) - } - } - - function replace_24_4(bytes24 self, bytes4 value, uint8 offset) internal pure returns (bytes24 result) { - bytes4 oldValue = extract_24_4(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_24_6(bytes24 self, uint8 offset) internal pure returns (bytes6 result) { - if (offset > 18) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(208, not(0))) - } - } - - function replace_24_6(bytes24 self, bytes6 value, uint8 offset) internal pure returns (bytes24 result) { - bytes6 oldValue = extract_24_6(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_24_8(bytes24 self, uint8 offset) internal pure returns (bytes8 result) { - if (offset > 16) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(192, not(0))) - } - } - - function replace_24_8(bytes24 self, bytes8 value, uint8 offset) internal pure returns (bytes24 result) { - bytes8 oldValue = extract_24_8(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_24_12(bytes24 self, uint8 offset) internal pure returns (bytes12 result) { - if (offset > 12) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(160, not(0))) - } - } - - function replace_24_12(bytes24 self, bytes12 value, uint8 offset) internal pure returns (bytes24 result) { - bytes12 oldValue = extract_24_12(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_24_16(bytes24 self, uint8 offset) internal pure returns (bytes16 result) { - if (offset > 8) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(128, not(0))) - } - } - - function replace_24_16(bytes24 self, bytes16 value, uint8 offset) internal pure returns (bytes24 result) { - bytes16 oldValue = extract_24_16(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_24_20(bytes24 self, uint8 offset) internal pure returns (bytes20 result) { - if (offset > 4) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(96, not(0))) - } - } - - function replace_24_20(bytes24 self, bytes20 value, uint8 offset) internal pure returns (bytes24 result) { - bytes20 oldValue = extract_24_20(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_28_1(bytes28 self, uint8 offset) internal pure returns (bytes1 result) { - if (offset > 27) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(248, not(0))) - } - } - - function replace_28_1(bytes28 self, bytes1 value, uint8 offset) internal pure returns (bytes28 result) { - bytes1 oldValue = extract_28_1(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_28_2(bytes28 self, uint8 offset) internal pure returns (bytes2 result) { - if (offset > 26) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(240, not(0))) - } - } - - function replace_28_2(bytes28 self, bytes2 value, uint8 offset) internal pure returns (bytes28 result) { - bytes2 oldValue = extract_28_2(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_28_4(bytes28 self, uint8 offset) internal pure returns (bytes4 result) { - if (offset > 24) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(224, not(0))) - } - } - - function replace_28_4(bytes28 self, bytes4 value, uint8 offset) internal pure returns (bytes28 result) { - bytes4 oldValue = extract_28_4(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_28_6(bytes28 self, uint8 offset) internal pure returns (bytes6 result) { - if (offset > 22) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(208, not(0))) - } - } - - function replace_28_6(bytes28 self, bytes6 value, uint8 offset) internal pure returns (bytes28 result) { - bytes6 oldValue = extract_28_6(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_28_8(bytes28 self, uint8 offset) internal pure returns (bytes8 result) { - if (offset > 20) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(192, not(0))) - } - } - - function replace_28_8(bytes28 self, bytes8 value, uint8 offset) internal pure returns (bytes28 result) { - bytes8 oldValue = extract_28_8(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_28_12(bytes28 self, uint8 offset) internal pure returns (bytes12 result) { - if (offset > 16) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(160, not(0))) - } - } - - function replace_28_12(bytes28 self, bytes12 value, uint8 offset) internal pure returns (bytes28 result) { - bytes12 oldValue = extract_28_12(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_28_16(bytes28 self, uint8 offset) internal pure returns (bytes16 result) { - if (offset > 12) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(128, not(0))) - } - } - - function replace_28_16(bytes28 self, bytes16 value, uint8 offset) internal pure returns (bytes28 result) { - bytes16 oldValue = extract_28_16(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_28_20(bytes28 self, uint8 offset) internal pure returns (bytes20 result) { - if (offset > 8) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(96, not(0))) - } - } - - function replace_28_20(bytes28 self, bytes20 value, uint8 offset) internal pure returns (bytes28 result) { - bytes20 oldValue = extract_28_20(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_28_24(bytes28 self, uint8 offset) internal pure returns (bytes24 result) { - if (offset > 4) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(64, not(0))) - } - } - - function replace_28_24(bytes28 self, bytes24 value, uint8 offset) internal pure returns (bytes28 result) { - bytes24 oldValue = extract_28_24(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_32_1(bytes32 self, uint8 offset) internal pure returns (bytes1 result) { - if (offset > 31) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(248, not(0))) - } - } - - function replace_32_1(bytes32 self, bytes1 value, uint8 offset) internal pure returns (bytes32 result) { - bytes1 oldValue = extract_32_1(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_32_2(bytes32 self, uint8 offset) internal pure returns (bytes2 result) { - if (offset > 30) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(240, not(0))) - } - } - - function replace_32_2(bytes32 self, bytes2 value, uint8 offset) internal pure returns (bytes32 result) { - bytes2 oldValue = extract_32_2(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_32_4(bytes32 self, uint8 offset) internal pure returns (bytes4 result) { - if (offset > 28) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(224, not(0))) - } - } - - function replace_32_4(bytes32 self, bytes4 value, uint8 offset) internal pure returns (bytes32 result) { - bytes4 oldValue = extract_32_4(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_32_6(bytes32 self, uint8 offset) internal pure returns (bytes6 result) { - if (offset > 26) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(208, not(0))) - } - } - - function replace_32_6(bytes32 self, bytes6 value, uint8 offset) internal pure returns (bytes32 result) { - bytes6 oldValue = extract_32_6(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_32_8(bytes32 self, uint8 offset) internal pure returns (bytes8 result) { - if (offset > 24) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(192, not(0))) - } - } - - function replace_32_8(bytes32 self, bytes8 value, uint8 offset) internal pure returns (bytes32 result) { - bytes8 oldValue = extract_32_8(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_32_12(bytes32 self, uint8 offset) internal pure returns (bytes12 result) { - if (offset > 20) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(160, not(0))) - } - } - - function replace_32_12(bytes32 self, bytes12 value, uint8 offset) internal pure returns (bytes32 result) { - bytes12 oldValue = extract_32_12(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_32_16(bytes32 self, uint8 offset) internal pure returns (bytes16 result) { - if (offset > 16) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(128, not(0))) - } - } - - function replace_32_16(bytes32 self, bytes16 value, uint8 offset) internal pure returns (bytes32 result) { - bytes16 oldValue = extract_32_16(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_32_20(bytes32 self, uint8 offset) internal pure returns (bytes20 result) { - if (offset > 12) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(96, not(0))) - } - } - - function replace_32_20(bytes32 self, bytes20 value, uint8 offset) internal pure returns (bytes32 result) { - bytes20 oldValue = extract_32_20(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_32_24(bytes32 self, uint8 offset) internal pure returns (bytes24 result) { - if (offset > 8) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(64, not(0))) - } - } - - function replace_32_24(bytes32 self, bytes24 value, uint8 offset) internal pure returns (bytes32 result) { - bytes24 oldValue = extract_32_24(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } - - function extract_32_28(bytes32 self, uint8 offset) internal pure returns (bytes28 result) { - if (offset > 4) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(32, not(0))) - } - } - - function replace_32_28(bytes32 self, bytes28 value, uint8 offset) internal pure returns (bytes32 result) { - bytes28 oldValue = extract_32_28(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/Panic.sol b/lib/openzeppelin-contracts/contracts/utils/Panic.sol deleted file mode 100644 index b644303..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/Panic.sol +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -/** - * @dev Helper library for emitting standardized panic codes. - * - * ```solidity - * contract Example { - * using Panic for uint256; - * - * // Use any of the declared internal constants - * function foo() { Panic.GENERIC.panic(); } - * - * // Alternatively - * function foo() { Panic.panic(Panic.GENERIC); } - * } - * ``` - * - * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil]. - */ -// slither-disable-next-line unused-state -library Panic { - /// @dev generic / unspecified error - uint256 internal constant GENERIC = 0x00; - /// @dev used by the assert() builtin - uint256 internal constant ASSERT = 0x01; - /// @dev arithmetic underflow or overflow - uint256 internal constant UNDER_OVERFLOW = 0x11; - /// @dev division or modulo by zero - uint256 internal constant DIVISION_BY_ZERO = 0x12; - /// @dev enum conversion error - uint256 internal constant ENUM_CONVERSION_ERROR = 0x21; - /// @dev invalid encoding in storage - uint256 internal constant STORAGE_ENCODING_ERROR = 0x22; - /// @dev empty array pop - uint256 internal constant EMPTY_ARRAY_POP = 0x31; - /// @dev array out of bounds access - uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32; - /// @dev resource error (too large allocation or too large array) - uint256 internal constant RESOURCE_ERROR = 0x41; - /// @dev calling invalid internal function - uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51; - - /// @dev Reverts with a panic code. Recommended to use with - /// the internal constants with predefined codes. - function panic(uint256 code) internal pure { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0x4e487b71) - mstore(0x20, code) - revert(0x1c, 0x24) - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/Pausable.sol b/lib/openzeppelin-contracts/contracts/utils/Pausable.sol deleted file mode 100644 index 312f1cb..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/Pausable.sol +++ /dev/null @@ -1,119 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol) - -pragma solidity ^0.8.20; - -import {Context} from "../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 { - bool private _paused; - - /** - * @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); - - /** - * @dev The operation failed because the contract is paused. - */ - error EnforcedPause(); - - /** - * @dev The operation failed because the contract is not paused. - */ - error ExpectedPause(); - - /** - * @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 { - if (paused()) { - revert EnforcedPause(); - } - } - - /** - * @dev Throws if the contract is not paused. - */ - function _requirePaused() internal view virtual { - if (!paused()) { - revert ExpectedPause(); - } - } - - /** - * @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/openzeppelin-contracts/contracts/utils/README.adoc b/lib/openzeppelin-contracts/contracts/utils/README.adoc deleted file mode 100644 index 71c39df..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/README.adoc +++ /dev/null @@ -1,131 +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. - - * {Math}, {SignedMath}: Implementation of various arithmetic functions. - * {SafeCast}: Checked downcasting functions to avoid silent truncation. - * {ECDSA}, {MessageHashUtils}: Libraries for interacting with ECDSA signatures. - * {P256}: Library for verifying and recovering public keys from secp256r1 signatures. - * {RSA}: Library with RSA PKCS#1 v1.5 signature verification utilities. - * {SignatureChecker}: A library helper to support regular ECDSA from EOAs as well as ERC-1271 signatures for smart contracts. - * {Hashes}: Commonly used hash functions. - * {MerkleProof}: Functions for verifying https://en.wikipedia.org/wiki/Merkle_tree[Merkle Tree] proofs. - * {EIP712}: Contract with functions to allow processing signed typed structure data according to https://eips.ethereum.org/EIPS/eip-712[EIP-712]. - * {ReentrancyGuard}: A modifier that can prevent reentrancy during certain functions. - * {ReentrancyGuardTransient}: Variant of {ReentrancyGuard} that uses transient storage (https://eips.ethereum.org/EIPS/eip-1153[EIP-1153]). - * {Pausable}: A common emergency response mechanism that can pause functionality while a remediation is pending. - * {Nonces}: Utility for tracking and verifying address nonces that only increment. - * {ERC165}, {ERC165Checker}: Utilities for inspecting interfaces supported by contracts. - * {BitMaps}: A simple library to manage boolean value mapped to a numerical index in an efficient way. - * {EnumerableMap}: A type like Solidity's https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`], 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. - * {DoubleEndedQueue}: An implementation of a https://en.wikipedia.org/wiki/Double-ended_queue[double ended queue] whose values can be removed added or remove from both sides. Useful for FIFO and LIFO structures. - * {CircularBuffer}: A data structure to store the last N values pushed to it. - * {Checkpoints}: A data structure to store values mapped to an strictly increasing key. Can be used for storing and accessing values over time. - * {MerkleTree}: A library with https://wikipedia.org/wiki/Merkle_Tree[Merkle Tree] data structures and helper functions. - * {Create2}: Wrapper around the https://blog.openzeppelin.com/getting-the-most-out-of-create2/[`CREATE2` EVM opcode] for safe use without having to deal with low-level assembly. - * {Address}: Collection of functions for overloading Solidity's https://docs.soliditylang.org/en/latest/types.html#address[`address`] type. - * {Arrays}: Collection of functions that operate on https://docs.soliditylang.org/en/latest/types.html#arrays[`arrays`]. - * {Base64}: On-chain base64 and base64URL encoding according to https://datatracker.ietf.org/doc/html/rfc4648[RFC-4648]. - * {Strings}: Common operations for strings formatting. - * {ShortString}: Library to encode (and decode) short strings into (or from) a single bytes32 slot for optimizing costs. Short strings are limited to 31 characters. - * {SlotDerivation}: Methods for deriving storage slot from ERC-7201 namespaces as well as from constructions such as mapping and arrays. - * {StorageSlot}: Methods for accessing specific storage slots formatted as common primitive types. Also include primitives for reading from and writing to transient storage (only value types are currently supported). - * {Multicall}: Abstract contract with an utility to allow batching together multiple calls in a single transaction. Useful for allowing EOAs to perform multiple operations at once. - * {Context}: An utility for abstracting the sender and calldata in the current execution context. - * {Packing}: A library for packing and unpacking multiple values into bytes32 - * {Panic}: A library to revert with https://docs.soliditylang.org/en/v0.8.20/control-structures.html#panic-via-assert-and-error-via-require[Solidity panic codes]. - -[NOTE] -==== -Because Solidity does not support generic types, {EnumerableMap} and {EnumerableSet} are specialized to a limited number of key-value types. -==== - -== Math - -{{Math}} - -{{SignedMath}} - -{{SafeCast}} - -== Cryptography - -{{ECDSA}} - -{{EIP712}} - -{{MessageHashUtils}} - -{{SignatureChecker}} - -{{Hashes}} - -{{MerkleProof}} - -== Security - -{{ReentrancyGuard}} - -{{ReentrancyGuardTransient}} - -{{Pausable}} - -{{Nonces}} - -== 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. ERC-20 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. - -{{IERC165}} - -{{ERC165}} - -{{ERC165Checker}} - -== Data Structures - -{{BitMaps}} - -{{EnumerableMap}} - -{{EnumerableSet}} - -{{DoubleEndedQueue}} - -{{CircularBuffer}} - -{{Checkpoints}} - -{{MerkleTree}} - -== Libraries - -{{Create2}} - -{{Address}} - -{{Arrays}} - -{{Base64}} - -{{Strings}} - -{{ShortStrings}} - -{{SlotDerivation}} - -{{StorageSlot}} - -{{Multicall}} - -{{Context}} - -{{Packing}} - -{{Panic}} diff --git a/lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol b/lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol deleted file mode 100644 index 0818511..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol) - -pragma solidity ^0.8.20; - -/** - * @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 EIP-1153 (transient storage) is available on the chain you're deploying at, - * consider using {ReentrancyGuardTransient} instead. - * - * 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; - - /** - * @dev Unauthorized reentrant call. - */ - error ReentrancyGuardReentrantCall(); - - 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, _status will be NOT_ENTERED - if (_status == ENTERED) { - revert ReentrancyGuardReentrantCall(); - } - - // 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 Returns true if the reentrancy guard is currently set to "entered", which indicates there is a - * `nonReentrant` function in the call stack. - */ - function _reentrancyGuardEntered() internal view returns (bool) { - return _status == ENTERED; - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/ReentrancyGuardTransient.sol b/lib/openzeppelin-contracts/contracts/utils/ReentrancyGuardTransient.sol deleted file mode 100644 index 0389b86..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/ReentrancyGuardTransient.sol +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.24; - -import {StorageSlot} from "./StorageSlot.sol"; - -/** - * @dev Variant of {ReentrancyGuard} that uses transient storage. - * - * NOTE: This variant only works on networks where EIP-1153 is available. - */ -abstract contract ReentrancyGuardTransient { - using StorageSlot for *; - - // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ReentrancyGuard")) - 1)) & ~bytes32(uint256(0xff)) - bytes32 private constant REENTRANCY_GUARD_STORAGE = - 0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00; - - /** - * @dev Unauthorized reentrant call. - */ - error ReentrancyGuardReentrantCall(); - - /** - * @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 - if (_reentrancyGuardEntered()) { - revert ReentrancyGuardReentrantCall(); - } - - // Any calls to nonReentrant after this point will fail - REENTRANCY_GUARD_STORAGE.asBoolean().tstore(true); - } - - function _nonReentrantAfter() private { - REENTRANCY_GUARD_STORAGE.asBoolean().tstore(false); - } - - /** - * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a - * `nonReentrant` function in the call stack. - */ - function _reentrancyGuardEntered() internal view returns (bool) { - return REENTRANCY_GUARD_STORAGE.asBoolean().tload(); - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/ShortStrings.sol b/lib/openzeppelin-contracts/contracts/utils/ShortStrings.sol deleted file mode 100644 index fdfe774..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/ShortStrings.sol +++ /dev/null @@ -1,123 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/ShortStrings.sol) - -pragma solidity ^0.8.20; - -import {StorageSlot} from "./StorageSlot.sol"; - -// | string | 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | -// | length | 0x BB | -type ShortString is bytes32; - -/** - * @dev This library provides functions to convert short memory strings - * into a `ShortString` type that can be used as an immutable variable. - * - * Strings of arbitrary length can be optimized using this library if - * they are short enough (up to 31 bytes) by packing them with their - * length (1 byte) in a single EVM word (32 bytes). Additionally, a - * fallback mechanism can be used for every other case. - * - * Usage example: - * - * ```solidity - * contract Named { - * using ShortStrings for *; - * - * ShortString private immutable _name; - * string private _nameFallback; - * - * constructor(string memory contractName) { - * _name = contractName.toShortStringWithFallback(_nameFallback); - * } - * - * function name() external view returns (string memory) { - * return _name.toStringWithFallback(_nameFallback); - * } - * } - * ``` - */ -library ShortStrings { - // Used as an identifier for strings longer than 31 bytes. - bytes32 private constant FALLBACK_SENTINEL = 0x00000000000000000000000000000000000000000000000000000000000000FF; - - error StringTooLong(string str); - error InvalidShortString(); - - /** - * @dev Encode a string of at most 31 chars into a `ShortString`. - * - * This will trigger a `StringTooLong` error is the input string is too long. - */ - function toShortString(string memory str) internal pure returns (ShortString) { - bytes memory bstr = bytes(str); - if (bstr.length > 31) { - revert StringTooLong(str); - } - return ShortString.wrap(bytes32(uint256(bytes32(bstr)) | bstr.length)); - } - - /** - * @dev Decode a `ShortString` back to a "normal" string. - */ - function toString(ShortString sstr) internal pure returns (string memory) { - uint256 len = byteLength(sstr); - // using `new string(len)` would work locally but is not memory safe. - string memory str = new string(32); - /// @solidity memory-safe-assembly - assembly { - mstore(str, len) - mstore(add(str, 0x20), sstr) - } - return str; - } - - /** - * @dev Return the length of a `ShortString`. - */ - function byteLength(ShortString sstr) internal pure returns (uint256) { - uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF; - if (result > 31) { - revert InvalidShortString(); - } - return result; - } - - /** - * @dev Encode a string into a `ShortString`, or write it to storage if it is too long. - */ - function toShortStringWithFallback(string memory value, string storage store) internal returns (ShortString) { - if (bytes(value).length < 32) { - return toShortString(value); - } else { - StorageSlot.getStringSlot(store).value = value; - return ShortString.wrap(FALLBACK_SENTINEL); - } - } - - /** - * @dev Decode a string that was encoded to `ShortString` or written to storage using {setWithFallback}. - */ - function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) { - if (ShortString.unwrap(value) != FALLBACK_SENTINEL) { - return toString(value); - } else { - return store; - } - } - - /** - * @dev Return the length of a string that was encoded to `ShortString` or written to storage using - * {setWithFallback}. - * - * WARNING: This will return the "byte length" of the string. This may not reflect the actual length in terms of - * actual characters as the UTF-8 encoding of a single character can span over multiple bytes. - */ - function byteLengthWithFallback(ShortString value, string storage store) internal view returns (uint256) { - if (ShortString.unwrap(value) != FALLBACK_SENTINEL) { - return byteLength(value); - } else { - return bytes(store).length; - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/SlotDerivation.sol b/lib/openzeppelin-contracts/contracts/utils/SlotDerivation.sol deleted file mode 100644 index c75941b..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/SlotDerivation.sol +++ /dev/null @@ -1,161 +0,0 @@ -// SPDX-License-Identifier: MIT -// This file was procedurally generated from scripts/generate/templates/SlotDerivation.js. - -pragma solidity ^0.8.20; - -/** - * @dev Library for computing storage (and transient storage) locations from namespaces and deriving slots - * corresponding to standard patterns. The derivation method for array and mapping matches the storage layout used by - * the solidity language / compiler. - * - * See https://docs.soliditylang.org/en/v0.8.20/internals/layout_in_storage.html#mappings-and-dynamic-arrays[Solidity docs for mappings and dynamic arrays.]. - * - * Example usage: - * ```solidity - * contract Example { - * // Add the library methods - * using StorageSlot for bytes32; - * using SlotDerivation for bytes32; - * - * // Declare a namespace - * string private constant _NAMESPACE = "" // eg. OpenZeppelin.Slot - * - * function setValueInNamespace(uint256 key, address newValue) internal { - * _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value = newValue; - * } - * - * function getValueInNamespace(uint256 key) internal view returns (address) { - * return _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value; - * } - * } - * ``` - * - * TIP: Consider using this library along with {StorageSlot}. - * - * NOTE: This library provides a way to manipulate storage locations in a non-standard way. Tooling for checking - * upgrade safety will ignore the slots accessed through this library. - */ -library SlotDerivation { - /** - * @dev Derive an ERC-7201 slot from a string (namespace). - */ - function erc7201Slot(string memory namespace) internal pure returns (bytes32 slot) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, sub(keccak256(add(namespace, 0x20), mload(namespace)), 1)) - slot := and(keccak256(0x00, 0x20), not(0xff)) - } - } - - /** - * @dev Add an offset to a slot to get the n-th element of a structure or an array. - */ - function offset(bytes32 slot, uint256 pos) internal pure returns (bytes32 result) { - unchecked { - return bytes32(uint256(slot) + pos); - } - } - - /** - * @dev Derive the location of the first element in an array from the slot where the length is stored. - */ - function deriveArray(bytes32 slot) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, slot) - result := keccak256(0x00, 0x20) - } - } - - /** - * @dev Derive the location of a mapping element from the key. - */ - function deriveMapping(bytes32 slot, address key) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, key) - mstore(0x20, slot) - result := keccak256(0x00, 0x40) - } - } - - /** - * @dev Derive the location of a mapping element from the key. - */ - function deriveMapping(bytes32 slot, bool key) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, key) - mstore(0x20, slot) - result := keccak256(0x00, 0x40) - } - } - - /** - * @dev Derive the location of a mapping element from the key. - */ - function deriveMapping(bytes32 slot, bytes32 key) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, key) - mstore(0x20, slot) - result := keccak256(0x00, 0x40) - } - } - - /** - * @dev Derive the location of a mapping element from the key. - */ - function deriveMapping(bytes32 slot, uint256 key) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, key) - mstore(0x20, slot) - result := keccak256(0x00, 0x40) - } - } - - /** - * @dev Derive the location of a mapping element from the key. - */ - function deriveMapping(bytes32 slot, int256 key) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, key) - mstore(0x20, slot) - result := keccak256(0x00, 0x40) - } - } - - /** - * @dev Derive the location of a mapping element from the key. - */ - function deriveMapping(bytes32 slot, string memory key) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let length := mload(key) - let begin := add(key, 0x20) - let end := add(begin, length) - let cache := mload(end) - mstore(end, slot) - result := keccak256(begin, add(length, 0x20)) - mstore(end, cache) - } - } - - /** - * @dev Derive the location of a mapping element from the key. - */ - function deriveMapping(bytes32 slot, bytes memory key) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let length := mload(key) - let begin := add(key, 0x20) - let end := add(begin, length) - let cache := mload(end) - mstore(end, slot) - result := keccak256(begin, add(length, 0x20)) - mstore(end, cache) - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol b/lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol deleted file mode 100644 index 85055ea..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol +++ /dev/null @@ -1,330 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/StorageSlot.sol) -// This file was procedurally generated from scripts/generate/templates/StorageSlot.js. - -pragma solidity ^0.8.24; - -/** - * @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 ERC-1967 implementation slot: - * ```solidity - * contract ERC1967 { - * // Define the slot. Alternatively, use the SlotDerivation library to derive the slot. - * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; - * - * function _getImplementation() internal view returns (address) { - * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; - * } - * - * function _setImplementation(address newImplementation) internal { - * require(newImplementation.code.length > 0); - * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; - * } - * } - * ``` - * - * Since version 5.1, this library also support writing and reading value types to and from transient storage. - * - * * Example using transient storage: - * ```solidity - * contract Lock { - * // Define the slot. Alternatively, use the SlotDerivation library to derive the slot. - * bytes32 internal constant _LOCK_SLOT = 0xf4678858b2b588224636b8522b729e7722d32fc491da849ed75b3fdf3c84f542; - * - * modifier locked() { - * require(!_LOCK_SLOT.asBoolean().tload()); - * - * _LOCK_SLOT.asBoolean().tstore(true); - * _; - * _LOCK_SLOT.asBoolean().tstore(false); - * } - * } - * ``` - * - * TIP: Consider using this library along with {SlotDerivation}. - */ -library StorageSlot { - struct AddressSlot { - address value; - } - - struct BooleanSlot { - bool value; - } - - struct Bytes32Slot { - bytes32 value; - } - - struct Uint256Slot { - uint256 value; - } - - struct Int256Slot { - int256 value; - } - - struct StringSlot { - string value; - } - - struct BytesSlot { - bytes 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 - } - } - - /** - * @dev Returns an `Int256Slot` with member `value` located at `slot`. - */ - function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) { - /// @solidity memory-safe-assembly - assembly { - r.slot := slot - } - } - - /** - * @dev Returns an `StringSlot` with member `value` located at `slot`. - */ - function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { - /// @solidity memory-safe-assembly - assembly { - r.slot := slot - } - } - - /** - * @dev Returns an `StringSlot` representation of the string storage pointer `store`. - */ - function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { - /// @solidity memory-safe-assembly - assembly { - r.slot := store.slot - } - } - - /** - * @dev Returns an `BytesSlot` with member `value` located at `slot`. - */ - function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { - /// @solidity memory-safe-assembly - assembly { - r.slot := slot - } - } - - /** - * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. - */ - function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { - /// @solidity memory-safe-assembly - assembly { - r.slot := store.slot - } - } - - /** - * @dev UDVT that represent a slot holding a address. - */ - type AddressSlotType is bytes32; - - /** - * @dev Cast an arbitrary slot to a AddressSlotType. - */ - function asAddress(bytes32 slot) internal pure returns (AddressSlotType) { - return AddressSlotType.wrap(slot); - } - - /** - * @dev UDVT that represent a slot holding a bool. - */ - type BooleanSlotType is bytes32; - - /** - * @dev Cast an arbitrary slot to a BooleanSlotType. - */ - function asBoolean(bytes32 slot) internal pure returns (BooleanSlotType) { - return BooleanSlotType.wrap(slot); - } - - /** - * @dev UDVT that represent a slot holding a bytes32. - */ - type Bytes32SlotType is bytes32; - - /** - * @dev Cast an arbitrary slot to a Bytes32SlotType. - */ - function asBytes32(bytes32 slot) internal pure returns (Bytes32SlotType) { - return Bytes32SlotType.wrap(slot); - } - - /** - * @dev UDVT that represent a slot holding a uint256. - */ - type Uint256SlotType is bytes32; - - /** - * @dev Cast an arbitrary slot to a Uint256SlotType. - */ - function asUint256(bytes32 slot) internal pure returns (Uint256SlotType) { - return Uint256SlotType.wrap(slot); - } - - /** - * @dev UDVT that represent a slot holding a int256. - */ - type Int256SlotType is bytes32; - - /** - * @dev Cast an arbitrary slot to a Int256SlotType. - */ - function asInt256(bytes32 slot) internal pure returns (Int256SlotType) { - return Int256SlotType.wrap(slot); - } - - /** - * @dev Load the value held at location `slot` in transient storage. - */ - function tload(AddressSlotType slot) internal view returns (address value) { - /// @solidity memory-safe-assembly - assembly { - value := tload(slot) - } - } - - /** - * @dev Store `value` at location `slot` in transient storage. - */ - function tstore(AddressSlotType slot, address value) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(slot, value) - } - } - - /** - * @dev Load the value held at location `slot` in transient storage. - */ - function tload(BooleanSlotType slot) internal view returns (bool value) { - /// @solidity memory-safe-assembly - assembly { - value := tload(slot) - } - } - - /** - * @dev Store `value` at location `slot` in transient storage. - */ - function tstore(BooleanSlotType slot, bool value) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(slot, value) - } - } - - /** - * @dev Load the value held at location `slot` in transient storage. - */ - function tload(Bytes32SlotType slot) internal view returns (bytes32 value) { - /// @solidity memory-safe-assembly - assembly { - value := tload(slot) - } - } - - /** - * @dev Store `value` at location `slot` in transient storage. - */ - function tstore(Bytes32SlotType slot, bytes32 value) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(slot, value) - } - } - - /** - * @dev Load the value held at location `slot` in transient storage. - */ - function tload(Uint256SlotType slot) internal view returns (uint256 value) { - /// @solidity memory-safe-assembly - assembly { - value := tload(slot) - } - } - - /** - * @dev Store `value` at location `slot` in transient storage. - */ - function tstore(Uint256SlotType slot, uint256 value) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(slot, value) - } - } - - /** - * @dev Load the value held at location `slot` in transient storage. - */ - function tload(Int256SlotType slot) internal view returns (int256 value) { - /// @solidity memory-safe-assembly - assembly { - value := tload(slot) - } - } - - /** - * @dev Store `value` at location `slot` in transient storage. - */ - function tstore(Int256SlotType slot, int256 value) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(slot, value) - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/Strings.sol b/lib/openzeppelin-contracts/contracts/utils/Strings.sol deleted file mode 100644 index 164d8ac..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/Strings.sol +++ /dev/null @@ -1,118 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol) - -pragma solidity ^0.8.20; - -import {Math} from "./math/Math.sol"; -import {SignedMath} from "./math/SignedMath.sol"; - -/** - * @dev String operations. - */ -library Strings { - bytes16 private constant HEX_DIGITS = "0123456789abcdef"; - uint8 private constant ADDRESS_LENGTH = 20; - - /** - * @dev The `value` string doesn't fit in the specified `length`. - */ - error StringsInsufficientHexLength(uint256 value, uint256 length); - - /** - * @dev Converts a `uint256` to its ASCII `string` decimal representation. - */ - function toString(uint256 value) internal pure returns (string memory) { - unchecked { - uint256 length = Math.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), HEX_DIGITS)) - } - value /= 10; - if (value == 0) break; - } - return buffer; - } - } - - /** - * @dev Converts a `int256` to its ASCII `string` decimal representation. - */ - function toStringSigned(int256 value) internal pure returns (string memory) { - return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value))); - } - - /** - * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. - */ - function toHexString(uint256 value) internal pure returns (string memory) { - unchecked { - return toHexString(value, Math.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) { - uint256 localValue = value; - 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_DIGITS[localValue & 0xf]; - localValue >>= 4; - } - if (localValue != 0) { - revert StringsInsufficientHexLength(value, length); - } - 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); - } - - /** - * @dev Converts an `address` with fixed length of 20 bytes to its checksummed ASCII `string` hexadecimal - * representation, according to EIP-55. - */ - function toChecksumHexString(address addr) internal pure returns (string memory) { - bytes memory buffer = bytes(toHexString(addr)); - - // hash the hex part of buffer (skip length + 2 bytes, length 40) - uint256 hashValue; - assembly ("memory-safe") { - hashValue := shr(96, keccak256(add(buffer, 0x22), 40)) - } - - for (uint256 i = 41; i > 1; --i) { - // possible values for buffer[i] are 48 (0) to 57 (9) and 97 (a) to 102 (f) - if (hashValue & 0xf > 7 && uint8(buffer[i]) > 96) { - // case shift by xoring with 0x20 - buffer[i] ^= 0x20; - } - hashValue >>= 4; - } - return string(buffer); - } - - /** - * @dev Returns true if the two strings are equal. - */ - function equal(string memory a, string memory b) internal pure returns (bool) { - return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b)); - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol b/lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol deleted file mode 100644 index 864c8ee..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol +++ /dev/null @@ -1,174 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/ECDSA.sol) - -pragma solidity ^0.8.20; - -/** - * @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 - } - - /** - * @dev The signature derives the `address(0)`. - */ - error ECDSAInvalidSignature(); - - /** - * @dev The signature has an invalid length. - */ - error ECDSAInvalidSignatureLength(uint256 length); - - /** - * @dev The signature has an S value that is in the upper half order. - */ - error ECDSAInvalidSignatureS(bytes32 s); - - /** - * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not - * return address(0) without also returning an error description. Errors are documented using an enum (error type) - * and a bytes32 providing additional information about the error. - * - * If no error is returned, then the address can be used for verification purposes. - * - * The `ecrecover` EVM precompile 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 {MessageHashUtils-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] - */ - function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError, bytes32) { - 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, bytes32(signature.length)); - } - } - - /** - * @dev Returns the address that signed a hashed message (`hash`) with - * `signature`. This address can then be used for verification purposes. - * - * The `ecrecover` EVM precompile 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 {MessageHashUtils-toEthSignedMessageHash} on it. - */ - function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { - (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature); - _throwError(error, errorArg); - 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[ERC-2098 short signatures] - */ - function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError, bytes32) { - unchecked { - bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); - // We do not check for an overflow here since the shift operation results in 0 or 1. - 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. - */ - function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { - (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs); - _throwError(error, errorArg); - return recovered; - } - - /** - * @dev Overload of {ECDSA-tryRecover} that receives the `v`, - * `r` and `s` signature fields separately. - */ - function tryRecover( - bytes32 hash, - uint8 v, - bytes32 r, - bytes32 s - ) internal pure returns (address, RecoverError, bytes32) { - // 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, s); - } - - // 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, bytes32(0)); - } - - return (signer, RecoverError.NoError, bytes32(0)); - } - - /** - * @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, bytes32 errorArg) = tryRecover(hash, v, r, s); - _throwError(error, errorArg); - return recovered; - } - - /** - * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided. - */ - function _throwError(RecoverError error, bytes32 errorArg) private pure { - if (error == RecoverError.NoError) { - return; // no error: do nothing - } else if (error == RecoverError.InvalidSignature) { - revert ECDSAInvalidSignature(); - } else if (error == RecoverError.InvalidSignatureLength) { - revert ECDSAInvalidSignatureLength(uint256(errorArg)); - } else if (error == RecoverError.InvalidSignatureS) { - revert ECDSAInvalidSignatureS(errorArg); - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/cryptography/EIP712.sol b/lib/openzeppelin-contracts/contracts/utils/cryptography/EIP712.sol deleted file mode 100644 index 77c4c89..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/cryptography/EIP712.sol +++ /dev/null @@ -1,160 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/EIP712.sol) - -pragma solidity ^0.8.20; - -import {MessageHashUtils} from "./MessageHashUtils.sol"; -import {ShortStrings, ShortString} from "../ShortStrings.sol"; -import {IERC5267} from "../../interfaces/IERC5267.sol"; - -/** - * @dev https://eips.ethereum.org/EIPS/eip-712[EIP-712] is a standard for hashing and signing of typed structured data. - * - * The encoding scheme specified in the EIP requires a domain separator and a hash of the typed structured data, whose - * encoding is very generic and therefore its 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 order to - * produce the hash of their typed data 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]. - * - * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain - * separator of the implementation contract. This will cause the {_domainSeparatorV4} function to always rebuild the - * separator from the immutable values, which is cheaper than accessing a cached version in cold storage. - * - * @custom:oz-upgrades-unsafe-allow state-variable-immutable - */ -abstract contract EIP712 is IERC5267 { - using ShortStrings for *; - - bytes32 private constant TYPE_HASH = - keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); - - // 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 _cachedDomainSeparator; - uint256 private immutable _cachedChainId; - address private immutable _cachedThis; - - bytes32 private immutable _hashedName; - bytes32 private immutable _hashedVersion; - - ShortString private immutable _name; - ShortString private immutable _version; - string private _nameFallback; - string private _versionFallback; - - /** - * @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) { - _name = name.toShortStringWithFallback(_nameFallback); - _version = version.toShortStringWithFallback(_versionFallback); - _hashedName = keccak256(bytes(name)); - _hashedVersion = keccak256(bytes(version)); - - _cachedChainId = block.chainid; - _cachedDomainSeparator = _buildDomainSeparator(); - _cachedThis = address(this); - } - - /** - * @dev Returns the domain separator for the current chain. - */ - function _domainSeparatorV4() internal view returns (bytes32) { - if (address(this) == _cachedThis && block.chainid == _cachedChainId) { - return _cachedDomainSeparator; - } else { - return _buildDomainSeparator(); - } - } - - function _buildDomainSeparator() private view returns (bytes32) { - return keccak256(abi.encode(TYPE_HASH, _hashedName, _hashedVersion, 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 MessageHashUtils.toTypedDataHash(_domainSeparatorV4(), structHash); - } - - /** - * @dev See {IERC-5267}. - */ - function eip712Domain() - public - view - virtual - returns ( - bytes1 fields, - string memory name, - string memory version, - uint256 chainId, - address verifyingContract, - bytes32 salt, - uint256[] memory extensions - ) - { - return ( - hex"0f", // 01111 - _EIP712Name(), - _EIP712Version(), - block.chainid, - address(this), - bytes32(0), - new uint256[](0) - ); - } - - /** - * @dev The name parameter for the EIP712 domain. - * - * NOTE: By default this function reads _name which is an immutable value. - * It only reads from storage if necessary (in case the value is too large to fit in a ShortString). - */ - // solhint-disable-next-line func-name-mixedcase - function _EIP712Name() internal view returns (string memory) { - return _name.toStringWithFallback(_nameFallback); - } - - /** - * @dev The version parameter for the EIP712 domain. - * - * NOTE: By default this function reads _version which is an immutable value. - * It only reads from storage if necessary (in case the value is too large to fit in a ShortString). - */ - // solhint-disable-next-line func-name-mixedcase - function _EIP712Version() internal view returns (string memory) { - return _version.toStringWithFallback(_versionFallback); - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/cryptography/Hashes.sol b/lib/openzeppelin-contracts/contracts/utils/cryptography/Hashes.sol deleted file mode 100644 index 434a849..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/cryptography/Hashes.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -/** - * @dev Library of standard hash functions. - */ -library Hashes { - /** - * @dev Commutative Keccak256 hash of a sorted pair of bytes32. Frequently used when working with merkle proofs. - * - * NOTE: Equivalent to the `standardNodeHash` in our https://github.com/OpenZeppelin/merkle-tree[JavaScript library]. - */ - function commutativeKeccak256(bytes32 a, bytes32 b) internal pure returns (bytes32) { - return a < b ? _efficientKeccak256(a, b) : _efficientKeccak256(b, a); - } - - /** - * @dev Implementation of keccak256(abi.encode(a, b)) that doesn't allocate or expand memory. - */ - function _efficientKeccak256(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/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol b/lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol deleted file mode 100644 index be19100..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol +++ /dev/null @@ -1,479 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MerkleProof.sol) -// This file was procedurally generated from scripts/generate/templates/MerkleProof.js. - -pragma solidity ^0.8.20; - -import {Hashes} from "./Hashes.sol"; - -/** - * @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. - * - * NOTE: This library supports proof verification for merkle trees built using - * custom _commutative_ hashing functions (i.e. `H(a, b) == H(b, a)`). Proving - * leaf inclusion in trees built using non-commutative hashing functions requires - * additional logic that is not supported by this library. - */ -library MerkleProof { - /** - *@dev The multiproof provided is not valid. - */ - error MerkleProofInvalidMultiproof(); - - /** - * @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. - * - * This version handles proofs in memory with the default hashing function. - */ - function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { - return processProof(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. - * - * This version handles proofs in memory with the default hashing function. - */ - function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { - bytes32 computedHash = leaf; - for (uint256 i = 0; i < proof.length; i++) { - computedHash = Hashes.commutativeKeccak256(computedHash, proof[i]); - } - return computedHash; - } - - /** - * @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. - * - * This version handles proofs in memory with a custom hashing function. - */ - function verify( - bytes32[] memory proof, - bytes32 root, - bytes32 leaf, - function(bytes32, bytes32) view returns (bytes32) hasher - ) internal view returns (bool) { - return processProof(proof, leaf, hasher) == 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. - * - * This version handles proofs in memory with a custom hashing function. - */ - function processProof( - bytes32[] memory proof, - bytes32 leaf, - function(bytes32, bytes32) view returns (bytes32) hasher - ) internal view returns (bytes32) { - bytes32 computedHash = leaf; - for (uint256 i = 0; i < proof.length; i++) { - computedHash = hasher(computedHash, proof[i]); - } - return computedHash; - } - - /** - * @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. - * - * This version handles proofs in calldata with the default hashing function. - */ - function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { - return processProof(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. - * - * This version handles proofs in calldata with the default hashing function. - */ - function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { - bytes32 computedHash = leaf; - for (uint256 i = 0; i < proof.length; i++) { - computedHash = Hashes.commutativeKeccak256(computedHash, proof[i]); - } - return computedHash; - } - - /** - * @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. - * - * This version handles proofs in calldata with a custom hashing function. - */ - function verifyCalldata( - bytes32[] calldata proof, - bytes32 root, - bytes32 leaf, - function(bytes32, bytes32) view returns (bytes32) hasher - ) internal view returns (bool) { - return processProof(proof, leaf, hasher) == 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. - * - * This version handles proofs in calldata with a custom hashing function. - */ - function processProofCalldata( - bytes32[] calldata proof, - bytes32 leaf, - function(bytes32, bytes32) view returns (bytes32) hasher - ) internal view returns (bytes32) { - bytes32 computedHash = leaf; - for (uint256 i = 0; i < proof.length; i++) { - computedHash = hasher(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}. - * - * This version handles multiproofs in memory with the default hashing function. - * - * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. - */ - function multiProofVerify( - bytes32[] memory proof, - bool[] memory proofFlags, - bytes32 root, - bytes32[] memory leaves - ) internal pure returns (bool) { - return processMultiProof(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. - * - * This version handles multiproofs in memory with the default hashing function. - * - * 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). - */ - function processMultiProof( - bytes32[] memory proof, - bool[] memory proofFlags, - bytes32[] memory leaves - ) internal pure returns (bytes32 merkleRoot) { - // This function rebuilds 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; - - // Check proof validity. - if (leavesLen + proof.length != proofFlags.length + 1) { - revert MerkleProofInvalidMultiproof(); - } - - // 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[](proofFlags.length); - 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 from the "main queue" (merging branches) or an element from the - // `proof` array. - for (uint256 i = 0; i < proofFlags.length; i++) { - bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; - bytes32 b = proofFlags[i] - ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) - : proof[proofPos++]; - hashes[i] = Hashes.commutativeKeccak256(a, b); - } - - if (proofFlags.length > 0) { - if (proofPos != proof.length) { - revert MerkleProofInvalidMultiproof(); - } - unchecked { - return hashes[proofFlags.length - 1]; - } - } else if (leavesLen > 0) { - return leaves[0]; - } else { - return proof[0]; - } - } - - /** - * @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}. - * - * This version handles multiproofs in memory with a custom hashing function. - * - * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. - */ - function multiProofVerify( - bytes32[] memory proof, - bool[] memory proofFlags, - bytes32 root, - bytes32[] memory leaves, - function(bytes32, bytes32) view returns (bytes32) hasher - ) internal view returns (bool) { - return processMultiProof(proof, proofFlags, leaves, hasher) == 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. - * - * This version handles multiproofs in memory with a custom hashing function. - * - * 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). - */ - function processMultiProof( - bytes32[] memory proof, - bool[] memory proofFlags, - bytes32[] memory leaves, - function(bytes32, bytes32) view returns (bytes32) hasher - ) internal view returns (bytes32 merkleRoot) { - // This function rebuilds 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; - - // Check proof validity. - if (leavesLen + proof.length != proofFlags.length + 1) { - revert MerkleProofInvalidMultiproof(); - } - - // 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[](proofFlags.length); - 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 from the "main queue" (merging branches) or an element from the - // `proof` array. - for (uint256 i = 0; i < proofFlags.length; i++) { - bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; - bytes32 b = proofFlags[i] - ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) - : proof[proofPos++]; - hashes[i] = hasher(a, b); - } - - if (proofFlags.length > 0) { - if (proofPos != proof.length) { - revert MerkleProofInvalidMultiproof(); - } - unchecked { - return hashes[proofFlags.length - 1]; - } - } else if (leavesLen > 0) { - return leaves[0]; - } else { - return proof[0]; - } - } - - /** - * @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}. - * - * This version handles multiproofs in calldata with the default hashing function. - * - * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. - */ - function multiProofVerifyCalldata( - bytes32[] calldata proof, - bool[] calldata proofFlags, - bytes32 root, - bytes32[] calldata leaves - ) internal pure returns (bool) { - return processMultiProof(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. - * - * This version handles multiproofs in calldata with the default hashing function. - * - * 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). - */ - function processMultiProofCalldata( - bytes32[] calldata proof, - bool[] calldata proofFlags, - bytes32[] calldata leaves - ) internal pure returns (bytes32 merkleRoot) { - // This function rebuilds 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; - - // Check proof validity. - if (leavesLen + proof.length != proofFlags.length + 1) { - revert MerkleProofInvalidMultiproof(); - } - - // 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[](proofFlags.length); - 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 from the "main queue" (merging branches) or an element from the - // `proof` array. - for (uint256 i = 0; i < proofFlags.length; i++) { - bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; - bytes32 b = proofFlags[i] - ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) - : proof[proofPos++]; - hashes[i] = Hashes.commutativeKeccak256(a, b); - } - - if (proofFlags.length > 0) { - if (proofPos != proof.length) { - revert MerkleProofInvalidMultiproof(); - } - unchecked { - return hashes[proofFlags.length - 1]; - } - } else if (leavesLen > 0) { - return leaves[0]; - } else { - return proof[0]; - } - } - - /** - * @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}. - * - * This version handles multiproofs in calldata with a custom hashing function. - * - * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. - */ - function multiProofVerifyCalldata( - bytes32[] calldata proof, - bool[] calldata proofFlags, - bytes32 root, - bytes32[] calldata leaves, - function(bytes32, bytes32) view returns (bytes32) hasher - ) internal view returns (bool) { - return processMultiProof(proof, proofFlags, leaves, hasher) == 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. - * - * This version handles multiproofs in calldata with a custom hashing function. - * - * 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). - */ - function processMultiProofCalldata( - bytes32[] calldata proof, - bool[] calldata proofFlags, - bytes32[] calldata leaves, - function(bytes32, bytes32) view returns (bytes32) hasher - ) internal view returns (bytes32 merkleRoot) { - // This function rebuilds 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; - - // Check proof validity. - if (leavesLen + proof.length != proofFlags.length + 1) { - revert MerkleProofInvalidMultiproof(); - } - - // 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[](proofFlags.length); - 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 from the "main queue" (merging branches) or an element from the - // `proof` array. - for (uint256 i = 0; i < proofFlags.length; i++) { - bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; - bytes32 b = proofFlags[i] - ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) - : proof[proofPos++]; - hashes[i] = hasher(a, b); - } - - if (proofFlags.length > 0) { - if (proofPos != proof.length) { - revert MerkleProofInvalidMultiproof(); - } - unchecked { - return hashes[proofFlags.length - 1]; - } - } else if (leavesLen > 0) { - return leaves[0]; - } else { - return proof[0]; - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/cryptography/MessageHashUtils.sol b/lib/openzeppelin-contracts/contracts/utils/cryptography/MessageHashUtils.sol deleted file mode 100644 index 45c2421..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/cryptography/MessageHashUtils.sol +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MessageHashUtils.sol) - -pragma solidity ^0.8.20; - -import {Strings} from "../Strings.sol"; - -/** - * @dev Signature message hash utilities for producing digests to be consumed by {ECDSA} recovery or signing. - * - * The library provides methods for generating a hash of a message that conforms to the - * https://eips.ethereum.org/EIPS/eip-191[ERC-191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712] - * specifications. - */ -library MessageHashUtils { - /** - * @dev Returns the keccak256 digest of an ERC-191 signed data with version - * `0x45` (`personal_sign` messages). - * - * The digest is calculated by prefixing a bytes32 `messageHash` with - * `"\x19Ethereum Signed Message:\n32"` and hashing the result. It corresponds with the - * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method. - * - * NOTE: The `messageHash` parameter is intended to be the result of hashing a raw message with - * keccak256, although any bytes32 value can be safely used because the final digest will - * be re-hashed. - * - * See {ECDSA-recover}. - */ - function toEthSignedMessageHash(bytes32 messageHash) internal pure returns (bytes32 digest) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, "\x19Ethereum Signed Message:\n32") // 32 is the bytes-length of messageHash - mstore(0x1c, messageHash) // 0x1c (28) is the length of the prefix - digest := keccak256(0x00, 0x3c) // 0x3c is the length of the prefix (0x1c) + messageHash (0x20) - } - } - - /** - * @dev Returns the keccak256 digest of an ERC-191 signed data with version - * `0x45` (`personal_sign` messages). - * - * The digest is calculated by prefixing an arbitrary `message` with - * `"\x19Ethereum Signed Message:\n" + len(message)` and hashing the result. It corresponds with the - * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method. - * - * See {ECDSA-recover}. - */ - function toEthSignedMessageHash(bytes memory message) internal pure returns (bytes32) { - return - keccak256(bytes.concat("\x19Ethereum Signed Message:\n", bytes(Strings.toString(message.length)), message)); - } - - /** - * @dev Returns the keccak256 digest of an ERC-191 signed data with version - * `0x00` (data with intended validator). - * - * The digest is calculated by prefixing an arbitrary `data` with `"\x19\x00"` and the intended - * `validator` address. Then hashing the result. - * - * See {ECDSA-recover}. - */ - function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { - return keccak256(abi.encodePacked(hex"19_00", validator, data)); - } - - /** - * @dev Returns the keccak256 digest of an EIP-712 typed data (ERC-191 version `0x01`). - * - * The digest is calculated from a `domainSeparator` and a `structHash`, by prefixing them with - * `\x19\x01` and hashing the result. It corresponds to the hash signed by the - * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] JSON-RPC method as part of EIP-712. - * - * See {ECDSA-recover}. - */ - function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 digest) { - /// @solidity memory-safe-assembly - assembly { - let ptr := mload(0x40) - mstore(ptr, hex"19_01") - mstore(add(ptr, 0x02), domainSeparator) - mstore(add(ptr, 0x22), structHash) - digest := keccak256(ptr, 0x42) - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/cryptography/P256.sol b/lib/openzeppelin-contracts/contracts/utils/cryptography/P256.sol deleted file mode 100644 index 83c9c97..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/cryptography/P256.sol +++ /dev/null @@ -1,316 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import {Math} from "../math/Math.sol"; -import {Errors} from "../Errors.sol"; - -/** - * @dev Implementation of secp256r1 verification and recovery functions. - * - * The secp256r1 curve (also known as P256) is a NIST standard curve with wide support in modern devices - * and cryptographic standards. Some notable examples include Apple's Secure Enclave and Android's Keystore - * as well as authentication protocols like FIDO2. - * - * Based on the original https://github.com/itsobvioustech/aa-passkeys-wallet/blob/main/src/Secp256r1.sol[implementation of itsobvioustech]. - * Heavily inspired in https://github.com/maxrobot/elliptic-solidity/blob/master/contracts/Secp256r1.sol[maxrobot] and - * https://github.com/tdrerup/elliptic-curve-solidity/blob/master/contracts/curves/EllipticCurve.sol[tdrerup] implementations. - */ -library P256 { - struct JPoint { - uint256 x; - uint256 y; - uint256 z; - } - - /// @dev Generator (x component) - uint256 internal constant GX = 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296; - /// @dev Generator (y component) - uint256 internal constant GY = 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5; - /// @dev P (size of the field) - uint256 internal constant P = 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF; - /// @dev N (order of G) - uint256 internal constant N = 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551; - /// @dev A parameter of the weierstrass equation - uint256 internal constant A = 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC; - /// @dev B parameter of the weierstrass equation - uint256 internal constant B = 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B; - - /// @dev (P + 1) / 4. Useful to compute sqrt - uint256 private constant P1DIV4 = 0x3fffffffc0000000400000000000000000000000400000000000000000000000; - - /// @dev N/2 for excluding higher order `s` values - uint256 private constant HALF_N = 0x7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a8; - - /** - * @dev Verifies a secp256r1 signature using the RIP-7212 precompile and falls back to the Solidity implementation - * if the precompile is not available. This version should work on all chains, but requires the deployment of more - * bytecode. - * - * @param h - hashed message - * @param r - signature half R - * @param s - signature half S - * @param qx - public key coordinate X - * @param qy - public key coordinate Y - * - * IMPORTANT: This function disallows signatures where the `s` value is above `N/2` to prevent malleability. - * To flip the `s` value, compute `s = N - s`. - */ - function verify(bytes32 h, bytes32 r, bytes32 s, bytes32 qx, bytes32 qy) internal view returns (bool) { - (bool valid, bool supported) = _tryVerifyNative(h, r, s, qx, qy); - return supported ? valid : verifySolidity(h, r, s, qx, qy); - } - - /** - * @dev Same as {verify}, but it will revert if the required precompile is not available. - * - * Make sure any logic (code or precompile) deployed at that address is the expected one, - * otherwise the returned value may be misinterpreted as a positive boolean. - */ - function verifyNative(bytes32 h, bytes32 r, bytes32 s, bytes32 qx, bytes32 qy) internal view returns (bool) { - (bool valid, bool supported) = _tryVerifyNative(h, r, s, qx, qy); - if (supported) { - return valid; - } else { - revert Errors.MissingPrecompile(address(0x100)); - } - } - - /** - * @dev Same as {verify}, but it will return false if the required precompile is not available. - */ - function _tryVerifyNative( - bytes32 h, - bytes32 r, - bytes32 s, - bytes32 qx, - bytes32 qy - ) private view returns (bool valid, bool supported) { - if (!_isProperSignature(r, s) || !isValidPublicKey(qx, qy)) { - return (false, true); // signature is invalid, and its not because the precompile is missing - } - - (bool success, bytes memory returndata) = address(0x100).staticcall(abi.encode(h, r, s, qx, qy)); - return (success && returndata.length == 0x20) ? (abi.decode(returndata, (bool)), true) : (false, false); - } - - /** - * @dev Same as {verify}, but only the Solidity implementation is used. - */ - function verifySolidity(bytes32 h, bytes32 r, bytes32 s, bytes32 qx, bytes32 qy) internal view returns (bool) { - if (!_isProperSignature(r, s) || !isValidPublicKey(qx, qy)) { - return false; - } - - JPoint[16] memory points = _preComputeJacobianPoints(uint256(qx), uint256(qy)); - uint256 w = Math.invModPrime(uint256(s), N); - uint256 u1 = mulmod(uint256(h), w, N); - uint256 u2 = mulmod(uint256(r), w, N); - (uint256 x, ) = _jMultShamir(points, u1, u2); - return ((x % N) == uint256(r)); - } - - /** - * @dev Public key recovery - * - * @param h - hashed message - * @param v - signature recovery param - * @param r - signature half R - * @param s - signature half S - * - * IMPORTANT: This function disallows signatures where the `s` value is above `N/2` to prevent malleability. - * To flip the `s` value, compute `s = N - s` and `v = 1 - v` if (`v = 0 | 1`). - */ - function recovery(bytes32 h, uint8 v, bytes32 r, bytes32 s) internal view returns (bytes32, bytes32) { - if (!_isProperSignature(r, s) || v > 1) { - return (0, 0); - } - - uint256 rx = uint256(r); - uint256 ry2 = addmod(mulmod(addmod(mulmod(rx, rx, P), A, P), rx, P), B, P); // weierstrass equation y² = x³ + a.x + b - uint256 ry = Math.modExp(ry2, P1DIV4, P); // This formula for sqrt work because P ≡ 3 (mod 4) - if (mulmod(ry, ry, P) != ry2) return (0, 0); // Sanity check - if (ry % 2 != v % 2) ry = P - ry; - - JPoint[16] memory points = _preComputeJacobianPoints(rx, ry); - uint256 w = Math.invModPrime(uint256(r), N); - uint256 u1 = mulmod(N - (uint256(h) % N), w, N); - uint256 u2 = mulmod(uint256(s), w, N); - (uint256 x, uint256 y) = _jMultShamir(points, u1, u2); - return (bytes32(x), bytes32(y)); - } - - /** - * @dev Checks if (x, y) are valid coordinates of a point on the curve. - * In particular this function checks that x <= P and y <= P. - */ - function isValidPublicKey(bytes32 x, bytes32 y) internal pure returns (bool result) { - assembly ("memory-safe") { - let p := P - let lhs := mulmod(y, y, p) // y^2 - let rhs := addmod(mulmod(addmod(mulmod(x, x, p), A, p), x, p), B, p) // ((x^2 + a) * x) + b = x^3 + ax + b - result := and(and(lt(x, p), lt(y, p)), eq(lhs, rhs)) // Should conform with the Weierstrass equation - } - } - - /** - * @dev Checks if (r, s) is a proper signature. - * In particular, this checks that `s` is in the "lower-range", making the signature non-malleable. - */ - function _isProperSignature(bytes32 r, bytes32 s) private pure returns (bool) { - return uint256(r) > 0 && uint256(r) < N && uint256(s) > 0 && uint256(s) <= HALF_N; - } - - /** - * @dev Reduce from jacobian to affine coordinates - * @param jx - jacobian coordinate x - * @param jy - jacobian coordinate y - * @param jz - jacobian coordinate z - * @return ax - affine coordinate x - * @return ay - affine coordinate y - */ - function _affineFromJacobian(uint256 jx, uint256 jy, uint256 jz) private view returns (uint256 ax, uint256 ay) { - if (jz == 0) return (0, 0); - uint256 zinv = Math.invModPrime(jz, P); - uint256 zzinv = mulmod(zinv, zinv, P); - uint256 zzzinv = mulmod(zzinv, zinv, P); - ax = mulmod(jx, zzinv, P); - ay = mulmod(jy, zzzinv, P); - } - - /** - * @dev Point addition on the jacobian coordinates - * Reference: https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#addition-add-1998-cmo-2 - */ - function _jAdd( - JPoint memory p1, - uint256 x2, - uint256 y2, - uint256 z2 - ) private pure returns (uint256 rx, uint256 ry, uint256 rz) { - assembly ("memory-safe") { - let p := P - let z1 := mload(add(p1, 0x40)) - let s1 := mulmod(mload(add(p1, 0x20)), mulmod(mulmod(z2, z2, p), z2, p), p) // s1 = y1*z2³ - let s2 := mulmod(y2, mulmod(mulmod(z1, z1, p), z1, p), p) // s2 = y2*z1³ - let r := addmod(s2, sub(p, s1), p) // r = s2-s1 - let u1 := mulmod(mload(p1), mulmod(z2, z2, p), p) // u1 = x1*z2² - let u2 := mulmod(x2, mulmod(z1, z1, p), p) // u2 = x2*z1² - let h := addmod(u2, sub(p, u1), p) // h = u2-u1 - let hh := mulmod(h, h, p) // h² - - // x' = r²-h³-2*u1*h² - rx := addmod( - addmod(mulmod(r, r, p), sub(p, mulmod(h, hh, p)), p), - sub(p, mulmod(2, mulmod(u1, hh, p), p)), - p - ) - // y' = r*(u1*h²-x')-s1*h³ - ry := addmod( - mulmod(r, addmod(mulmod(u1, hh, p), sub(p, rx), p), p), - sub(p, mulmod(s1, mulmod(h, hh, p), p)), - p - ) - // z' = h*z1*z2 - rz := mulmod(h, mulmod(z1, z2, p), p) - } - } - - /** - * @dev Point doubling on the jacobian coordinates - * Reference: https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-1998-cmo-2 - */ - function _jDouble(uint256 x, uint256 y, uint256 z) private pure returns (uint256 rx, uint256 ry, uint256 rz) { - assembly ("memory-safe") { - let p := P - let yy := mulmod(y, y, p) - let zz := mulmod(z, z, p) - let s := mulmod(4, mulmod(x, yy, p), p) // s = 4*x*y² - let m := addmod(mulmod(3, mulmod(x, x, p), p), mulmod(A, mulmod(zz, zz, p), p), p) // m = 3*x²+a*z⁴ - let t := addmod(mulmod(m, m, p), sub(p, mulmod(2, s, p)), p) // t = m²-2*s - - // x' = t - rx := t - // y' = m*(s-t)-8*y⁴ - ry := addmod(mulmod(m, addmod(s, sub(p, t), p), p), sub(p, mulmod(8, mulmod(yy, yy, p), p)), p) - // z' = 2*y*z - rz := mulmod(2, mulmod(y, z, p), p) - } - } - - /** - * @dev Compute P·u1 + Q·u2 using the precomputed points for P and Q (see {_preComputeJacobianPoints}). - * - * Uses Strauss Shamir trick for EC multiplication - * https://stackoverflow.com/questions/50993471/ec-scalar-multiplication-with-strauss-shamir-method - * we optimise on this a bit to do with 2 bits at a time rather than a single bit - * the individual points for a single pass are precomputed - * overall this reduces the number of additions while keeping the same number of doublings - */ - function _jMultShamir(JPoint[16] memory points, uint256 u1, uint256 u2) private view returns (uint256, uint256) { - uint256 x = 0; - uint256 y = 0; - uint256 z = 0; - unchecked { - for (uint256 i = 0; i < 128; ++i) { - if (z > 0) { - (x, y, z) = _jDouble(x, y, z); - (x, y, z) = _jDouble(x, y, z); - } - // Read 2 bits of u1, and 2 bits of u2. Combining the two give a lookup index in the table. - uint256 pos = ((u1 >> 252) & 0xc) | ((u2 >> 254) & 0x3); - if (pos > 0) { - if (z == 0) { - (x, y, z) = (points[pos].x, points[pos].y, points[pos].z); - } else { - (x, y, z) = _jAdd(points[pos], x, y, z); - } - } - u1 <<= 2; - u2 <<= 2; - } - } - return _affineFromJacobian(x, y, z); - } - - /** - * @dev Precompute a matrice of useful jacobian points associated with a given P. This can be seen as a 4x4 matrix - * that contains combination of P and G (generator) up to 3 times each. See the table below: - * - * ┌────┬─────────────────────┐ - * │ i │ 0 1 2 3 │ - * ├────┼─────────────────────┤ - * │ 0 │ 0 p 2p 3p │ - * │ 4 │ g g+p g+2p g+3p │ - * │ 8 │ 2g 2g+p 2g+2p 2g+3p │ - * │ 12 │ 3g 3g+p 3g+2p 3g+3p │ - * └────┴─────────────────────┘ - */ - function _preComputeJacobianPoints(uint256 px, uint256 py) private pure returns (JPoint[16] memory points) { - points[0x00] = JPoint(0, 0, 0); // 0,0 - points[0x01] = JPoint(px, py, 1); // 1,0 (p) - points[0x04] = JPoint(GX, GY, 1); // 0,1 (g) - points[0x02] = _jDoublePoint(points[0x01]); // 2,0 (2p) - points[0x08] = _jDoublePoint(points[0x04]); // 0,2 (2g) - points[0x03] = _jAddPoint(points[0x01], points[0x02]); // 3,0 (3p) - points[0x05] = _jAddPoint(points[0x01], points[0x04]); // 1,1 (p+g) - points[0x06] = _jAddPoint(points[0x02], points[0x04]); // 2,1 (2p+g) - points[0x07] = _jAddPoint(points[0x03], points[0x04]); // 3,1 (3p+g) - points[0x09] = _jAddPoint(points[0x01], points[0x08]); // 1,2 (p+2g) - points[0x0a] = _jAddPoint(points[0x02], points[0x08]); // 2,2 (2p+2g) - points[0x0b] = _jAddPoint(points[0x03], points[0x08]); // 3,2 (3p+2g) - points[0x0c] = _jAddPoint(points[0x04], points[0x08]); // 0,3 (g+2g) - points[0x0d] = _jAddPoint(points[0x01], points[0x0c]); // 1,3 (p+3g) - points[0x0e] = _jAddPoint(points[0x02], points[0x0c]); // 2,3 (2p+3g) - points[0x0f] = _jAddPoint(points[0x03], points[0x0C]); // 3,3 (3p+3g) - } - - function _jAddPoint(JPoint memory p1, JPoint memory p2) private pure returns (JPoint memory) { - (uint256 x, uint256 y, uint256 z) = _jAdd(p1, p2.x, p2.y, p2.z); - return JPoint(x, y, z); - } - - function _jDoublePoint(JPoint memory p) private pure returns (JPoint memory) { - (uint256 x, uint256 y, uint256 z) = _jDouble(p.x, p.y, p.z); - return JPoint(x, y, z); - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/cryptography/RSA.sol b/lib/openzeppelin-contracts/contracts/utils/cryptography/RSA.sol deleted file mode 100644 index 105853a..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/cryptography/RSA.sol +++ /dev/null @@ -1,145 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import {Math} from "../math/Math.sol"; - -/** - * @dev RSA PKCS#1 v1.5 signature verification implementation according to https://datatracker.ietf.org/doc/html/rfc8017[RFC8017]. - * - * This library supports PKCS#1 v1.5 padding to avoid malleability via chosen plaintext attacks in practical implementations. - * The padding follows the EMSA-PKCS1-v1_5-ENCODE encoding definition as per section 9.2 of the RFC. This padding makes - * RSA semanticaly secure for signing messages. - * - * Inspired by https://github.com/adria0/SolRsaVerify[Adrià Massanet's work] - */ -library RSA { - /** - * @dev Same as {pkcs1} but using SHA256 to calculate the digest of `data`. - */ - function pkcs1Sha256( - bytes memory data, - bytes memory s, - bytes memory e, - bytes memory n - ) internal view returns (bool) { - return pkcs1(sha256(data), s, e, n); - } - - /** - * @dev Verifies a PKCSv1.5 signature given a digest according the verification - * method described in https://datatracker.ietf.org/doc/html/rfc8017#section-8.2.2[section 8.2.2 of RFC8017]. - * - * IMPORTANT: Although this function allows for it, using n of length 1024 bits is considered unsafe. - * Consider using at least 2048 bits. - * - * WARNING: PKCS#1 v1.5 allows for replayability given the message may contain arbitrary optional parameters in the - * DigestInfo. Consider using an onchain nonce or unique identifier to include in the message to prevent replay attacks. - * - * @param digest the digest to verify - * @param s is a buffer containing the signature - * @param e is the exponent of the public key - * @param n is the modulus of the public key - */ - function pkcs1(bytes32 digest, bytes memory s, bytes memory e, bytes memory n) internal view returns (bool) { - unchecked { - // cache and check length - uint256 length = n.length; - if ( - length < 0x40 || // PKCS#1 padding is slightly less than 0x40 bytes at the bare minimum - length != s.length // signature must have the same length as the finite field - ) { - return false; - } - - // Verify that s < n to ensure there's only one valid signature for a given message - for (uint256 i = 0; i < length; i += 0x20) { - uint256 p = Math.min(i, length - 0x20); - bytes32 sp = _unsafeReadBytes32(s, p); - bytes32 np = _unsafeReadBytes32(n, p); - if (sp < np) { - // s < n in the upper bits (everything before is equal) → s < n globally: ok - break; - } else if (sp > np || p == length - 0x20) { - // s > n in the upper bits (everything before is equal) → s > n globally: fail - // or - // s = n and we are looking at the lower bits → s = n globally: fail - return false; - } - } - - // RSAVP1 https://datatracker.ietf.org/doc/html/rfc8017#section-5.2.2 - // The previous check guarantees that n > 0. Therefore modExp cannot revert. - bytes memory buffer = Math.modExp(s, e, n); - - // Check that buffer is well encoded: - // buffer ::= 0x00 | 0x01 | PS | 0x00 | DigestInfo - // - // With - // - PS is padding filled with 0xFF - // - DigestInfo ::= SEQUENCE { - // digestAlgorithm AlgorithmIdentifier, - // [optional algorithm parameters] - // digest OCTET STRING - // } - - // Get AlgorithmIdentifier from the DigestInfo, and set the config accordingly - // - params: includes 00 + first part of DigestInfo - // - mask: filter to check the params - // - offset: length of the suffix (including digest) - bytes32 params; // 0x00 | DigestInfo - bytes32 mask; - uint256 offset; - - // Digest is expected at the end of the buffer. Therefore if NULL param is present, - // it should be at 32 (digest) + 2 bytes from the end. To those 34 bytes, we add the - // OID (9 bytes) and its length (2 bytes) to get the position of the DigestInfo sequence, - // which is expected to have a length of 0x31 when the NULL param is present or 0x2f if not. - if (bytes1(_unsafeReadBytes32(buffer, length - 50)) == 0x31) { - offset = 0x34; - // 00 (1 byte) | SEQUENCE length (0x31) = 3031 (2 bytes) | SEQUENCE length (0x0d) = 300d (2 bytes) | OBJECT_IDENTIFIER length (0x09) = 0609 (2 bytes) - // SHA256 OID = 608648016503040201 (9 bytes) | NULL = 0500 (2 bytes) (explicit) | OCTET_STRING length (0x20) = 0420 (2 bytes) - params = 0x003031300d060960864801650304020105000420000000000000000000000000; - mask = 0xffffffffffffffffffffffffffffffffffffffff000000000000000000000000; // (20 bytes) - } else if (bytes1(_unsafeReadBytes32(buffer, length - 48)) == 0x2F) { - offset = 0x32; - // 00 (1 byte) | SEQUENCE length (0x2f) = 302f (2 bytes) | SEQUENCE length (0x0b) = 300b (2 bytes) | OBJECT_IDENTIFIER length (0x09) = 0609 (2 bytes) - // SHA256 OID = 608648016503040201 (9 bytes) | NULL = | OCTET_STRING length (0x20) = 0420 (2 bytes) - params = 0x00302f300b060960864801650304020104200000000000000000000000000000; - mask = 0xffffffffffffffffffffffffffffffffffff0000000000000000000000000000; // (18 bytes) - } else { - // unknown - return false; - } - - // Length is at least 0x40 and offset is at most 0x34, so this is safe. There is always some padding. - uint256 paddingEnd = length - offset; - - // The padding has variable (arbitrary) length, so we check it byte per byte in a loop. - // This is required to ensure non-malleability. Not checking would allow an attacker to - // use the padding to manipulate the message in order to create a valid signature out of - // multiple valid signatures. - for (uint256 i = 2; i < paddingEnd; ++i) { - if (bytes1(_unsafeReadBytes32(buffer, i)) != 0xFF) { - return false; - } - } - - // All the other parameters are small enough to fit in a bytes32, so we can check them directly. - return - bytes2(0x0001) == bytes2(_unsafeReadBytes32(buffer, 0x00)) && // 00 | 01 - // PS was checked in the loop - params == _unsafeReadBytes32(buffer, paddingEnd) & mask && // DigestInfo - // Optional parameters are not checked - digest == _unsafeReadBytes32(buffer, length - 0x20); // Digest - } - } - - /// @dev Reads a bytes32 from a bytes array without bounds checking. - function _unsafeReadBytes32(bytes memory array, uint256 offset) private pure returns (bytes32 result) { - // Memory safetiness is guaranteed as long as the provided `array` is a Solidity-allocated bytes array - // and `offset` is within bounds. This is the case for all calls to this private function from {pkcs1}. - assembly ("memory-safe") { - result := mload(add(add(array, 0x20), offset)) - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sol b/lib/openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sol deleted file mode 100644 index 9aaa2e0..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sol +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/SignatureChecker.sol) - -pragma solidity ^0.8.20; - -import {ECDSA} from "./ECDSA.sol"; -import {IERC1271} from "../../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 ERC-1271 signatures from smart contract wallets like - * Argent and Safe Wallet (previously Gnosis Safe). - */ -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 ERC-1271, 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) { - if (signer.code.length == 0) { - (address recovered, ECDSA.RecoverError err, ) = ECDSA.tryRecover(hash, signature); - return err == ECDSA.RecoverError.NoError && recovered == signer; - } else { - return isValidERC1271SignatureNow(signer, hash, signature); - } - } - - /** - * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated - * against the signer smart contract using ERC-1271. - * - * 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 isValidERC1271SignatureNow( - address signer, - bytes32 hash, - bytes memory signature - ) internal view returns (bool) { - (bool success, bytes memory result) = signer.staticcall( - abi.encodeCall(IERC1271.isValidSignature, (hash, signature)) - ); - return (success && - result.length >= 32 && - abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector)); - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol b/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol deleted file mode 100644 index 664b39f..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol) - -pragma solidity ^0.8.20; - -import {IERC165} from "./IERC165.sol"; - -/** - * @dev Implementation of the {IERC165} interface. - * - * Contracts that want to implement ERC-165 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); - * } - * ``` - */ -abstract contract ERC165 is IERC165 { - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { - return interfaceId == type(IERC165).interfaceId; - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Checker.sol b/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Checker.sol deleted file mode 100644 index da729ca..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Checker.sol +++ /dev/null @@ -1,124 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165Checker.sol) - -pragma solidity ^0.8.20; - -import {IERC165} from "./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 ERC-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 ERC-165 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 ERC-165 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}. - */ - 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 ERC-165 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 ERC-165 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 ERC-165 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 ERC-165, 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.encodeCall(IERC165.supportsInterface, (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/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol b/lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol deleted file mode 100644 index bfbdf5d..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol) - -pragma solidity ^0.8.20; - -/** - * @dev Interface of the ERC-165 standard, as defined in the - * https://eips.ethereum.org/EIPS/eip-165[ERC]. - * - * 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[ERC 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/openzeppelin-contracts/contracts/utils/math/Math.sol b/lib/openzeppelin-contracts/contracts/utils/math/Math.sol deleted file mode 100644 index d5ae271..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/math/Math.sol +++ /dev/null @@ -1,687 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol) - -pragma solidity ^0.8.20; - -import {Panic} from "../Panic.sol"; -import {SafeCast} from "./SafeCast.sol"; - -/** - * @dev Standard math utilities missing in the Solidity language. - */ -library Math { - enum Rounding { - Floor, // Toward negative infinity - Ceil, // Toward positive infinity - Trunc, // Toward zero - Expand // Away from zero - } - - /** - * @dev Returns the addition of two unsigned integers, with an success flag (no overflow). - */ - function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { - unchecked { - uint256 c = a + b; - if (c < a) return (false, 0); - return (true, c); - } - } - - /** - * @dev Returns the subtraction of two unsigned integers, with an success flag (no overflow). - */ - function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { - unchecked { - if (b > a) return (false, 0); - return (true, a - b); - } - } - - /** - * @dev Returns the multiplication of two unsigned integers, with an success flag (no overflow). - */ - function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { - 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 success flag (no division by zero). - */ - function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { - unchecked { - if (b == 0) return (false, 0); - return (true, a / b); - } - } - - /** - * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero). - */ - function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { - unchecked { - if (b == 0) return (false, 0); - return (true, a % b); - } - } - - /** - * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant. - * - * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone. - * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute - * one branch when needed, making this function more expensive. - */ - function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) { - unchecked { - // branchless ternary works because: - // b ^ (a ^ b) == a - // b ^ 0 == b - return b ^ ((a ^ b) * SafeCast.toUint(condition)); - } - } - - /** - * @dev Returns the largest of two numbers. - */ - function max(uint256 a, uint256 b) internal pure returns (uint256) { - return ternary(a > b, a, b); - } - - /** - * @dev Returns the smallest of two numbers. - */ - function min(uint256 a, uint256 b) internal pure returns (uint256) { - return ternary(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 towards infinity instead - * of rounding towards zero. - */ - function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { - if (b == 0) { - // Guarantee the same behavior as in a regular Solidity division. - Panic.panic(Panic.DIVISION_BY_ZERO); - } - - // The following calculation ensures accurate ceiling division without overflow. - // Since a is non-zero, (a - 1) / b will not overflow. - // The largest possible result occurs when (a - 1) / b is type(uint256).max, - // but the largest value we can obtain is type(uint256).max - 1, which happens - // when a = type(uint256).max and b = 1. - unchecked { - return SafeCast.toUint(a > 0) * ((a - 1) / b + 1); - } - } - - /** - * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or - * denominator == 0. - * - * 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²⁵⁶ and mod 2²⁵⁶ - 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²⁵⁶ + prod0. - uint256 prod0 = x * y; // Least significant 256 bits of the product - uint256 prod1; // Most significant 256 bits of the product - assembly { - let mm := mulmod(x, y, not(0)) - prod1 := sub(sub(mm, prod0), lt(mm, prod0)) - } - - // Handle non-overflow cases, 256 by 256 division. - if (prod1 == 0) { - // Solidity will revert if denominator == 0, unlike the div opcode on its own. - // The surrounding unchecked block does not change this fact. - // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. - return prod0 / denominator; - } - - // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0. - if (denominator <= prod1) { - Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW)); - } - - /////////////////////////////////////////////// - // 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. - - uint256 twos = denominator & (0 - denominator); - 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²⁵⁶ / 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²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such - // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for - // four bits. That is, denominator * inv ≡ 1 mod 2⁴. - 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⁸ - inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶ - inverse *= 2 - denominator * inverse; // inverse mod 2³² - inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴ - inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸ - inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶ - - // 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²⁵⁶. Since the preconditions guarantee that the outcome is - // less than 2²⁵⁶, 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; - } - } - - /** - * @dev 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) { - return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0); - } - - /** - * @dev Calculate the modular multiplicative inverse of a number in Z/nZ. - * - * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, expect 0. - * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible. - * - * If the input value is not inversible, 0 is returned. - * - * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the - * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}. - */ - function invMod(uint256 a, uint256 n) internal pure returns (uint256) { - unchecked { - if (n == 0) return 0; - - // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version) - // Used to compute integers x and y such that: ax + ny = gcd(a, n). - // When the gcd is 1, then the inverse of a modulo n exists and it's x. - // ax + ny = 1 - // ax = 1 + (-y)n - // ax ≡ 1 (mod n) # x is the inverse of a modulo n - - // If the remainder is 0 the gcd is n right away. - uint256 remainder = a % n; - uint256 gcd = n; - - // Therefore the initial coefficients are: - // ax + ny = gcd(a, n) = n - // 0a + 1n = n - int256 x = 0; - int256 y = 1; - - while (remainder != 0) { - uint256 quotient = gcd / remainder; - - (gcd, remainder) = ( - // The old remainder is the next gcd to try. - remainder, - // Compute the next remainder. - // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd - // where gcd is at most n (capped to type(uint256).max) - gcd - remainder * quotient - ); - - (x, y) = ( - // Increment the coefficient of a. - y, - // Decrement the coefficient of n. - // Can overflow, but the result is casted to uint256 so that the - // next value of y is "wrapped around" to a value between 0 and n - 1. - x - y * int256(quotient) - ); - } - - if (gcd != 1) return 0; // No inverse exists. - return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative. - } - } - - /** - * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`. - * - * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is - * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that - * `a**(p-2)` is the modular multiplicative inverse of a in Fp. - * - * NOTE: this function does NOT check that `p` is a prime greater than `2`. - */ - function invModPrime(uint256 a, uint256 p) internal view returns (uint256) { - unchecked { - return Math.modExp(a, p - 2, p); - } - } - - /** - * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m) - * - * Requirements: - * - modulus can't be zero - * - underlying staticcall to precompile must succeed - * - * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make - * sure the chain you're using it on supports the precompiled contract for modular exponentiation - * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, - * the underlying function will succeed given the lack of a revert, but the result may be incorrectly - * interpreted as 0. - */ - function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) { - (bool success, uint256 result) = tryModExp(b, e, m); - if (!success) { - Panic.panic(Panic.DIVISION_BY_ZERO); - } - return result; - } - - /** - * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m). - * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying - * to operate modulo 0 or if the underlying precompile reverted. - * - * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain - * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in - * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack - * of a revert, but the result may be incorrectly interpreted as 0. - */ - function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) { - if (m == 0) return (false, 0); - /// @solidity memory-safe-assembly - assembly { - let ptr := mload(0x40) - // | Offset | Content | Content (Hex) | - // |-----------|------------|--------------------------------------------------------------------| - // | 0x00:0x1f | size of b | 0x0000000000000000000000000000000000000000000000000000000000000020 | - // | 0x20:0x3f | size of e | 0x0000000000000000000000000000000000000000000000000000000000000020 | - // | 0x40:0x5f | size of m | 0x0000000000000000000000000000000000000000000000000000000000000020 | - // | 0x60:0x7f | value of b | 0x<.............................................................b> | - // | 0x80:0x9f | value of e | 0x<.............................................................e> | - // | 0xa0:0xbf | value of m | 0x<.............................................................m> | - mstore(ptr, 0x20) - mstore(add(ptr, 0x20), 0x20) - mstore(add(ptr, 0x40), 0x20) - mstore(add(ptr, 0x60), b) - mstore(add(ptr, 0x80), e) - mstore(add(ptr, 0xa0), m) - - // Given the result < m, it's guaranteed to fit in 32 bytes, - // so we can use the memory scratch space located at offset 0. - success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20) - result := mload(0x00) - } - } - - /** - * @dev Variant of {modExp} that supports inputs of arbitrary length. - */ - function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) { - (bool success, bytes memory result) = tryModExp(b, e, m); - if (!success) { - Panic.panic(Panic.DIVISION_BY_ZERO); - } - return result; - } - - /** - * @dev Variant of {tryModExp} that supports inputs of arbitrary length. - */ - function tryModExp( - bytes memory b, - bytes memory e, - bytes memory m - ) internal view returns (bool success, bytes memory result) { - if (_zeroBytes(m)) return (false, new bytes(0)); - - uint256 mLen = m.length; - - // Encode call args in result and move the free memory pointer - result = abi.encodePacked(b.length, e.length, mLen, b, e, m); - - /// @solidity memory-safe-assembly - assembly { - let dataPtr := add(result, 0x20) - // Write result on top of args to avoid allocating extra memory. - success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen) - // Overwrite the length. - // result.length > returndatasize() is guaranteed because returndatasize() == m.length - mstore(result, mLen) - // Set the memory pointer after the returned data. - mstore(0x40, add(dataPtr, mLen)) - } - } - - /** - * @dev Returns whether the provided byte array is zero. - */ - function _zeroBytes(bytes memory byteArray) private pure returns (bool) { - for (uint256 i = 0; i < byteArray.length; ++i) { - if (byteArray[i] != 0) { - return false; - } - } - return true; - } - - /** - * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded - * towards zero. - * - * This method is based on Newton's method for computing square roots; the algorithm is restricted to only - * using integer operations. - */ - function sqrt(uint256 a) internal pure returns (uint256) { - unchecked { - // Take care of easy edge cases when a == 0 or a == 1 - if (a <= 1) { - return a; - } - - // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a - // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between - // the current value as `ε_n = | x_n - sqrt(a) |`. - // - // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root - // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is - // bigger than any uint256. - // - // By noticing that - // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)` - // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar - // to the msb function. - uint256 aa = a; - uint256 xn = 1; - - if (aa >= (1 << 128)) { - aa >>= 128; - xn <<= 64; - } - if (aa >= (1 << 64)) { - aa >>= 64; - xn <<= 32; - } - if (aa >= (1 << 32)) { - aa >>= 32; - xn <<= 16; - } - if (aa >= (1 << 16)) { - aa >>= 16; - xn <<= 8; - } - if (aa >= (1 << 8)) { - aa >>= 8; - xn <<= 4; - } - if (aa >= (1 << 4)) { - aa >>= 4; - xn <<= 2; - } - if (aa >= (1 << 2)) { - xn <<= 1; - } - - // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1). - // - // We can refine our estimation by noticing that the middle of that interval minimizes the error. - // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2). - // This is going to be our x_0 (and ε_0) - xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2) - - // From here, Newton's method give us: - // x_{n+1} = (x_n + a / x_n) / 2 - // - // One should note that: - // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a - // = ((x_n² + a) / (2 * x_n))² - a - // = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a - // = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²) - // = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²) - // = (x_n² - a)² / (2 * x_n)² - // = ((x_n² - a) / (2 * x_n))² - // ≥ 0 - // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n - // - // This gives us the proof of quadratic convergence of the sequence: - // ε_{n+1} = | x_{n+1} - sqrt(a) | - // = | (x_n + a / x_n) / 2 - sqrt(a) | - // = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) | - // = | (x_n - sqrt(a))² / (2 * x_n) | - // = | ε_n² / (2 * x_n) | - // = ε_n² / | (2 * x_n) | - // - // For the first iteration, we have a special case where x_0 is known: - // ε_1 = ε_0² / | (2 * x_0) | - // ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2))) - // ≤ 2**(2*e-4) / (3 * 2**(e-1)) - // ≤ 2**(e-3) / 3 - // ≤ 2**(e-3-log2(3)) - // ≤ 2**(e-4.5) - // - // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n: - // ε_{n+1} = ε_n² / | (2 * x_n) | - // ≤ (2**(e-k))² / (2 * 2**(e-1)) - // ≤ 2**(2*e-2*k) / 2**e - // ≤ 2**(e-2*k) - xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5) -- special case, see above - xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9) -- general case with k = 4.5 - xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18) -- general case with k = 9 - xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36) -- general case with k = 18 - xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72) -- general case with k = 36 - xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144) -- general case with k = 72 - - // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision - // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either - // sqrt(a) or sqrt(a) + 1. - return xn - SafeCast.toUint(xn > a / xn); - } - } - - /** - * @dev 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 + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a); - } - } - - /** - * @dev Return the log in base 2 of a positive value rounded towards zero. - * Returns 0 if given 0. - */ - function log2(uint256 value) internal pure returns (uint256) { - uint256 result = 0; - uint256 exp; - unchecked { - exp = 128 * SafeCast.toUint(value > (1 << 128) - 1); - value >>= exp; - result += exp; - - exp = 64 * SafeCast.toUint(value > (1 << 64) - 1); - value >>= exp; - result += exp; - - exp = 32 * SafeCast.toUint(value > (1 << 32) - 1); - value >>= exp; - result += exp; - - exp = 16 * SafeCast.toUint(value > (1 << 16) - 1); - value >>= exp; - result += exp; - - exp = 8 * SafeCast.toUint(value > (1 << 8) - 1); - value >>= exp; - result += exp; - - exp = 4 * SafeCast.toUint(value > (1 << 4) - 1); - value >>= exp; - result += exp; - - exp = 2 * SafeCast.toUint(value > (1 << 2) - 1); - value >>= exp; - result += exp; - - result += SafeCast.toUint(value > 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 + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value); - } - } - - /** - * @dev Return the log in base 10 of a positive value rounded towards zero. - * 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 + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value); - } - } - - /** - * @dev Return the log in base 256 of a positive value rounded towards zero. - * 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; - uint256 isGt; - unchecked { - isGt = SafeCast.toUint(value > (1 << 128) - 1); - value >>= isGt * 128; - result += isGt * 16; - - isGt = SafeCast.toUint(value > (1 << 64) - 1); - value >>= isGt * 64; - result += isGt * 8; - - isGt = SafeCast.toUint(value > (1 << 32) - 1); - value >>= isGt * 32; - result += isGt * 4; - - isGt = SafeCast.toUint(value > (1 << 16) - 1); - value >>= isGt * 16; - result += isGt * 2; - - result += SafeCast.toUint(value > (1 << 8) - 1); - } - return result; - } - - /** - * @dev Return the log in base 256, 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 + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value); - } - } - - /** - * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. - */ - function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { - return uint8(rounding) % 2 == 1; - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol b/lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol deleted file mode 100644 index d8de2e1..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol +++ /dev/null @@ -1,1163 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SafeCast.sol) -// This file was procedurally generated from scripts/generate/templates/SafeCast.js. - -pragma solidity ^0.8.20; - -/** - * @dev Wrappers over Solidity's uintXX/intXX/bool 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. - */ -library SafeCast { - /** - * @dev Value doesn't fit in an uint of `bits` size. - */ - error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value); - - /** - * @dev An int value doesn't fit in an uint of `bits` size. - */ - error SafeCastOverflowedIntToUint(int256 value); - - /** - * @dev Value doesn't fit in an int of `bits` size. - */ - error SafeCastOverflowedIntDowncast(uint8 bits, int256 value); - - /** - * @dev An uint value doesn't fit in an int of `bits` size. - */ - error SafeCastOverflowedUintToInt(uint256 value); - - /** - * @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 - */ - function toUint248(uint256 value) internal pure returns (uint248) { - if (value > type(uint248).max) { - revert SafeCastOverflowedUintDowncast(248, value); - } - 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 - */ - function toUint240(uint256 value) internal pure returns (uint240) { - if (value > type(uint240).max) { - revert SafeCastOverflowedUintDowncast(240, value); - } - 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 - */ - function toUint232(uint256 value) internal pure returns (uint232) { - if (value > type(uint232).max) { - revert SafeCastOverflowedUintDowncast(232, value); - } - 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 - */ - function toUint224(uint256 value) internal pure returns (uint224) { - if (value > type(uint224).max) { - revert SafeCastOverflowedUintDowncast(224, value); - } - 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 - */ - function toUint216(uint256 value) internal pure returns (uint216) { - if (value > type(uint216).max) { - revert SafeCastOverflowedUintDowncast(216, value); - } - 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 - */ - function toUint208(uint256 value) internal pure returns (uint208) { - if (value > type(uint208).max) { - revert SafeCastOverflowedUintDowncast(208, value); - } - 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 - */ - function toUint200(uint256 value) internal pure returns (uint200) { - if (value > type(uint200).max) { - revert SafeCastOverflowedUintDowncast(200, value); - } - 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 - */ - function toUint192(uint256 value) internal pure returns (uint192) { - if (value > type(uint192).max) { - revert SafeCastOverflowedUintDowncast(192, value); - } - 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 - */ - function toUint184(uint256 value) internal pure returns (uint184) { - if (value > type(uint184).max) { - revert SafeCastOverflowedUintDowncast(184, value); - } - 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 - */ - function toUint176(uint256 value) internal pure returns (uint176) { - if (value > type(uint176).max) { - revert SafeCastOverflowedUintDowncast(176, value); - } - 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 - */ - function toUint168(uint256 value) internal pure returns (uint168) { - if (value > type(uint168).max) { - revert SafeCastOverflowedUintDowncast(168, value); - } - 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 - */ - function toUint160(uint256 value) internal pure returns (uint160) { - if (value > type(uint160).max) { - revert SafeCastOverflowedUintDowncast(160, value); - } - 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 - */ - function toUint152(uint256 value) internal pure returns (uint152) { - if (value > type(uint152).max) { - revert SafeCastOverflowedUintDowncast(152, value); - } - 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 - */ - function toUint144(uint256 value) internal pure returns (uint144) { - if (value > type(uint144).max) { - revert SafeCastOverflowedUintDowncast(144, value); - } - 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 - */ - function toUint136(uint256 value) internal pure returns (uint136) { - if (value > type(uint136).max) { - revert SafeCastOverflowedUintDowncast(136, value); - } - 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 - */ - function toUint128(uint256 value) internal pure returns (uint128) { - if (value > type(uint128).max) { - revert SafeCastOverflowedUintDowncast(128, value); - } - 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 - */ - function toUint120(uint256 value) internal pure returns (uint120) { - if (value > type(uint120).max) { - revert SafeCastOverflowedUintDowncast(120, value); - } - 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 - */ - function toUint112(uint256 value) internal pure returns (uint112) { - if (value > type(uint112).max) { - revert SafeCastOverflowedUintDowncast(112, value); - } - 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 - */ - function toUint104(uint256 value) internal pure returns (uint104) { - if (value > type(uint104).max) { - revert SafeCastOverflowedUintDowncast(104, value); - } - 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 - */ - function toUint96(uint256 value) internal pure returns (uint96) { - if (value > type(uint96).max) { - revert SafeCastOverflowedUintDowncast(96, value); - } - 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 - */ - function toUint88(uint256 value) internal pure returns (uint88) { - if (value > type(uint88).max) { - revert SafeCastOverflowedUintDowncast(88, value); - } - 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 - */ - function toUint80(uint256 value) internal pure returns (uint80) { - if (value > type(uint80).max) { - revert SafeCastOverflowedUintDowncast(80, value); - } - 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 - */ - function toUint72(uint256 value) internal pure returns (uint72) { - if (value > type(uint72).max) { - revert SafeCastOverflowedUintDowncast(72, value); - } - 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 - */ - function toUint64(uint256 value) internal pure returns (uint64) { - if (value > type(uint64).max) { - revert SafeCastOverflowedUintDowncast(64, value); - } - 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 - */ - function toUint56(uint256 value) internal pure returns (uint56) { - if (value > type(uint56).max) { - revert SafeCastOverflowedUintDowncast(56, value); - } - 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 - */ - function toUint48(uint256 value) internal pure returns (uint48) { - if (value > type(uint48).max) { - revert SafeCastOverflowedUintDowncast(48, value); - } - 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 - */ - function toUint40(uint256 value) internal pure returns (uint40) { - if (value > type(uint40).max) { - revert SafeCastOverflowedUintDowncast(40, value); - } - 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 - */ - function toUint32(uint256 value) internal pure returns (uint32) { - if (value > type(uint32).max) { - revert SafeCastOverflowedUintDowncast(32, value); - } - 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 - */ - function toUint24(uint256 value) internal pure returns (uint24) { - if (value > type(uint24).max) { - revert SafeCastOverflowedUintDowncast(24, value); - } - 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 - */ - function toUint16(uint256 value) internal pure returns (uint16) { - if (value > type(uint16).max) { - revert SafeCastOverflowedUintDowncast(16, value); - } - 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) { - if (value > type(uint8).max) { - revert SafeCastOverflowedUintDowncast(8, value); - } - 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) { - if (value < 0) { - revert SafeCastOverflowedIntToUint(value); - } - 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 - */ - function toInt248(int256 value) internal pure returns (int248 downcasted) { - downcasted = int248(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(248, value); - } - } - - /** - * @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 - */ - function toInt240(int256 value) internal pure returns (int240 downcasted) { - downcasted = int240(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(240, value); - } - } - - /** - * @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 - */ - function toInt232(int256 value) internal pure returns (int232 downcasted) { - downcasted = int232(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(232, value); - } - } - - /** - * @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 - */ - function toInt224(int256 value) internal pure returns (int224 downcasted) { - downcasted = int224(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(224, value); - } - } - - /** - * @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 - */ - function toInt216(int256 value) internal pure returns (int216 downcasted) { - downcasted = int216(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(216, value); - } - } - - /** - * @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 - */ - function toInt208(int256 value) internal pure returns (int208 downcasted) { - downcasted = int208(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(208, value); - } - } - - /** - * @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 - */ - function toInt200(int256 value) internal pure returns (int200 downcasted) { - downcasted = int200(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(200, value); - } - } - - /** - * @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 - */ - function toInt192(int256 value) internal pure returns (int192 downcasted) { - downcasted = int192(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(192, value); - } - } - - /** - * @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 - */ - function toInt184(int256 value) internal pure returns (int184 downcasted) { - downcasted = int184(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(184, value); - } - } - - /** - * @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 - */ - function toInt176(int256 value) internal pure returns (int176 downcasted) { - downcasted = int176(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(176, value); - } - } - - /** - * @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 - */ - function toInt168(int256 value) internal pure returns (int168 downcasted) { - downcasted = int168(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(168, value); - } - } - - /** - * @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 - */ - function toInt160(int256 value) internal pure returns (int160 downcasted) { - downcasted = int160(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(160, value); - } - } - - /** - * @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 - */ - function toInt152(int256 value) internal pure returns (int152 downcasted) { - downcasted = int152(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(152, value); - } - } - - /** - * @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 - */ - function toInt144(int256 value) internal pure returns (int144 downcasted) { - downcasted = int144(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(144, value); - } - } - - /** - * @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 - */ - function toInt136(int256 value) internal pure returns (int136 downcasted) { - downcasted = int136(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(136, 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 - */ - function toInt128(int256 value) internal pure returns (int128 downcasted) { - downcasted = int128(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(128, value); - } - } - - /** - * @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 - */ - function toInt120(int256 value) internal pure returns (int120 downcasted) { - downcasted = int120(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(120, value); - } - } - - /** - * @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 - */ - function toInt112(int256 value) internal pure returns (int112 downcasted) { - downcasted = int112(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(112, value); - } - } - - /** - * @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 - */ - function toInt104(int256 value) internal pure returns (int104 downcasted) { - downcasted = int104(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(104, value); - } - } - - /** - * @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 - */ - function toInt96(int256 value) internal pure returns (int96 downcasted) { - downcasted = int96(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(96, value); - } - } - - /** - * @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 - */ - function toInt88(int256 value) internal pure returns (int88 downcasted) { - downcasted = int88(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(88, value); - } - } - - /** - * @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 - */ - function toInt80(int256 value) internal pure returns (int80 downcasted) { - downcasted = int80(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(80, value); - } - } - - /** - * @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 - */ - function toInt72(int256 value) internal pure returns (int72 downcasted) { - downcasted = int72(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(72, 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 - */ - function toInt64(int256 value) internal pure returns (int64 downcasted) { - downcasted = int64(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(64, value); - } - } - - /** - * @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 - */ - function toInt56(int256 value) internal pure returns (int56 downcasted) { - downcasted = int56(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(56, value); - } - } - - /** - * @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 - */ - function toInt48(int256 value) internal pure returns (int48 downcasted) { - downcasted = int48(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(48, value); - } - } - - /** - * @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 - */ - function toInt40(int256 value) internal pure returns (int40 downcasted) { - downcasted = int40(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(40, 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 - */ - function toInt32(int256 value) internal pure returns (int32 downcasted) { - downcasted = int32(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(32, value); - } - } - - /** - * @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 - */ - function toInt24(int256 value) internal pure returns (int24 downcasted) { - downcasted = int24(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(24, 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 - */ - function toInt16(int256 value) internal pure returns (int16 downcasted) { - downcasted = int16(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(16, 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 - */ - function toInt8(int256 value) internal pure returns (int8 downcasted) { - downcasted = int8(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(8, 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 - if (value > uint256(type(int256).max)) { - revert SafeCastOverflowedUintToInt(value); - } - return int256(value); - } - - /** - * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump. - */ - function toUint(bool b) internal pure returns (uint256 u) { - /// @solidity memory-safe-assembly - assembly { - u := iszero(iszero(b)) - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol b/lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol deleted file mode 100644 index c1109f9..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol) - -pragma solidity ^0.8.20; - -import {SafeCast} from "./SafeCast.sol"; - -/** - * @dev Standard signed math utilities missing in the Solidity language. - */ -library SignedMath { - /** - * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant. - * - * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone. - * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute - * one branch when needed, making this function more expensive. - */ - function ternary(bool condition, int256 a, int256 b) internal pure returns (int256) { - unchecked { - // branchless ternary works because: - // b ^ (a ^ b) == a - // b ^ 0 == b - return b ^ ((a ^ b) * int256(SafeCast.toUint(condition))); - } - } - - /** - * @dev Returns the largest of two signed numbers. - */ - function max(int256 a, int256 b) internal pure returns (int256) { - return ternary(a > b, a, b); - } - - /** - * @dev Returns the smallest of two signed numbers. - */ - function min(int256 a, int256 b) internal pure returns (int256) { - return ternary(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 { - // Formula from the "Bit Twiddling Hacks" by Sean Eron Anderson. - // Since `n` is a signed integer, the generated bytecode will use the SAR opcode to perform the right shift, - // taking advantage of the most significant (or "sign" bit) in two's complement representation. - // This opcode adds new most significant bits set to the value of the previous most significant bit. As a result, - // the mask will either be `bytes(0)` (if n is positive) or `~bytes32(0)` (if n is negative). - int256 mask = n >> 255; - - // A `bytes(0)` mask leaves the input unchanged, while a `~bytes32(0)` mask complements it. - return uint256((n + mask) ^ mask); - } - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/structs/BitMaps.sol b/lib/openzeppelin-contracts/contracts/utils/structs/BitMaps.sol deleted file mode 100644 index 40cceb9..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/structs/BitMaps.sol +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/BitMaps.sol) -pragma solidity ^0.8.20; - -/** - * @dev Library for managing uint256 to bool mapping in a compact and efficient way, provided the keys are sequential. - * Largely inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor]. - * - * BitMaps pack 256 booleans across each bit of a single 256-bit slot of `uint256` type. - * Hence booleans corresponding to 256 _sequential_ indices would only consume a single slot, - * unlike the regular `bool` which would consume an entire slot for a single value. - * - * This results in gas savings in two ways: - * - * - Setting a zero value to non-zero only once every 256 times - * - Accessing the same warm slot for every 256 _sequential_ indices - */ -library BitMaps { - struct BitMap { - mapping(uint256 bucket => 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/openzeppelin-contracts/contracts/utils/structs/Checkpoints.sol b/lib/openzeppelin-contracts/contracts/utils/structs/Checkpoints.sol deleted file mode 100644 index 5ba6ad9..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/structs/Checkpoints.sol +++ /dev/null @@ -1,606 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/Checkpoints.sol) -// This file was procedurally generated from scripts/generate/templates/Checkpoints.js. - -pragma solidity ^0.8.20; - -import {Math} from "../math/Math.sol"; - -/** - * @dev This library defines the `Trace*` 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.Trace*` in your contract, and store a new - * checkpoint for the current transaction block using the {push} function. - */ -library Checkpoints { - /** - * @dev A value was attempted to be inserted on a past checkpoint. - */ - error CheckpointUnorderedInsertion(); - - 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. - * - * IMPORTANT: Never accept `key` as a user input, since an arbitrary `type(uint32).max` key set will disable the - * library. - */ - 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 first (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 last (most recent) checkpoint with key lower or equal than the search key, or zero - * if there is none. - */ - 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 last (most recent) checkpoint with key lower or equal than the search key, or zero - * if there is none. - * - * NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high - * keys). - */ - function upperLookupRecent(Trace224 storage self, uint32 key) internal view returns (uint224) { - uint256 len = self._checkpoints.length; - - uint256 low = 0; - uint256 high = len; - - if (len > 5) { - uint256 mid = len - Math.sqrt(len); - if (key < _unsafeAccess(self._checkpoints, mid)._key) { - 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 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 storage 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 Returns checkpoint at given position. - */ - function at(Trace224 storage self, uint32 pos) internal view returns (Checkpoint224 memory) { - return self._checkpoints[pos]; - } - - /** - * @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) { - Checkpoint224 storage last = _unsafeAccess(self, pos - 1); - uint32 lastKey = last._key; - uint224 lastValue = last._value; - - // Checkpoint keys must be non-decreasing. - if (lastKey > key) { - revert CheckpointUnorderedInsertion(); - } - - // Update or push new checkpoint - if (lastKey == key) { - _unsafeAccess(self, pos - 1)._value = value; - } else { - self.push(Checkpoint224({_key: key, _value: value})); - } - return (lastValue, value); - } else { - self.push(Checkpoint224({_key: key, _value: value})); - return (0, value); - } - } - - /** - * @dev Return the index of the last (most recent) checkpoint with key lower 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 _upperBinaryLookup( - Checkpoint224[] storage self, - uint32 key, - uint256 low, - uint256 high - ) private view returns (uint256) { - while (low < high) { - uint256 mid = Math.average(low, high); - if (_unsafeAccess(self, mid)._key > key) { - high = mid; - } else { - low = mid + 1; - } - } - return high; - } - - /** - * @dev Return the index of the first (oldest) checkpoint with 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 = Math.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 Trace208 { - Checkpoint208[] _checkpoints; - } - - struct Checkpoint208 { - uint48 _key; - uint208 _value; - } - - /** - * @dev Pushes a (`key`, `value`) pair into a Trace208 so that it is stored as the checkpoint. - * - * Returns previous value and new value. - * - * IMPORTANT: Never accept `key` as a user input, since an arbitrary `type(uint48).max` key set will disable the - * library. - */ - function push(Trace208 storage self, uint48 key, uint208 value) internal returns (uint208, uint208) { - return _insert(self._checkpoints, key, value); - } - - /** - * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if - * there is none. - */ - function lowerLookup(Trace208 storage self, uint48 key) internal view returns (uint208) { - 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 last (most recent) checkpoint with key lower or equal than the search key, or zero - * if there is none. - */ - function upperLookup(Trace208 storage self, uint48 key) internal view returns (uint208) { - 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 last (most recent) checkpoint with key lower or equal than the search key, or zero - * if there is none. - * - * NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high - * keys). - */ - function upperLookupRecent(Trace208 storage self, uint48 key) internal view returns (uint208) { - uint256 len = self._checkpoints.length; - - uint256 low = 0; - uint256 high = len; - - if (len > 5) { - uint256 mid = len - Math.sqrt(len); - if (key < _unsafeAccess(self._checkpoints, mid)._key) { - 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 Returns the value in the most recent checkpoint, or zero if there are no checkpoints. - */ - function latest(Trace208 storage self) internal view returns (uint208) { - 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(Trace208 storage self) internal view returns (bool exists, uint48 _key, uint208 _value) { - uint256 pos = self._checkpoints.length; - if (pos == 0) { - return (false, 0, 0); - } else { - Checkpoint208 storage ckpt = _unsafeAccess(self._checkpoints, pos - 1); - return (true, ckpt._key, ckpt._value); - } - } - - /** - * @dev Returns the number of checkpoint. - */ - function length(Trace208 storage self) internal view returns (uint256) { - return self._checkpoints.length; - } - - /** - * @dev Returns checkpoint at given position. - */ - function at(Trace208 storage self, uint32 pos) internal view returns (Checkpoint208 memory) { - return self._checkpoints[pos]; - } - - /** - * @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(Checkpoint208[] storage self, uint48 key, uint208 value) private returns (uint208, uint208) { - uint256 pos = self.length; - - if (pos > 0) { - Checkpoint208 storage last = _unsafeAccess(self, pos - 1); - uint48 lastKey = last._key; - uint208 lastValue = last._value; - - // Checkpoint keys must be non-decreasing. - if (lastKey > key) { - revert CheckpointUnorderedInsertion(); - } - - // Update or push new checkpoint - if (lastKey == key) { - _unsafeAccess(self, pos - 1)._value = value; - } else { - self.push(Checkpoint208({_key: key, _value: value})); - } - return (lastValue, value); - } else { - self.push(Checkpoint208({_key: key, _value: value})); - return (0, value); - } - } - - /** - * @dev Return the index of the last (most recent) checkpoint with key lower 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 _upperBinaryLookup( - Checkpoint208[] storage self, - uint48 key, - uint256 low, - uint256 high - ) private view returns (uint256) { - while (low < high) { - uint256 mid = Math.average(low, high); - if (_unsafeAccess(self, mid)._key > key) { - high = mid; - } else { - low = mid + 1; - } - } - return high; - } - - /** - * @dev Return the index of the first (oldest) checkpoint with 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( - Checkpoint208[] storage self, - uint48 key, - uint256 low, - uint256 high - ) private view returns (uint256) { - while (low < high) { - uint256 mid = Math.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( - Checkpoint208[] storage self, - uint256 pos - ) private pure returns (Checkpoint208 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. - * - * IMPORTANT: Never accept `key` as a user input, since an arbitrary `type(uint96).max` key set will disable the - * library. - */ - 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 first (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 last (most recent) checkpoint with key lower or equal than the search key, or zero - * if there is none. - */ - 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 last (most recent) checkpoint with key lower or equal than the search key, or zero - * if there is none. - * - * NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high - * keys). - */ - function upperLookupRecent(Trace160 storage self, uint96 key) internal view returns (uint160) { - uint256 len = self._checkpoints.length; - - uint256 low = 0; - uint256 high = len; - - if (len > 5) { - uint256 mid = len - Math.sqrt(len); - if (key < _unsafeAccess(self._checkpoints, mid)._key) { - 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 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 storage 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 Returns checkpoint at given position. - */ - function at(Trace160 storage self, uint32 pos) internal view returns (Checkpoint160 memory) { - return self._checkpoints[pos]; - } - - /** - * @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) { - Checkpoint160 storage last = _unsafeAccess(self, pos - 1); - uint96 lastKey = last._key; - uint160 lastValue = last._value; - - // Checkpoint keys must be non-decreasing. - if (lastKey > key) { - revert CheckpointUnorderedInsertion(); - } - - // Update or push new checkpoint - if (lastKey == key) { - _unsafeAccess(self, pos - 1)._value = value; - } else { - self.push(Checkpoint160({_key: key, _value: value})); - } - return (lastValue, value); - } else { - self.push(Checkpoint160({_key: key, _value: value})); - return (0, value); - } - } - - /** - * @dev Return the index of the last (most recent) checkpoint with key lower 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 _upperBinaryLookup( - Checkpoint160[] storage self, - uint96 key, - uint256 low, - uint256 high - ) private view returns (uint256) { - while (low < high) { - uint256 mid = Math.average(low, high); - if (_unsafeAccess(self, mid)._key > key) { - high = mid; - } else { - low = mid + 1; - } - } - return high; - } - - /** - * @dev Return the index of the first (oldest) checkpoint with 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 = Math.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/openzeppelin-contracts/contracts/utils/structs/CircularBuffer.sol b/lib/openzeppelin-contracts/contracts/utils/structs/CircularBuffer.sol deleted file mode 100644 index be9af9f..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/structs/CircularBuffer.sol +++ /dev/null @@ -1,130 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import {Math} from "../math/Math.sol"; -import {Arrays} from "../Arrays.sol"; -import {Panic} from "../Panic.sol"; - -/** - * @dev A fixed-size buffer for keeping `bytes32` items in storage. - * - * This data structure allows for pushing elements to it, and when its length exceeds the specified fixed size, - * new items take the place of the oldest element in the buffer, keeping at most `N` elements in the - * structure. - * - * Elements can't be removed but the data structure can be cleared. See {clear}. - * - * Complexity: - * - insertion ({push}): O(1) - * - lookup ({last}): O(1) - * - inclusion ({includes}): O(N) (worst case) - * - reset ({clear}): O(1) - * - * * The struct is called `Bytes32CircularBuffer`. Other types can be cast to and from `bytes32`. This data structure - * can only be used in storage, and not in memory. - * - * Example usage: - * - * ```solidity - * contract Example { - * // Add the library methods - * using CircularBuffer for CircularBuffer.Bytes32CircularBuffer; - * - * // Declare a buffer storage variable - * CircularBuffer.Bytes32CircularBuffer private myBuffer; - * } - * ``` - */ -library CircularBuffer { - /** - * @dev Counts the number of items that have been pushed to the buffer. The residuo modulo _data.length indicates - * where the next value should be stored. - * - * 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. - * - * The last item is at data[(index - 1) % data.length] and the last item is at data[index % data.length]. This - * range can wrap around. - */ - struct Bytes32CircularBuffer { - uint256 _count; - bytes32[] _data; - } - - /** - * @dev Initialize a new CircularBuffer of given size. - * - * If the CircularBuffer was already setup and used, calling that function again will reset it to a blank state. - * - * NOTE: The size of the buffer will affect the execution of {includes} function, as it has a complexity of O(N). - * Consider a large buffer size may render the function unusable. - */ - function setup(Bytes32CircularBuffer storage self, uint256 size) internal { - clear(self); - Arrays.unsafeSetLength(self._data, size); - } - - /** - * @dev Clear all data in the buffer without resetting memory, keeping the existing size. - */ - function clear(Bytes32CircularBuffer storage self) internal { - self._count = 0; - } - - /** - * @dev Push a new value to the buffer. If the buffer is already full, the new value replaces the oldest value in - * the buffer. - */ - function push(Bytes32CircularBuffer storage self, bytes32 value) internal { - uint256 index = self._count++; - uint256 modulus = self._data.length; - Arrays.unsafeAccess(self._data, index % modulus).value = value; - } - - /** - * @dev Number of values currently in the buffer. This value is 0 for an empty buffer, and cannot exceed the size of - * the buffer. - */ - function count(Bytes32CircularBuffer storage self) internal view returns (uint256) { - return Math.min(self._count, self._data.length); - } - - /** - * @dev Length of the buffer. This is the maximum number of elements kepts in the buffer. - */ - function length(Bytes32CircularBuffer storage self) internal view returns (uint256) { - return self._data.length; - } - - /** - * @dev Getter for the i-th value in the buffer, from the end. - * - * Reverts with {Panic-ARRAY_OUT_OF_BOUNDS} if trying to access an element that was not pushed, or that was - * dropped to make room for newer elements. - */ - function last(Bytes32CircularBuffer storage self, uint256 i) internal view returns (bytes32) { - uint256 index = self._count; - uint256 modulus = self._data.length; - uint256 total = Math.min(index, modulus); // count(self) - if (i >= total) { - Panic.panic(Panic.ARRAY_OUT_OF_BOUNDS); - } - return Arrays.unsafeAccess(self._data, (index - i - 1) % modulus).value; - } - - /** - * @dev Check if a given value is in the buffer. - */ - function includes(Bytes32CircularBuffer storage self, bytes32 value) internal view returns (bool) { - uint256 index = self._count; - uint256 modulus = self._data.length; - uint256 total = Math.min(index, modulus); // count(self) - for (uint256 i = 0; i < total; ++i) { - if (Arrays.unsafeAccess(self._data, (index - i - 1) % modulus).value == value) { - return true; - } - } - return false; - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/structs/DoubleEndedQueue.sol b/lib/openzeppelin-contracts/contracts/utils/structs/DoubleEndedQueue.sol deleted file mode 100644 index 48f0d68..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/structs/DoubleEndedQueue.sol +++ /dev/null @@ -1,156 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/DoubleEndedQueue.sol) -pragma solidity ^0.8.20; - -import {Panic} from "../Panic.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. - * ```solidity - * DoubleEndedQueue.Bytes32Deque queue; - * ``` - */ -library DoubleEndedQueue { - /** - * @dev Indices are 128 bits so begin and end are packed in a single storage slot for efficient access. - * - * 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. - * - * The first item is at data[begin] and the last item is at data[end - 1]. This range can wrap around. - */ - struct Bytes32Deque { - uint128 _begin; - uint128 _end; - mapping(uint128 index => bytes32) _data; - } - - /** - * @dev Inserts an item at the end of the queue. - * - * Reverts with {Panic-RESOURCE_ERROR} if the queue is full. - */ - function pushBack(Bytes32Deque storage deque, bytes32 value) internal { - unchecked { - uint128 backIndex = deque._end; - if (backIndex + 1 == deque._begin) Panic.panic(Panic.RESOURCE_ERROR); - deque._data[backIndex] = value; - deque._end = backIndex + 1; - } - } - - /** - * @dev Removes the item at the end of the queue and returns it. - * - * Reverts with {Panic-EMPTY_ARRAY_POP} if the queue is empty. - */ - function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) { - unchecked { - uint128 backIndex = deque._end; - if (backIndex == deque._begin) Panic.panic(Panic.EMPTY_ARRAY_POP); - --backIndex; - value = deque._data[backIndex]; - delete deque._data[backIndex]; - deque._end = backIndex; - } - } - - /** - * @dev Inserts an item at the beginning of the queue. - * - * Reverts with {Panic-RESOURCE_ERROR} if the queue is full. - */ - function pushFront(Bytes32Deque storage deque, bytes32 value) internal { - unchecked { - uint128 frontIndex = deque._begin - 1; - if (frontIndex == deque._end) Panic.panic(Panic.RESOURCE_ERROR); - deque._data[frontIndex] = value; - deque._begin = frontIndex; - } - } - - /** - * @dev Removes the item at the beginning of the queue and returns it. - * - * Reverts with {Panic-EMPTY_ARRAY_POP} if the queue is empty. - */ - function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) { - unchecked { - uint128 frontIndex = deque._begin; - if (frontIndex == deque._end) Panic.panic(Panic.EMPTY_ARRAY_POP); - value = deque._data[frontIndex]; - delete deque._data[frontIndex]; - deque._begin = frontIndex + 1; - } - } - - /** - * @dev Returns the item at the beginning of the queue. - * - * Reverts with {Panic-ARRAY_OUT_OF_BOUNDS} if the queue is empty. - */ - function front(Bytes32Deque storage deque) internal view returns (bytes32 value) { - if (empty(deque)) Panic.panic(Panic.ARRAY_OUT_OF_BOUNDS); - return deque._data[deque._begin]; - } - - /** - * @dev Returns the item at the end of the queue. - * - * Reverts with {Panic-ARRAY_OUT_OF_BOUNDS} if the queue is empty. - */ - function back(Bytes32Deque storage deque) internal view returns (bytes32 value) { - if (empty(deque)) Panic.panic(Panic.ARRAY_OUT_OF_BOUNDS); - unchecked { - return deque._data[deque._end - 1]; - } - } - - /** - * @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 {Panic-ARRAY_OUT_OF_BOUNDS} if the index is out of bounds. - */ - function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) { - if (index >= length(deque)) Panic.panic(Panic.ARRAY_OUT_OF_BOUNDS); - // By construction, length is a uint128, so the check above ensures that index can be safely downcast to uint128 - unchecked { - return deque._data[deque._begin + uint128(index)]; - } - } - - /** - * @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) { - unchecked { - return uint256(deque._end - 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/openzeppelin-contracts/contracts/utils/structs/EnumerableMap.sol b/lib/openzeppelin-contracts/contracts/utils/structs/EnumerableMap.sol deleted file mode 100644 index 814916b..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/structs/EnumerableMap.sol +++ /dev/null @@ -1,913 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/EnumerableMap.sol) -// This file was procedurally generated from scripts/generate/templates/EnumerableMap.js. - -pragma solidity ^0.8.20; - -import {EnumerableSet} from "./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. - * - * ```solidity - * 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 - * - `uint256 -> bytes32` (`UintToBytes32Map`) since v5.1.0 - * - `address -> address` (`AddressToAddressMap`) since v5.1.0 - * - `address -> bytes32` (`AddressToBytes32Map`) since v5.1.0 - * - `bytes32 -> address` (`Bytes32ToAddressMap`) since v5.1.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 `UintToAddressMap` are just wrappers around the underlying Map. - // This means that we can only create new EnumerableMaps for types that fit in bytes32. - - /** - * @dev Query for a nonexistent map key. - */ - error EnumerableMapNonexistentKey(bytes32 key); - - struct Bytes32ToBytes32Map { - // Storage of keys - EnumerableSet.Bytes32Set _keys; - mapping(bytes32 key => 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]; - if (value == 0 && !contains(map, key)) { - revert EnumerableMapNonexistentKey(key); - } - return value; - } - - /** - * @dev Return the an array containing all the keys - * - * 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 map grows to a point where copying to memory consumes too much gas to fit in a block. - */ - function keys(Bytes32ToBytes32Map storage map) internal view returns (bytes32[] memory) { - return map._keys.values(); - } - - // 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 map. 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 map. 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 Return the an array containing all the keys - * - * 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 map grows to a point where copying to memory consumes too much gas to fit in a block. - */ - function keys(UintToUintMap storage map) internal view returns (uint256[] memory) { - bytes32[] memory store = keys(map._inner); - uint256[] memory result; - - /// @solidity memory-safe-assembly - assembly { - result := store - } - - return result; - } - - // 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 map. 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 map. 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 Return the an array containing all the keys - * - * 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 map grows to a point where copying to memory consumes too much gas to fit in a block. - */ - function keys(UintToAddressMap storage map) internal view returns (uint256[] memory) { - bytes32[] memory store = keys(map._inner); - uint256[] memory result; - - /// @solidity memory-safe-assembly - assembly { - result := store - } - - return result; - } - - // UintToBytes32Map - - struct UintToBytes32Map { - 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(UintToBytes32Map storage map, uint256 key, bytes32 value) internal returns (bool) { - return set(map._inner, bytes32(key), value); - } - - /** - * @dev Removes a value from a map. O(1). - * - * Returns true if the key was removed from the map, that is if it was present. - */ - function remove(UintToBytes32Map 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(UintToBytes32Map 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(UintToBytes32Map storage map) internal view returns (uint256) { - return length(map._inner); - } - - /** - * @dev Returns the element stored at position `index` in the map. 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(UintToBytes32Map storage map, uint256 index) internal view returns (uint256, bytes32) { - (bytes32 key, bytes32 value) = at(map._inner, index); - return (uint256(key), value); - } - - /** - * @dev Tries to returns the value associated with `key`. O(1). - * Does not revert if `key` is not in the map. - */ - function tryGet(UintToBytes32Map storage map, uint256 key) internal view returns (bool, bytes32) { - (bool success, bytes32 value) = tryGet(map._inner, bytes32(key)); - return (success, value); - } - - /** - * @dev Returns the value associated with `key`. O(1). - * - * Requirements: - * - * - `key` must be in the map. - */ - function get(UintToBytes32Map storage map, uint256 key) internal view returns (bytes32) { - return get(map._inner, bytes32(key)); - } - - /** - * @dev Return the an array containing all the keys - * - * 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 map grows to a point where copying to memory consumes too much gas to fit in a block. - */ - function keys(UintToBytes32Map storage map) internal view returns (uint256[] memory) { - bytes32[] memory store = keys(map._inner); - uint256[] memory result; - - /// @solidity memory-safe-assembly - assembly { - result := store - } - - return result; - } - - // 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 map. 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 map. 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 Return the an array containing all the keys - * - * 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 map grows to a point where copying to memory consumes too much gas to fit in a block. - */ - function keys(AddressToUintMap storage map) internal view returns (address[] memory) { - bytes32[] memory store = keys(map._inner); - address[] memory result; - - /// @solidity memory-safe-assembly - assembly { - result := store - } - - return result; - } - - // AddressToAddressMap - - struct AddressToAddressMap { - 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(AddressToAddressMap storage map, address key, address value) internal returns (bool) { - return set(map._inner, bytes32(uint256(uint160(key))), bytes32(uint256(uint160(value)))); - } - - /** - * @dev Removes a value from a map. O(1). - * - * Returns true if the key was removed from the map, that is if it was present. - */ - function remove(AddressToAddressMap 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(AddressToAddressMap 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(AddressToAddressMap storage map) internal view returns (uint256) { - return length(map._inner); - } - - /** - * @dev Returns the element stored at position `index` in the map. 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(AddressToAddressMap storage map, uint256 index) internal view returns (address, address) { - (bytes32 key, bytes32 value) = at(map._inner, index); - return (address(uint160(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(AddressToAddressMap storage map, address key) internal view returns (bool, address) { - (bool success, bytes32 value) = tryGet(map._inner, bytes32(uint256(uint160(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(AddressToAddressMap storage map, address key) internal view returns (address) { - return address(uint160(uint256(get(map._inner, bytes32(uint256(uint160(key))))))); - } - - /** - * @dev Return the an array containing all the keys - * - * 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 map grows to a point where copying to memory consumes too much gas to fit in a block. - */ - function keys(AddressToAddressMap storage map) internal view returns (address[] memory) { - bytes32[] memory store = keys(map._inner); - address[] memory result; - - /// @solidity memory-safe-assembly - assembly { - result := store - } - - return result; - } - - // AddressToBytes32Map - - struct AddressToBytes32Map { - 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(AddressToBytes32Map storage map, address key, bytes32 value) internal returns (bool) { - return set(map._inner, bytes32(uint256(uint160(key))), value); - } - - /** - * @dev Removes a value from a map. O(1). - * - * Returns true if the key was removed from the map, that is if it was present. - */ - function remove(AddressToBytes32Map 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(AddressToBytes32Map 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(AddressToBytes32Map storage map) internal view returns (uint256) { - return length(map._inner); - } - - /** - * @dev Returns the element stored at position `index` in the map. 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(AddressToBytes32Map storage map, uint256 index) internal view returns (address, bytes32) { - (bytes32 key, bytes32 value) = at(map._inner, index); - return (address(uint160(uint256(key))), value); - } - - /** - * @dev Tries to returns the value associated with `key`. O(1). - * Does not revert if `key` is not in the map. - */ - function tryGet(AddressToBytes32Map storage map, address key) internal view returns (bool, bytes32) { - (bool success, bytes32 value) = tryGet(map._inner, bytes32(uint256(uint160(key)))); - return (success, value); - } - - /** - * @dev Returns the value associated with `key`. O(1). - * - * Requirements: - * - * - `key` must be in the map. - */ - function get(AddressToBytes32Map storage map, address key) internal view returns (bytes32) { - return get(map._inner, bytes32(uint256(uint160(key)))); - } - - /** - * @dev Return the an array containing all the keys - * - * 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 map grows to a point where copying to memory consumes too much gas to fit in a block. - */ - function keys(AddressToBytes32Map storage map) internal view returns (address[] memory) { - bytes32[] memory store = keys(map._inner); - address[] memory result; - - /// @solidity memory-safe-assembly - assembly { - result := store - } - - return result; - } - - // 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 map. 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 map. 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 Return the an array containing all the keys - * - * 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 map grows to a point where copying to memory consumes too much gas to fit in a block. - */ - function keys(Bytes32ToUintMap storage map) internal view returns (bytes32[] memory) { - bytes32[] memory store = keys(map._inner); - bytes32[] memory result; - - /// @solidity memory-safe-assembly - assembly { - result := store - } - - return result; - } - - // Bytes32ToAddressMap - - struct Bytes32ToAddressMap { - 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(Bytes32ToAddressMap storage map, bytes32 key, address value) internal returns (bool) { - return set(map._inner, key, bytes32(uint256(uint160(value)))); - } - - /** - * @dev Removes a value from a map. O(1). - * - * Returns true if the key was removed from the map, that is if it was present. - */ - function remove(Bytes32ToAddressMap 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(Bytes32ToAddressMap 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(Bytes32ToAddressMap storage map) internal view returns (uint256) { - return length(map._inner); - } - - /** - * @dev Returns the element stored at position `index` in the map. 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(Bytes32ToAddressMap storage map, uint256 index) internal view returns (bytes32, address) { - (bytes32 key, bytes32 value) = at(map._inner, index); - return (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(Bytes32ToAddressMap storage map, bytes32 key) internal view returns (bool, address) { - (bool success, bytes32 value) = tryGet(map._inner, 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(Bytes32ToAddressMap storage map, bytes32 key) internal view returns (address) { - return address(uint160(uint256(get(map._inner, key)))); - } - - /** - * @dev Return the an array containing all the keys - * - * 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 map grows to a point where copying to memory consumes too much gas to fit in a block. - */ - function keys(Bytes32ToAddressMap storage map) internal view returns (bytes32[] memory) { - bytes32[] memory store = keys(map._inner); - bytes32[] memory result; - - /// @solidity memory-safe-assembly - assembly { - result := store - } - - return result; - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol b/lib/openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol deleted file mode 100644 index 4c7fc5e..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol +++ /dev/null @@ -1,378 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/EnumerableSet.sol) -// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. - -pragma solidity ^0.8.20; - -/** - * @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. - * - * ```solidity - * 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 is the index of the value in the `values` array plus 1. - // Position 0 is used to mean a value is not in the set. - mapping(bytes32 value => uint256) _positions; - } - - /** - * @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._positions[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 cache the value's position to prevent multiple reads from the same storage slot - uint256 position = set._positions[value]; - - if (position != 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 valueIndex = position - 1; - uint256 lastIndex = set._values.length - 1; - - if (valueIndex != lastIndex) { - bytes32 lastValue = set._values[lastIndex]; - - // Move the lastValue to the index where the value to delete is - set._values[valueIndex] = lastValue; - // Update the tracked position of the lastValue (that was just moved) - set._positions[lastValue] = position; - } - - // Delete the slot where the moved value was stored - set._values.pop(); - - // Delete the tracked position for the deleted slot - delete set._positions[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._positions[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/openzeppelin-contracts/contracts/utils/structs/MerkleTree.sol b/lib/openzeppelin-contracts/contracts/utils/structs/MerkleTree.sol deleted file mode 100644 index 93f59ac..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/structs/MerkleTree.sol +++ /dev/null @@ -1,171 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import {Hashes} from "../cryptography/Hashes.sol"; -import {Arrays} from "../Arrays.sol"; -import {Panic} from "../Panic.sol"; - -/** - * @dev Library for managing https://wikipedia.org/wiki/Merkle_Tree[Merkle Tree] data structures. - * - * Each tree is a complete binary tree with the ability to sequentially insert leaves, changing them from a zero to a - * non-zero value and updating its root. This structure allows inserting commitments (or other entries) that are not - * stored, but can be proven to be part of the tree at a later time if the root is kept. See {MerkleProof}. - * - * A tree is defined by the following parameters: - * - * * Depth: The number of levels in the tree, it also defines the maximum number of leaves as 2**depth. - * * Zero value: The value that represents an empty leaf. Used to avoid regular zero values to be part of the tree. - * * Hashing function: A cryptographic hash function used to produce internal nodes. Defaults to {Hashes-commutativeKeccak256}. - * - * NOTE: Building trees using non-commutative hashing functions (i.e. `H(a, b) != H(b, a)`) is supported. However, - * proving the inclusion of a leaf in such trees is not possible with the {MerkleProof} library since it only supports - * _commutative_ hashing functions. - * - * _Available since v5.1._ - */ -library MerkleTree { - /** - * @dev A complete `bytes32` Merkle tree. - * - * The `sides` and `zero` arrays are set to have a length equal to the depth of the tree during setup. - * - * 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. - * - * NOTE: The `root` and the updates history is not stored within the tree. Consider using a secondary structure to - * store a list of historical roots from the values returned from {setup} and {push} (e.g. a mapping, {BitMaps} or - * {Checkpoints}). - * - * WARNING: Updating any of the tree's parameters after the first insertion will result in a corrupted tree. - */ - struct Bytes32PushTree { - uint256 _nextLeafIndex; - bytes32[] _sides; - bytes32[] _zeros; - } - - /** - * @dev Initialize a {Bytes32PushTree} using {Hashes-commutativeKeccak256} to hash internal nodes. - * The capacity of the tree (i.e. number of leaves) is set to `2**levels`. - * - * Calling this function on MerkleTree that was already setup and used will reset it to a blank state. - * - * Once a tree is setup, any push to it must use the same hashing function. This means that values - * should be pushed to it using the default {xref-MerkleTree-push-struct-MerkleTree-Bytes32PushTree-bytes32-}[push] function. - * - * IMPORTANT: The zero value should be carefully chosen since it will be stored in the tree representing - * empty leaves. It should be a value that is not expected to be part of the tree. - */ - function setup(Bytes32PushTree storage self, uint8 levels, bytes32 zero) internal returns (bytes32 initialRoot) { - return setup(self, levels, zero, Hashes.commutativeKeccak256); - } - - /** - * @dev Same as {xref-MerkleTree-setup-struct-MerkleTree-Bytes32PushTree-uint8-bytes32-}[setup], but allows to specify a custom hashing function. - * - * Once a tree is setup, any push to it must use the same hashing function. This means that values - * should be pushed to it using the custom push function, which should be the same one as used during the setup. - * - * IMPORTANT: Providing a custom hashing function is a security-sensitive operation since it may - * compromise the soundness of the tree. Consider using functions from {Hashes}. - */ - function setup( - Bytes32PushTree storage self, - uint8 levels, - bytes32 zero, - function(bytes32, bytes32) view returns (bytes32) fnHash - ) internal returns (bytes32 initialRoot) { - // Store depth in the dynamic array - Arrays.unsafeSetLength(self._sides, levels); - Arrays.unsafeSetLength(self._zeros, levels); - - // Build each root of zero-filled subtrees - bytes32 currentZero = zero; - for (uint32 i = 0; i < levels; ++i) { - Arrays.unsafeAccess(self._zeros, i).value = currentZero; - currentZero = fnHash(currentZero, currentZero); - } - - // Set the first root - self._nextLeafIndex = 0; - - return currentZero; - } - - /** - * @dev Insert a new leaf in the tree, and compute the new root. Returns the position of the inserted leaf in the - * tree, and the resulting root. - * - * Hashing the leaf before calling this function is recommended as a protection against - * second pre-image attacks. - * - * This variant uses {Hashes-commutativeKeccak256} to hash internal nodes. It should only be used on merkle trees - * that were setup using the same (default) hashing function (i.e. by calling - * {xref-MerkleTree-setup-struct-MerkleTree-Bytes32PushTree-uint8-bytes32-}[the default setup] function). - */ - function push(Bytes32PushTree storage self, bytes32 leaf) internal returns (uint256 index, bytes32 newRoot) { - return push(self, leaf, Hashes.commutativeKeccak256); - } - - /** - * @dev Insert a new leaf in the tree, and compute the new root. Returns the position of the inserted leaf in the - * tree, and the resulting root. - * - * Hashing the leaf before calling this function is recommended as a protection against - * second pre-image attacks. - * - * This variant uses a custom hashing function to hash internal nodes. It should only be called with the same - * function as the one used during the initial setup of the merkle tree. - */ - function push( - Bytes32PushTree storage self, - bytes32 leaf, - function(bytes32, bytes32) view returns (bytes32) fnHash - ) internal returns (uint256 index, bytes32 newRoot) { - // Cache read - uint256 levels = self._zeros.length; - - // Get leaf index - index = self._nextLeafIndex++; - - // Check if tree is full. - if (index >= 1 << levels) { - Panic.panic(Panic.RESOURCE_ERROR); - } - - // Rebuild branch from leaf to root - uint256 currentIndex = index; - bytes32 currentLevelHash = leaf; - for (uint32 i = 0; i < levels; i++) { - // Reaching the parent node, is currentLevelHash the left child? - bool isLeft = currentIndex % 2 == 0; - - // If so, next time we will come from the right, so we need to save it - if (isLeft) { - Arrays.unsafeAccess(self._sides, i).value = currentLevelHash; - } - - // Compute the current node hash by using the hash function - // with either its sibling (side) or the zero value for that level. - currentLevelHash = fnHash( - isLeft ? currentLevelHash : Arrays.unsafeAccess(self._sides, i).value, - isLeft ? Arrays.unsafeAccess(self._zeros, i).value : currentLevelHash - ); - - // Update node index - currentIndex >>= 1; - } - - return (index, currentLevelHash); - } - - /** - * @dev Tree's depth (set at initialization) - */ - function depth(Bytes32PushTree storage self) internal view returns (uint256) { - return self._zeros.length; - } -} diff --git a/lib/openzeppelin-contracts/contracts/utils/types/Time.sol b/lib/openzeppelin-contracts/contracts/utils/types/Time.sol deleted file mode 100644 index 9faef31..0000000 --- a/lib/openzeppelin-contracts/contracts/utils/types/Time.sol +++ /dev/null @@ -1,130 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (utils/types/Time.sol) - -pragma solidity ^0.8.20; - -import {Math} from "../math/Math.sol"; -import {SafeCast} from "../math/SafeCast.sol"; - -/** - * @dev This library provides helpers for manipulating time-related objects. - * - * It uses the following types: - * - `uint48` for timepoints - * - `uint32` for durations - * - * While the library doesn't provide specific types for timepoints and duration, it does provide: - * - a `Delay` type to represent duration that can be programmed to change value automatically at a given point - * - additional helper functions - */ -library Time { - using Time for *; - - /** - * @dev Get the block timestamp as a Timepoint. - */ - function timestamp() internal view returns (uint48) { - return SafeCast.toUint48(block.timestamp); - } - - /** - * @dev Get the block number as a Timepoint. - */ - function blockNumber() internal view returns (uint48) { - return SafeCast.toUint48(block.number); - } - - // ==================================================== Delay ===================================================== - /** - * @dev A `Delay` is a uint32 duration that can be programmed to change value automatically at a given point in the - * future. The "effect" timepoint describes when the transitions happens from the "old" value to the "new" value. - * This allows updating the delay applied to some operation while keeping some guarantees. - * - * In particular, the {update} function guarantees that if the delay is reduced, the old delay still applies for - * some time. For example if the delay is currently 7 days to do an upgrade, the admin should not be able to set - * the delay to 0 and upgrade immediately. If the admin wants to reduce the delay, the old delay (7 days) should - * still apply for some time. - * - * - * The `Delay` type is 112 bits long, and packs the following: - * - * ``` - * | [uint48]: effect date (timepoint) - * | | [uint32]: value before (duration) - * ↓ ↓ ↓ [uint32]: value after (duration) - * 0xAAAAAAAAAAAABBBBBBBBCCCCCCCC - * ``` - * - * NOTE: The {get} and {withUpdate} functions operate using timestamps. Block number based delays are not currently - * supported. - */ - type Delay is uint112; - - /** - * @dev Wrap a duration into a Delay to add the one-step "update in the future" feature - */ - function toDelay(uint32 duration) internal pure returns (Delay) { - return Delay.wrap(duration); - } - - /** - * @dev Get the value at a given timepoint plus the pending value and effect timepoint if there is a scheduled - * change after this timepoint. If the effect timepoint is 0, then the pending value should not be considered. - */ - function _getFullAt(Delay self, uint48 timepoint) private pure returns (uint32, uint32, uint48) { - (uint32 valueBefore, uint32 valueAfter, uint48 effect) = self.unpack(); - return effect <= timepoint ? (valueAfter, 0, 0) : (valueBefore, valueAfter, effect); - } - - /** - * @dev Get the current value plus the pending value and effect timepoint if there is a scheduled change. If the - * effect timepoint is 0, then the pending value should not be considered. - */ - function getFull(Delay self) internal view returns (uint32, uint32, uint48) { - return _getFullAt(self, timestamp()); - } - - /** - * @dev Get the current value. - */ - function get(Delay self) internal view returns (uint32) { - (uint32 delay, , ) = self.getFull(); - return delay; - } - - /** - * @dev Update a Delay object so that it takes a new duration after a timepoint that is automatically computed to - * enforce the old delay at the moment of the update. Returns the updated Delay object and the timestamp when the - * new delay becomes effective. - */ - function withUpdate( - Delay self, - uint32 newValue, - uint32 minSetback - ) internal view returns (Delay updatedDelay, uint48 effect) { - uint32 value = self.get(); - uint32 setback = uint32(Math.max(minSetback, value > newValue ? value - newValue : 0)); - effect = timestamp() + setback; - return (pack(value, newValue, effect), effect); - } - - /** - * @dev Split a delay into its components: valueBefore, valueAfter and effect (transition timepoint). - */ - function unpack(Delay self) internal pure returns (uint32 valueBefore, uint32 valueAfter, uint48 effect) { - uint112 raw = Delay.unwrap(self); - - valueAfter = uint32(raw); - valueBefore = uint32(raw >> 32); - effect = uint48(raw >> 64); - - return (valueBefore, valueAfter, effect); - } - - /** - * @dev pack the components into a Delay object. - */ - function pack(uint32 valueBefore, uint32 valueAfter, uint48 effect) internal pure returns (Delay) { - return Delay.wrap((uint112(effect) << 64) | (uint112(valueBefore) << 32) | uint112(valueAfter)); - } -} diff --git a/lib/openzeppelin-contracts/contracts/vendor/compound/ICompoundTimelock.sol b/lib/openzeppelin-contracts/contracts/vendor/compound/ICompoundTimelock.sol deleted file mode 100644 index 320eea1..0000000 --- a/lib/openzeppelin-contracts/contracts/vendor/compound/ICompoundTimelock.sol +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (vendor/compound/ICompoundTimelock.sol) - -pragma solidity ^0.8.20; - -/** - * https://github.com/compound-finance/compound-protocol/blob/master/contracts/Timelock.sol[Compound 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/openzeppelin-contracts/contracts/vendor/compound/LICENSE b/lib/openzeppelin-contracts/contracts/vendor/compound/LICENSE deleted file mode 100644 index 7da2324..0000000 --- a/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/openzeppelin-contracts/foundry.toml b/lib/openzeppelin-contracts/foundry.toml deleted file mode 100644 index 3f60b7c..0000000 --- a/lib/openzeppelin-contracts/foundry.toml +++ /dev/null @@ -1,14 +0,0 @@ -[profile.default] -solc_version = '0.8.24' -evm_version = 'cancun' -optimizer = true -optimizer-runs = 200 -src = 'contracts' -out = 'out' -libs = ['node_modules', 'lib'] -test = 'test' -cache_path = 'cache_forge' - -[fuzz] -runs = 5000 -max_test_rejects = 150000 diff --git a/lib/openzeppelin-contracts/fv-requirements.txt b/lib/openzeppelin-contracts/fv-requirements.txt deleted file mode 100644 index 920662b..0000000 --- a/lib/openzeppelin-contracts/fv-requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -certora-cli==4.13.1 -# File uses a custom name (fv-requirements.txt) so that it isn't picked by Netlify's build -# whose latest Python version is 0.3.8, incompatible with most recent versions of Halmos -halmos==0.1.13 diff --git a/lib/openzeppelin-contracts/hardhat.config.js b/lib/openzeppelin-contracts/hardhat.config.js deleted file mode 100644 index d39d3d0..0000000 --- a/lib/openzeppelin-contracts/hardhat.config.js +++ /dev/null @@ -1,124 +0,0 @@ -/// ENVVAR -// - COMPILER: compiler version (default: 0.8.24) -// - SRC: contracts folder to compile (default: contracts) -// - RUNS: number of optimization runs (default: 200) -// - IR: enable IR compilation (default: false) -// - COVERAGE: enable coverage report (default: false) -// - GAS: enable gas report (default: false) -// - COINMARKETCAP: coinmarketcap api key for USD value in gas report -// - CI: output gas report to file instead of stdout - -const fs = require('fs'); -const path = require('path'); - -const { argv } = require('yargs/yargs')() - .env('') - .options({ - // Compilation settings - compiler: { - alias: 'compileVersion', - type: 'string', - default: '0.8.24', - }, - src: { - alias: 'source', - type: 'string', - default: 'contracts', - }, - runs: { - alias: 'optimizationRuns', - type: 'number', - default: 200, - }, - ir: { - alias: 'enableIR', - type: 'boolean', - default: false, - }, - evm: { - alias: 'evmVersion', - type: 'string', - default: 'cancun', - }, - // Extra modules - coverage: { - type: 'boolean', - default: false, - }, - gas: { - alias: 'enableGasReport', - type: 'boolean', - default: false, - }, - coinmarketcap: { - alias: 'coinmarketcapApiKey', - type: 'string', - }, - }); - -require('@nomicfoundation/hardhat-chai-matchers'); -require('@nomicfoundation/hardhat-ethers'); -require('hardhat-exposed'); -require('hardhat-gas-reporter'); -require('hardhat-ignore-warnings'); -require('solidity-coverage'); -require('solidity-docgen'); - -for (const f of fs.readdirSync(path.join(__dirname, 'hardhat'))) { - require(path.join(__dirname, 'hardhat', f)); -} - -/** - * @type import('hardhat/config').HardhatUserConfig - */ -module.exports = { - solidity: { - version: argv.compiler, - settings: { - optimizer: { - enabled: true, - runs: argv.runs, - }, - evmVersion: argv.evm, - viaIR: argv.ir, - outputSelection: { '*': { '*': ['storageLayout'] } }, - }, - }, - warnings: { - 'contracts-exposed/**/*': { - 'code-size': 'off', - 'initcode-size': 'off', - }, - '*': { - 'code-size': true, - 'unused-param': !argv.coverage, // coverage causes unused-param warnings - 'transient-storage': false, - default: 'error', - }, - }, - networks: { - hardhat: { - hardfork: argv.evm, - // Exposed contracts often exceed the maximum contract size. For normal contract, - // we rely on the `code-size` compiler warning, that will cause a compilation error. - allowUnlimitedContractSize: true, - initialBaseFeePerGas: argv.coverage ? 0 : undefined, - }, - }, - exposed: { - imports: true, - initializers: true, - exclude: ['vendor/**/*', '**/*WithInit.sol'], - }, - gasReporter: { - enabled: argv.gas, - showMethodSig: true, - includeBytecodeInJSON: true, - currency: 'USD', - coinmarketcap: argv.coinmarketcap, - }, - paths: { - sources: argv.src, - }, - docgen: require('./docs/config'), -}; diff --git a/lib/openzeppelin-contracts/hardhat/async-test-sanity.js b/lib/openzeppelin-contracts/hardhat/async-test-sanity.js deleted file mode 100644 index c05e5bd..0000000 --- a/lib/openzeppelin-contracts/hardhat/async-test-sanity.js +++ /dev/null @@ -1,3 +0,0 @@ -process.on('unhandledRejection', reason => { - throw new Error(reason); -}); diff --git a/lib/openzeppelin-contracts/hardhat/env-artifacts.js b/lib/openzeppelin-contracts/hardhat/env-artifacts.js deleted file mode 100644 index e97ae64..0000000 --- a/lib/openzeppelin-contracts/hardhat/env-artifacts.js +++ /dev/null @@ -1,29 +0,0 @@ -const { HardhatError } = require('hardhat/internal/core/errors'); - -function isExpectedError(e, suffix) { - // HH700: Artifact not found - from https://hardhat.org/hardhat-runner/docs/errors#HH700 - return HardhatError.isHardhatError(e) && e.number === 700 && suffix !== ''; -} - -// Modifies the artifact require functions so that instead of X it loads the XUpgradeable contract. -// This allows us to run the same test suite on both the original and the transpiled and renamed Upgradeable contracts. -extendEnvironment(hre => { - const suffixes = ['UpgradeableWithInit', 'Upgradeable', '']; - - // Ethers - const originalReadArtifact = hre.artifacts.readArtifact; - hre.artifacts.readArtifact = async function (name) { - for (const suffix of suffixes) { - try { - return await originalReadArtifact.call(this, name + suffix); - } catch (e) { - if (isExpectedError(e, suffix)) { - continue; - } else { - throw e; - } - } - } - throw new Error('Unreachable'); - }; -}); diff --git a/lib/openzeppelin-contracts/hardhat/ignore-unreachable-warnings.js b/lib/openzeppelin-contracts/hardhat/ignore-unreachable-warnings.js deleted file mode 100644 index 8e3e343..0000000 --- a/lib/openzeppelin-contracts/hardhat/ignore-unreachable-warnings.js +++ /dev/null @@ -1,45 +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/openzeppelin-contracts/hardhat/remappings.js b/lib/openzeppelin-contracts/hardhat/remappings.js deleted file mode 100644 index cd9984d..0000000 --- a/lib/openzeppelin-contracts/hardhat/remappings.js +++ /dev/null @@ -1,18 +0,0 @@ -const fs = require('fs'); -const { task } = require('hardhat/config'); -const { TASK_COMPILE_GET_REMAPPINGS } = require('hardhat/builtin-tasks/task-names'); - -task(TASK_COMPILE_GET_REMAPPINGS).setAction((taskArgs, env, runSuper) => - runSuper().then(remappings => - Object.assign( - remappings, - Object.fromEntries( - fs - .readFileSync('remappings.txt', 'utf-8') - .split('\n') - .filter(Boolean) - .map(line => line.trim().split('=')), - ), - ), - ), -); diff --git a/lib/openzeppelin-contracts/hardhat/skip-foundry-tests.js b/lib/openzeppelin-contracts/hardhat/skip-foundry-tests.js deleted file mode 100644 index 965ba37..0000000 --- a/lib/openzeppelin-contracts/hardhat/skip-foundry-tests.js +++ /dev/null @@ -1,6 +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/openzeppelin-contracts/hardhat/task-test-get-files.js b/lib/openzeppelin-contracts/hardhat/task-test-get-files.js deleted file mode 100644 index 108f40a..0000000 --- a/lib/openzeppelin-contracts/hardhat/task-test-get-files.js +++ /dev/null @@ -1,25 +0,0 @@ -const { internalTask } = require('hardhat/config'); -const { TASK_TEST_GET_TEST_FILES } = require('hardhat/builtin-tasks/task-names'); - -// Modifies `hardhat test` to skip the proxy tests after proxies are removed by the transpiler for upgradeability. - -internalTask(TASK_TEST_GET_TEST_FILES).setAction(async (args, hre, runSuper) => { - const path = require('path'); - const { promises: fs } = require('fs'); - - const hasProxies = await fs - .access(path.join(hre.config.paths.sources, 'proxy/Proxy.sol')) - .then(() => true) - .catch(() => false); - - const ignoredIfProxy = [ - 'proxy/beacon/BeaconProxy.test.js', - 'proxy/beacon/UpgradeableBeacon.test.js', - 'proxy/ERC1967/ERC1967Proxy.test.js', - 'proxy/transparent/ProxyAdmin.test.js', - 'proxy/transparent/TransparentUpgradeableProxy.test.js', - 'proxy/utils/UUPSUpgradeable.test.js', - ].map(p => path.join(hre.config.paths.tests, p)); - - return (await runSuper(args)).filter(file => hasProxies || !ignoredIfProxy.includes(file)); -}); diff --git a/lib/openzeppelin-contracts/lib/erc4626-tests/ERC4626.prop.sol b/lib/openzeppelin-contracts/lib/erc4626-tests/ERC4626.prop.sol deleted file mode 100644 index c34512b..0000000 --- a/lib/openzeppelin-contracts/lib/erc4626-tests/ERC4626.prop.sol +++ /dev/null @@ -1,404 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity >=0.8.0 <0.9.0; - -import "forge-std/Test.sol"; - -// TODO: use interface provided by forge-std v1.0.0 or later -// import {IERC20} from "forge-std/interfaces/IERC20.sol"; -interface IERC20 { - event Transfer(address indexed from, address indexed to, uint value); - event Approval(address indexed owner, address indexed spender, uint value); - function totalSupply() external view returns (uint); - function balanceOf(address account) external view returns (uint); - function transfer(address to, uint amount) external returns (bool); - function allowance(address owner, address spender) external view returns (uint); - function approve(address spender, uint amount) external returns (bool); - function transferFrom(address from, address to, uint amount) external returns (bool); -} - -// TODO: use interface provided by forge-std v1.0.0 or later -// import {IERC4626} from "forge-std/interfaces/IERC4626.sol"; -interface IERC4626 is IERC20 { - event Deposit(address indexed caller, address indexed owner, uint assets, uint shares); - event Withdraw(address indexed caller, address indexed receiver, address indexed owner, uint assets, uint shares); - function asset() external view returns (address assetTokenAddress); - function totalAssets() external view returns (uint totalManagedAssets); - function convertToShares(uint assets) external view returns (uint shares); - function convertToAssets(uint shares) external view returns (uint assets); - function maxDeposit(address receiver) external view returns (uint maxAssets); - function previewDeposit(uint assets) external view returns (uint shares); - function deposit(uint assets, address receiver) external returns (uint shares); - function maxMint(address receiver) external view returns (uint maxShares); - function previewMint(uint shares) external view returns (uint assets); - function mint(uint shares, address receiver) external returns (uint assets); - function maxWithdraw(address owner) external view returns (uint maxAssets); - function previewWithdraw(uint assets) external view returns (uint shares); - function withdraw(uint assets, address receiver, address owner) external returns (uint shares); - function maxRedeem(address owner) external view returns (uint maxShares); - function previewRedeem(uint shares) external view returns (uint assets); - function redeem(uint shares, address receiver, address owner) external returns (uint assets); -} - -abstract contract ERC4626Prop is Test { - uint internal _delta_; - - address internal _underlying_; - address internal _vault_; - - bool internal _vaultMayBeEmpty; - bool internal _unlimitedAmount; - - // - // asset - // - - // asset - // "MUST NOT revert." - function prop_asset(address caller) public { - vm.prank(caller); IERC4626(_vault_).asset(); - } - - // totalAssets - // "MUST NOT revert." - function prop_totalAssets(address caller) public { - vm.prank(caller); IERC4626(_vault_).totalAssets(); - } - - // - // convert - // - - // convertToShares - // "MUST NOT show any variations depending on the caller." - function prop_convertToShares(address caller1, address caller2, uint assets) public { - vm.prank(caller1); uint res1 = vault_convertToShares(assets); // "MAY revert due to integer overflow caused by an unreasonably large input." - vm.prank(caller2); uint res2 = vault_convertToShares(assets); // "MAY revert due to integer overflow caused by an unreasonably large input." - assertEq(res1, res2); - } - - // convertToAssets - // "MUST NOT show any variations depending on the caller." - function prop_convertToAssets(address caller1, address caller2, uint shares) public { - vm.prank(caller1); uint res1 = vault_convertToAssets(shares); // "MAY revert due to integer overflow caused by an unreasonably large input." - vm.prank(caller2); uint res2 = vault_convertToAssets(shares); // "MAY revert due to integer overflow caused by an unreasonably large input." - assertEq(res1, res2); - } - - // - // deposit - // - - // maxDeposit - // "MUST NOT revert." - function prop_maxDeposit(address caller, address receiver) public { - vm.prank(caller); IERC4626(_vault_).maxDeposit(receiver); - } - - // previewDeposit - // "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." - function prop_previewDeposit(address caller, address receiver, address other, uint assets) public { - vm.prank(other); uint sharesPreview = vault_previewDeposit(assets); // "MAY revert due to other conditions that would also cause deposit to revert." - vm.prank(caller); uint sharesActual = vault_deposit(assets, receiver); - assertApproxGeAbs(sharesActual, sharesPreview, _delta_); - } - - // deposit - function prop_deposit(address caller, address receiver, uint assets) public { - uint oldCallerAsset = IERC20(_underlying_).balanceOf(caller); - uint oldReceiverShare = IERC20(_vault_).balanceOf(receiver); - uint oldAllowance = IERC20(_underlying_).allowance(caller, _vault_); - - vm.prank(caller); uint shares = vault_deposit(assets, receiver); - - uint newCallerAsset = IERC20(_underlying_).balanceOf(caller); - uint newReceiverShare = IERC20(_vault_).balanceOf(receiver); - uint newAllowance = IERC20(_underlying_).allowance(caller, _vault_); - - assertApproxEqAbs(newCallerAsset, oldCallerAsset - assets, _delta_, "asset"); // NOTE: this may fail if the caller is a contract in which the asset is stored - assertApproxEqAbs(newReceiverShare, oldReceiverShare + shares, _delta_, "share"); - if (oldAllowance != type(uint).max) assertApproxEqAbs(newAllowance, oldAllowance - assets, _delta_, "allowance"); - } - - // - // mint - // - - // maxMint - // "MUST NOT revert." - function prop_maxMint(address caller, address receiver) public { - vm.prank(caller); IERC4626(_vault_).maxMint(receiver); - } - - // previewMint - // "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." - function prop_previewMint(address caller, address receiver, address other, uint shares) public { - vm.prank(other); uint assetsPreview = vault_previewMint(shares); - vm.prank(caller); uint assetsActual = vault_mint(shares, receiver); - assertApproxLeAbs(assetsActual, assetsPreview, _delta_); - } - - // mint - function prop_mint(address caller, address receiver, uint shares) public { - uint oldCallerAsset = IERC20(_underlying_).balanceOf(caller); - uint oldReceiverShare = IERC20(_vault_).balanceOf(receiver); - uint oldAllowance = IERC20(_underlying_).allowance(caller, _vault_); - - vm.prank(caller); uint assets = vault_mint(shares, receiver); - - uint newCallerAsset = IERC20(_underlying_).balanceOf(caller); - uint newReceiverShare = IERC20(_vault_).balanceOf(receiver); - uint newAllowance = IERC20(_underlying_).allowance(caller, _vault_); - - assertApproxEqAbs(newCallerAsset, oldCallerAsset - assets, _delta_, "asset"); // NOTE: this may fail if the caller is a contract in which the asset is stored - assertApproxEqAbs(newReceiverShare, oldReceiverShare + shares, _delta_, "share"); - if (oldAllowance != type(uint).max) assertApproxEqAbs(newAllowance, oldAllowance - assets, _delta_, "allowance"); - } - - // - // withdraw - // - - // maxWithdraw - // "MUST NOT revert." - // NOTE: some implementations failed due to arithmetic overflow - function prop_maxWithdraw(address caller, address owner) public { - vm.prank(caller); IERC4626(_vault_).maxWithdraw(owner); - } - - // previewWithdraw - // "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." - function prop_previewWithdraw(address caller, address receiver, address owner, address other, uint assets) public { - vm.prank(other); uint preview = vault_previewWithdraw(assets); - vm.prank(caller); uint actual = vault_withdraw(assets, receiver, owner); - assertApproxLeAbs(actual, preview, _delta_); - } - - // withdraw - function prop_withdraw(address caller, address receiver, address owner, uint assets) public { - uint oldReceiverAsset = IERC20(_underlying_).balanceOf(receiver); - uint oldOwnerShare = IERC20(_vault_).balanceOf(owner); - uint oldAllowance = IERC20(_vault_).allowance(owner, caller); - - vm.prank(caller); uint shares = vault_withdraw(assets, receiver, owner); - - uint newReceiverAsset = IERC20(_underlying_).balanceOf(receiver); - uint newOwnerShare = IERC20(_vault_).balanceOf(owner); - uint newAllowance = IERC20(_vault_).allowance(owner, caller); - - assertApproxEqAbs(newOwnerShare, oldOwnerShare - shares, _delta_, "share"); - assertApproxEqAbs(newReceiverAsset, oldReceiverAsset + assets, _delta_, "asset"); // NOTE: this may fail if the receiver is a contract in which the asset is stored - if (caller != owner && oldAllowance != type(uint).max) assertApproxEqAbs(newAllowance, oldAllowance - shares, _delta_, "allowance"); - - assertTrue(caller == owner || oldAllowance != 0 || (shares == 0 && assets == 0), "access control"); - } - - // - // redeem - // - - // maxRedeem - // "MUST NOT revert." - function prop_maxRedeem(address caller, address owner) public { - vm.prank(caller); IERC4626(_vault_).maxRedeem(owner); - } - - // previewRedeem - // "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." - function prop_previewRedeem(address caller, address receiver, address owner, address other, uint shares) public { - vm.prank(other); uint preview = vault_previewRedeem(shares); - vm.prank(caller); uint actual = vault_redeem(shares, receiver, owner); - assertApproxGeAbs(actual, preview, _delta_); - } - - // redeem - function prop_redeem(address caller, address receiver, address owner, uint shares) public { - uint oldReceiverAsset = IERC20(_underlying_).balanceOf(receiver); - uint oldOwnerShare = IERC20(_vault_).balanceOf(owner); - uint oldAllowance = IERC20(_vault_).allowance(owner, caller); - - vm.prank(caller); uint assets = vault_redeem(shares, receiver, owner); - - uint newReceiverAsset = IERC20(_underlying_).balanceOf(receiver); - uint newOwnerShare = IERC20(_vault_).balanceOf(owner); - uint newAllowance = IERC20(_vault_).allowance(owner, caller); - - assertApproxEqAbs(newOwnerShare, oldOwnerShare - shares, _delta_, "share"); - assertApproxEqAbs(newReceiverAsset, oldReceiverAsset + assets, _delta_, "asset"); // NOTE: this may fail if the receiver is a contract in which the asset is stored - if (caller != owner && oldAllowance != type(uint).max) assertApproxEqAbs(newAllowance, oldAllowance - shares, _delta_, "allowance"); - - assertTrue(caller == owner || oldAllowance != 0 || (shares == 0 && assets == 0), "access control"); - } - - // - // round trip properties - // - - // redeem(deposit(a)) <= a - function prop_RT_deposit_redeem(address caller, uint assets) public { - if (!_vaultMayBeEmpty) vm.assume(IERC20(_vault_).totalSupply() > 0); - vm.prank(caller); uint shares = vault_deposit(assets, caller); - vm.prank(caller); uint assets2 = vault_redeem(shares, caller, caller); - assertApproxLeAbs(assets2, assets, _delta_); - } - - // s = deposit(a) - // s' = withdraw(a) - // s' >= s - function prop_RT_deposit_withdraw(address caller, uint assets) public { - if (!_vaultMayBeEmpty) vm.assume(IERC20(_vault_).totalSupply() > 0); - vm.prank(caller); uint shares1 = vault_deposit(assets, caller); - vm.prank(caller); uint shares2 = vault_withdraw(assets, caller, caller); - assertApproxGeAbs(shares2, shares1, _delta_); - } - - // deposit(redeem(s)) <= s - function prop_RT_redeem_deposit(address caller, uint shares) public { - vm.prank(caller); uint assets = vault_redeem(shares, caller, caller); - if (!_vaultMayBeEmpty) vm.assume(IERC20(_vault_).totalSupply() > 0); - vm.prank(caller); uint shares2 = vault_deposit(assets, caller); - assertApproxLeAbs(shares2, shares, _delta_); - } - - // a = redeem(s) - // a' = mint(s) - // a' >= a - function prop_RT_redeem_mint(address caller, uint shares) public { - vm.prank(caller); uint assets1 = vault_redeem(shares, caller, caller); - if (!_vaultMayBeEmpty) vm.assume(IERC20(_vault_).totalSupply() > 0); - vm.prank(caller); uint assets2 = vault_mint(shares, caller); - assertApproxGeAbs(assets2, assets1, _delta_); - } - - // withdraw(mint(s)) >= s - function prop_RT_mint_withdraw(address caller, uint shares) public { - if (!_vaultMayBeEmpty) vm.assume(IERC20(_vault_).totalSupply() > 0); - vm.prank(caller); uint assets = vault_mint(shares, caller); - vm.prank(caller); uint shares2 = vault_withdraw(assets, caller, caller); - assertApproxGeAbs(shares2, shares, _delta_); - } - - // a = mint(s) - // a' = redeem(s) - // a' <= a - function prop_RT_mint_redeem(address caller, uint shares) public { - if (!_vaultMayBeEmpty) vm.assume(IERC20(_vault_).totalSupply() > 0); - vm.prank(caller); uint assets1 = vault_mint(shares, caller); - vm.prank(caller); uint assets2 = vault_redeem(shares, caller, caller); - assertApproxLeAbs(assets2, assets1, _delta_); - } - - // mint(withdraw(a)) >= a - function prop_RT_withdraw_mint(address caller, uint assets) public { - vm.prank(caller); uint shares = vault_withdraw(assets, caller, caller); - if (!_vaultMayBeEmpty) vm.assume(IERC20(_vault_).totalSupply() > 0); - vm.prank(caller); uint assets2 = vault_mint(shares, caller); - assertApproxGeAbs(assets2, assets, _delta_); - } - - // s = withdraw(a) - // s' = deposit(a) - // s' <= s - function prop_RT_withdraw_deposit(address caller, uint assets) public { - vm.prank(caller); uint shares1 = vault_withdraw(assets, caller, caller); - if (!_vaultMayBeEmpty) vm.assume(IERC20(_vault_).totalSupply() > 0); - vm.prank(caller); uint shares2 = vault_deposit(assets, caller); - assertApproxLeAbs(shares2, shares1, _delta_); - } - - // - // utils - // - - function vault_convertToShares(uint assets) internal returns (uint) { - return _call_vault(abi.encodeWithSelector(IERC4626.convertToShares.selector, assets)); - } - function vault_convertToAssets(uint shares) internal returns (uint) { - return _call_vault(abi.encodeWithSelector(IERC4626.convertToAssets.selector, shares)); - } - - function vault_maxDeposit(address receiver) internal returns (uint) { - return _call_vault(abi.encodeWithSelector(IERC4626.maxDeposit.selector, receiver)); - } - function vault_maxMint(address receiver) internal returns (uint) { - return _call_vault(abi.encodeWithSelector(IERC4626.maxMint.selector, receiver)); - } - function vault_maxWithdraw(address owner) internal returns (uint) { - return _call_vault(abi.encodeWithSelector(IERC4626.maxWithdraw.selector, owner)); - } - function vault_maxRedeem(address owner) internal returns (uint) { - return _call_vault(abi.encodeWithSelector(IERC4626.maxRedeem.selector, owner)); - } - - function vault_previewDeposit(uint assets) internal returns (uint) { - return _call_vault(abi.encodeWithSelector(IERC4626.previewDeposit.selector, assets)); - } - function vault_previewMint(uint shares) internal returns (uint) { - return _call_vault(abi.encodeWithSelector(IERC4626.previewMint.selector, shares)); - } - function vault_previewWithdraw(uint assets) internal returns (uint) { - return _call_vault(abi.encodeWithSelector(IERC4626.previewWithdraw.selector, assets)); - } - function vault_previewRedeem(uint shares) internal returns (uint) { - return _call_vault(abi.encodeWithSelector(IERC4626.previewRedeem.selector, shares)); - } - - function vault_deposit(uint assets, address receiver) internal returns (uint) { - return _call_vault(abi.encodeWithSelector(IERC4626.deposit.selector, assets, receiver)); - } - function vault_mint(uint shares, address receiver) internal returns (uint) { - return _call_vault(abi.encodeWithSelector(IERC4626.mint.selector, shares, receiver)); - } - function vault_withdraw(uint assets, address receiver, address owner) internal returns (uint) { - return _call_vault(abi.encodeWithSelector(IERC4626.withdraw.selector, assets, receiver, owner)); - } - function vault_redeem(uint shares, address receiver, address owner) internal returns (uint) { - return _call_vault(abi.encodeWithSelector(IERC4626.redeem.selector, shares, receiver, owner)); - } - - function _call_vault(bytes memory data) internal returns (uint) { - (bool success, bytes memory retdata) = _vault_.call(data); - if (success) return abi.decode(retdata, (uint)); - vm.assume(false); // if reverted, discard the current fuzz inputs, and let the fuzzer to start a new fuzz run - return 0; // silence warning - } - - function assertApproxGeAbs(uint a, uint b, uint maxDelta) internal { - if (!(a >= b)) { - uint dt = b - a; - if (dt > maxDelta) { - emit log ("Error: a >=~ b not satisfied [uint]"); - emit log_named_uint (" Value a", a); - emit log_named_uint (" Value b", b); - emit log_named_uint (" Max Delta", maxDelta); - emit log_named_uint (" Delta", dt); - fail(); - } - } - } - - function assertApproxLeAbs(uint a, uint b, uint maxDelta) internal { - if (!(a <= b)) { - uint dt = a - b; - if (dt > maxDelta) { - emit log ("Error: a <=~ b not satisfied [uint]"); - emit log_named_uint (" Value a", a); - emit log_named_uint (" Value b", b); - emit log_named_uint (" Max Delta", maxDelta); - emit log_named_uint (" Delta", dt); - fail(); - } - } - } -} diff --git a/lib/openzeppelin-contracts/lib/erc4626-tests/ERC4626.test.sol b/lib/openzeppelin-contracts/lib/erc4626-tests/ERC4626.test.sol deleted file mode 100644 index 6254a05..0000000 --- a/lib/openzeppelin-contracts/lib/erc4626-tests/ERC4626.test.sol +++ /dev/null @@ -1,349 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity >=0.8.0 <0.9.0; - -import "./ERC4626.prop.sol"; - -interface IMockERC20 is IERC20 { - function mint(address to, uint value) external; - function burn(address from, uint value) external; -} - -abstract contract ERC4626Test is ERC4626Prop { - function setUp() public virtual; - - uint constant N = 4; - - struct Init { - address[N] user; - uint[N] share; - uint[N] asset; - int yield; - } - - // setup initial vault state as follows: - // - // totalAssets == sum(init.share) + init.yield - // totalShares == sum(init.share) - // - // init.user[i]'s assets == init.asset[i] - // init.user[i]'s shares == init.share[i] - function setUpVault(Init memory init) public virtual { - // setup initial shares and assets for individual users - for (uint i = 0; i < N; i++) { - address user = init.user[i]; - vm.assume(_isEOA(user)); - // shares - uint shares = init.share[i]; - try IMockERC20(_underlying_).mint(user, shares) {} catch { vm.assume(false); } - _approve(_underlying_, user, _vault_, shares); - vm.prank(user); try IERC4626(_vault_).deposit(shares, user) {} catch { vm.assume(false); } - // assets - uint assets = init.asset[i]; - try IMockERC20(_underlying_).mint(user, assets) {} catch { vm.assume(false); } - } - - // setup initial yield for vault - setUpYield(init); - } - - // setup initial yield - function setUpYield(Init memory init) public virtual { - if (init.yield >= 0) { // gain - uint gain = uint(init.yield); - try IMockERC20(_underlying_).mint(_vault_, gain) {} catch { vm.assume(false); } // this can be replaced by calling yield generating functions if provided by the vault - } else { // loss - vm.assume(init.yield > type(int).min); // avoid overflow in conversion - uint loss = uint(-1 * init.yield); - try IMockERC20(_underlying_).burn(_vault_, loss) {} catch { vm.assume(false); } // this can be replaced by calling yield generating functions if provided by the vault - } - } - - // - // asset - // - - function test_asset(Init memory init) public virtual { - setUpVault(init); - address caller = init.user[0]; - prop_asset(caller); - } - - function test_totalAssets(Init memory init) public virtual { - setUpVault(init); - address caller = init.user[0]; - prop_totalAssets(caller); - } - - // - // convert - // - - function test_convertToShares(Init memory init, uint assets) public virtual { - setUpVault(init); - address caller1 = init.user[0]; - address caller2 = init.user[1]; - prop_convertToShares(caller1, caller2, assets); - } - - function test_convertToAssets(Init memory init, uint shares) public virtual { - setUpVault(init); - address caller1 = init.user[0]; - address caller2 = init.user[1]; - prop_convertToAssets(caller1, caller2, shares); - } - - // - // deposit - // - - function test_maxDeposit(Init memory init) public virtual { - setUpVault(init); - address caller = init.user[0]; - address receiver = init.user[1]; - prop_maxDeposit(caller, receiver); - } - - function test_previewDeposit(Init memory init, uint assets) public virtual { - setUpVault(init); - address caller = init.user[0]; - address receiver = init.user[1]; - address other = init.user[2]; - assets = bound(assets, 0, _max_deposit(caller)); - _approve(_underlying_, caller, _vault_, type(uint).max); - prop_previewDeposit(caller, receiver, other, assets); - } - - function test_deposit(Init memory init, uint assets, uint allowance) public virtual { - setUpVault(init); - address caller = init.user[0]; - address receiver = init.user[1]; - assets = bound(assets, 0, _max_deposit(caller)); - _approve(_underlying_, caller, _vault_, allowance); - prop_deposit(caller, receiver, assets); - } - - // - // mint - // - - function test_maxMint(Init memory init) public virtual { - setUpVault(init); - address caller = init.user[0]; - address receiver = init.user[1]; - prop_maxMint(caller, receiver); - } - - function test_previewMint(Init memory init, uint shares) public virtual { - setUpVault(init); - address caller = init.user[0]; - address receiver = init.user[1]; - address other = init.user[2]; - shares = bound(shares, 0, _max_mint(caller)); - _approve(_underlying_, caller, _vault_, type(uint).max); - prop_previewMint(caller, receiver, other, shares); - } - - function test_mint(Init memory init, uint shares, uint allowance) public virtual { - setUpVault(init); - address caller = init.user[0]; - address receiver = init.user[1]; - shares = bound(shares, 0, _max_mint(caller)); - _approve(_underlying_, caller, _vault_, allowance); - prop_mint(caller, receiver, shares); - } - - // - // withdraw - // - - function test_maxWithdraw(Init memory init) public virtual { - setUpVault(init); - address caller = init.user[0]; - address owner = init.user[1]; - prop_maxWithdraw(caller, owner); - } - - function test_previewWithdraw(Init memory init, uint assets) public virtual { - setUpVault(init); - address caller = init.user[0]; - address receiver = init.user[1]; - address owner = init.user[2]; - address other = init.user[3]; - assets = bound(assets, 0, _max_withdraw(owner)); - _approve(_vault_, owner, caller, type(uint).max); - prop_previewWithdraw(caller, receiver, owner, other, assets); - } - - function test_withdraw(Init memory init, uint assets, uint allowance) public virtual { - setUpVault(init); - address caller = init.user[0]; - address receiver = init.user[1]; - address owner = init.user[2]; - assets = bound(assets, 0, _max_withdraw(owner)); - _approve(_vault_, owner, caller, allowance); - prop_withdraw(caller, receiver, owner, assets); - } - - function testFail_withdraw(Init memory init, uint assets) public virtual { - setUpVault(init); - address caller = init.user[0]; - address receiver = init.user[1]; - address owner = init.user[2]; - assets = bound(assets, 0, _max_withdraw(owner)); - vm.assume(caller != owner); - vm.assume(assets > 0); - _approve(_vault_, owner, caller, 0); - vm.prank(caller); uint shares = IERC4626(_vault_).withdraw(assets, receiver, owner); - assertGt(shares, 0); // this assert is expected to fail - } - - // - // redeem - // - - function test_maxRedeem(Init memory init) public virtual { - setUpVault(init); - address caller = init.user[0]; - address owner = init.user[1]; - prop_maxRedeem(caller, owner); - } - - function test_previewRedeem(Init memory init, uint shares) public virtual { - setUpVault(init); - address caller = init.user[0]; - address receiver = init.user[1]; - address owner = init.user[2]; - address other = init.user[3]; - shares = bound(shares, 0, _max_redeem(owner)); - _approve(_vault_, owner, caller, type(uint).max); - prop_previewRedeem(caller, receiver, owner, other, shares); - } - - function test_redeem(Init memory init, uint shares, uint allowance) public virtual { - setUpVault(init); - address caller = init.user[0]; - address receiver = init.user[1]; - address owner = init.user[2]; - shares = bound(shares, 0, _max_redeem(owner)); - _approve(_vault_, owner, caller, allowance); - prop_redeem(caller, receiver, owner, shares); - } - - function testFail_redeem(Init memory init, uint shares) public virtual { - setUpVault(init); - address caller = init.user[0]; - address receiver = init.user[1]; - address owner = init.user[2]; - shares = bound(shares, 0, _max_redeem(owner)); - vm.assume(caller != owner); - vm.assume(shares > 0); - _approve(_vault_, owner, caller, 0); - vm.prank(caller); IERC4626(_vault_).redeem(shares, receiver, owner); - } - - // - // round trip tests - // - - function test_RT_deposit_redeem(Init memory init, uint assets) public virtual { - setUpVault(init); - address caller = init.user[0]; - assets = bound(assets, 0, _max_deposit(caller)); - _approve(_underlying_, caller, _vault_, type(uint).max); - prop_RT_deposit_redeem(caller, assets); - } - - function test_RT_deposit_withdraw(Init memory init, uint assets) public virtual { - setUpVault(init); - address caller = init.user[0]; - assets = bound(assets, 0, _max_deposit(caller)); - _approve(_underlying_, caller, _vault_, type(uint).max); - prop_RT_deposit_withdraw(caller, assets); - } - - function test_RT_redeem_deposit(Init memory init, uint shares) public virtual { - setUpVault(init); - address caller = init.user[0]; - shares = bound(shares, 0, _max_redeem(caller)); - _approve(_underlying_, caller, _vault_, type(uint).max); - prop_RT_redeem_deposit(caller, shares); - } - - function test_RT_redeem_mint(Init memory init, uint shares) public virtual { - setUpVault(init); - address caller = init.user[0]; - shares = bound(shares, 0, _max_redeem(caller)); - _approve(_underlying_, caller, _vault_, type(uint).max); - prop_RT_redeem_mint(caller, shares); - } - - function test_RT_mint_withdraw(Init memory init, uint shares) public virtual { - setUpVault(init); - address caller = init.user[0]; - shares = bound(shares, 0, _max_mint(caller)); - _approve(_underlying_, caller, _vault_, type(uint).max); - prop_RT_mint_withdraw(caller, shares); - } - - function test_RT_mint_redeem(Init memory init, uint shares) public virtual { - setUpVault(init); - address caller = init.user[0]; - shares = bound(shares, 0, _max_mint(caller)); - _approve(_underlying_, caller, _vault_, type(uint).max); - prop_RT_mint_redeem(caller, shares); - } - - function test_RT_withdraw_mint(Init memory init, uint assets) public virtual { - setUpVault(init); - address caller = init.user[0]; - assets = bound(assets, 0, _max_withdraw(caller)); - _approve(_underlying_, caller, _vault_, type(uint).max); - prop_RT_withdraw_mint(caller, assets); - } - - function test_RT_withdraw_deposit(Init memory init, uint assets) public virtual { - setUpVault(init); - address caller = init.user[0]; - assets = bound(assets, 0, _max_withdraw(caller)); - _approve(_underlying_, caller, _vault_, type(uint).max); - prop_RT_withdraw_deposit(caller, assets); - } - - // - // utils - // - - function _isContract(address account) internal view returns (bool) { return account.code.length > 0; } - function _isEOA (address account) internal view returns (bool) { return account.code.length == 0; } - - function _approve(address token, address owner, address spender, uint amount) internal { - vm.prank(owner); _safeApprove(token, spender, 0); - vm.prank(owner); _safeApprove(token, spender, amount); - } - - function _safeApprove(address token, address spender, uint amount) internal { - (bool success, bytes memory retdata) = token.call(abi.encodeWithSelector(IERC20.approve.selector, spender, amount)); - vm.assume(success); - if (retdata.length > 0) vm.assume(abi.decode(retdata, (bool))); - } - - function _max_deposit(address from) internal virtual returns (uint) { - if (_unlimitedAmount) return type(uint).max; - return IERC20(_underlying_).balanceOf(from); - } - - function _max_mint(address from) internal virtual returns (uint) { - if (_unlimitedAmount) return type(uint).max; - return vault_convertToShares(IERC20(_underlying_).balanceOf(from)); - } - - function _max_withdraw(address from) internal virtual returns (uint) { - if (_unlimitedAmount) return type(uint).max; - return vault_convertToAssets(IERC20(_vault_).balanceOf(from)); // may be different from maxWithdraw(from) - } - - function _max_redeem(address from) internal virtual returns (uint) { - if (_unlimitedAmount) return type(uint).max; - return IERC20(_vault_).balanceOf(from); // may be different from maxRedeem(from) - } -} diff --git a/lib/openzeppelin-contracts/lib/erc4626-tests/LICENSE b/lib/openzeppelin-contracts/lib/erc4626-tests/LICENSE deleted file mode 100644 index 0ad25db..0000000 --- a/lib/openzeppelin-contracts/lib/erc4626-tests/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/openzeppelin-contracts/lib/erc4626-tests/README.md b/lib/openzeppelin-contracts/lib/erc4626-tests/README.md deleted file mode 100644 index 651e443..0000000 --- a/lib/openzeppelin-contracts/lib/erc4626-tests/README.md +++ /dev/null @@ -1,116 +0,0 @@ -# ERC4626 Property Tests - -Foundry (dapptools-style) property-based tests for [ERC4626] standard conformance. - -[ERC4626]: - -You can read our post on "_[Generalized property tests for ERC4626 vaults][post]_." - -[post]: - -## Overview - -#### What is it? -- Test suites for checking if the given ERC4626 implementation satisfies the **standard requirements**. -- Dapptools-style **property-based tests** for fuzzing or symbolic execution testing. -- Tests that are **independent** from implementation details, thus applicable for any ERC4626 vaults. - -#### What isn’t it? -- It does NOT test implementation-specific details, e.g., how to generate and distribute yields, how to compute the share price, etc. - -#### Testing properties: - -- **Round-trip properties**: no one can make a free profit by depositing and immediately withdrawing back and forth. - -- **Functional correctness**: the `deposit()`, `mint()`, `withdraw()`, and `redeem()` functions update the balance and allowance properly. - -- The `preview{Deposit,Redeem}()` functions **MUST NOT over-estimate** the exact amount.[^1] - -[^1]: That is, the `deposit()` and `redeem()` functions “MUST return the same or more amounts as their preview function if called in the same transaction.” - -- The `preview{Mint,Withdraw}()` functions **MUST NOT under-estimate** the exact amount.[^2] - -[^2]: That is, the `mint()` and `withdraw()` functions “MUST return the same or fewer amounts as their preview function if called in the same transaction.” - -- The `convertTo{Shares,Assets}` functions “**MUST NOT show any variations** depending on the caller.” - -- The `asset()`, `totalAssets()`, and `max{Deposit,Mint,Withdraw,Redeem}()` functions “**MUST NOT revert**.” - -## Usage - -**Step 0**: Install [foundry] and add [forge-std] in your vault repo: -```bash -$ curl -L https://foundry.paradigm.xyz | bash - -$ cd /path/to/your-erc4626-vault -$ forge install foundry-rs/forge-std -``` - -[foundry]: -[forge-std]: - -**Step 1**: Add this [erc4626-tests] as a dependency to your vault: -```bash -$ cd /path/to/your-erc4626-vault -$ forge install a16z/erc4626-tests -``` - -[erc4626-tests]: - -**Step 2**: Extend the abstract test contract [`ERC4626Test`](ERC4626.test.sol) with your own custom vault setup method, for example: - -```solidity -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity >=0.8.0 <0.9.0; - -import "erc4626-tests/ERC4626.test.sol"; - -import { ERC20Mock } from "/path/to/mocks/ERC20Mock.sol"; -import { ERC4626Mock } from "/path/to/mocks/ERC4626Mock.sol"; - -contract ERC4626StdTest is ERC4626Test { - function setUp() public override { - _underlying_ = address(new ERC20Mock("Mock ERC20", "MERC20", 18)); - _vault_ = address(new ERC4626Mock(ERC20Mock(__underlying__), "Mock ERC4626", "MERC4626")); - _delta_ = 0; - _vaultMayBeEmpty = false; - _unlimitedAmount = false; - } -} -``` - -Specifically, set the state variables as follows: -- `_vault_`: the address of your ERC4626 vault. -- `_underlying_`: the address of the underlying asset of your vault. Note that the default `setupVault()` and `setupYield()` methods of `ERC4626Test` assume that it implements `mint(address to, uint value)` and `burn(address from, uint value)`. You can override the setup methods with your own if such `mint()` and `burn()` are not implemented. -- `_delta_`: the maximum approximation error size to be passed to [`assertApproxEqAbs()`]. It must be given as an absolute value (not a percentage) in the smallest unit (e.g., Wei or Satoshi). Note that all the tests are expected to pass with `__delta__ == 0` as long as your vault follows the [preferred rounding direction] as specified in the standard. If your vault doesn't follow the preferred rounding direction, you can set `__delta__` to a reasonable size of rounding errors where the adversarial profit of exploiting such rounding errors stays sufficiently small compared to the gas cost. (You can read our [post] for more about the adversarial profit.) -- `_vaultMayBeEmpty`: when set to false, fuzz inputs that empties the vault are ignored. -- `_unlimitedAmount`: when set to false, fuzz inputs are restricted to the currently available amount from the caller. Limiting the amount can speed up fuzzing, but may miss some edge cases. - -[`assertApproxEqAbs()`]: - -[preferred rounding direction]: - -**Step 3**: Run `forge test` - -``` -$ forge test -``` - -## Examples - -Below are examples of adding these property tests to existing ERC4626 vaults: -- [OpenZeppelin ERC4626] [[diff](https://github.com/daejunpark/openzeppelin-contracts/pull/1/files)] -- [Solmate ERC4626] [[diff](https://github.com/daejunpark/solmate/pull/1/files)] -- [Revenue Distribution Token] [[diff](https://github.com/daejunpark/revenue-distribution-token/pull/1/files)] -- [Yield Daddy ERC4626 wrappers] [[diff](https://github.com/daejunpark/yield-daddy/pull/1/files)][^bug] - -[OpenZeppelin ERC4626]: -[Solmate ERC4626]: -[Revenue Distribution Token]: -[Yield Daddy ERC4626 wrappers]: - -[^bug]: Our property tests indeed revealed an [issue](https://github.com/timeless-fi/yield-daddy/issues/7) in their eToken testing mock contract. The tests passed after it is [fixed](https://github.com/daejunpark/yield-daddy/commit/721cf4bd766805fd409455434aa5fd1a9b2df25c). - -## Disclaimer - -_These smart contracts are being provided as is. No guarantee, representation or warranty is being made, express or implied, as to the safety or correctness of the user interface or the smart contracts. They have not been audited and as such there can be no assurance they will work as intended, and users may experience delays, failures, errors, omissions or loss of transmitted information. THE SMART CONTRACTS CONTAINED HEREIN ARE FURNISHED AS IS, WHERE IS, WITH ALL FAULTS AND WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING ANY WARRANTY OF MERCHANTABILITY, NON-INFRINGEMENT OR FITNESS FOR ANY PARTICULAR PURPOSE. Further, use of any of these smart contracts may be restricted or prohibited under applicable law, including securities laws, and it is therefore strongly advised for you to contact a reputable attorney in any jurisdiction where these smart contracts may be accessible for any questions or concerns with respect thereto. Further, no information provided in this repo should be construed as investment advice or legal advice for any particular facts or circumstances, and is not meant to replace competent counsel. a16z is not liable for any use of the foregoing, and users should proceed with caution and use at their own risk. See a16z.com/disclosures for more info._ diff --git a/lib/openzeppelin-contracts/lib/forge-std/.gitattributes b/lib/openzeppelin-contracts/lib/forge-std/.gitattributes deleted file mode 100644 index 27042d4..0000000 --- a/lib/openzeppelin-contracts/lib/forge-std/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -src/Vm.sol linguist-generated diff --git a/lib/openzeppelin-contracts/lib/forge-std/.github/workflows/ci.yml b/lib/openzeppelin-contracts/lib/forge-std/.github/workflows/ci.yml deleted file mode 100644 index cb241ae..0000000 --- a/lib/openzeppelin-contracts/lib/forge-std/.github/workflows/ci.yml +++ /dev/null @@ -1,134 +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: - # - the oldest and newest version of each supported minor version - # - versions with specific issues - - name: Check compatibility with latest - if: always() - run: | - output=$(forge build --skip test) - - if echo "$output" | grep -q "Warning"; then - echo "$output" - exit 1 - fi - - - name: Check compatibility with 0.8.0 - if: always() - run: | - output=$(forge build --skip test --use solc:0.8.0) - - if echo "$output" | grep -q "Warning"; then - echo "$output" - exit 1 - fi - - - name: Check compatibility with 0.7.6 - if: always() - run: | - output=$(forge build --skip test --use solc:0.7.6) - - if echo "$output" | grep -q "Warning"; then - echo "$output" - exit 1 - fi - - - name: Check compatibility with 0.7.0 - if: always() - run: | - output=$(forge build --skip test --use solc:0.7.0) - - if echo "$output" | grep -q "Warning"; then - echo "$output" - exit 1 - fi - - - name: Check compatibility with 0.6.12 - if: always() - run: | - output=$(forge build --skip test --use solc:0.6.12) - - if echo "$output" | grep -q "Warning"; then - echo "$output" - exit 1 - fi - - - name: Check compatibility with 0.6.2 - if: always() - run: | - output=$(forge build --skip test --use solc:0.6.2) - - if echo "$output" | grep -q "Warning"; then - echo "$output" - exit 1 - fi - - # 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/openzeppelin-contracts/lib/forge-std/.github/workflows/sync.yml b/lib/openzeppelin-contracts/lib/forge-std/.github/workflows/sync.yml deleted file mode 100644 index 5a9e9d5..0000000 --- a/lib/openzeppelin-contracts/lib/forge-std/.github/workflows/sync.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: Sync Release Branch - -on: - release: - types: - - created - -jobs: - sync-release-branch: - runs-on: ubuntu-latest - if: startsWith(github.event.release.tag_name, 'v1') - steps: - - name: Check out the repo - uses: actions/checkout@v3 - with: - fetch-depth: 0 - ref: v1 - - - name: Configure Git - run: | - git config user.name github-actions[bot] - git config user.email 41898282+github-actions[bot]@users.noreply.github.com - - - name: Sync Release Branch - run: | - git fetch --tags - git checkout v1 - git reset --hard ${GITHUB_REF} - git push --force diff --git a/lib/openzeppelin-contracts/lib/forge-std/.gitignore b/lib/openzeppelin-contracts/lib/forge-std/.gitignore deleted file mode 100644 index 756106d..0000000 --- a/lib/openzeppelin-contracts/lib/forge-std/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -cache/ -out/ -.vscode -.idea diff --git a/lib/openzeppelin-contracts/lib/forge-std/.gitmodules b/lib/openzeppelin-contracts/lib/forge-std/.gitmodules deleted file mode 100644 index e124719..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/LICENSE-APACHE b/lib/openzeppelin-contracts/lib/forge-std/LICENSE-APACHE deleted file mode 100644 index cf01a49..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/LICENSE-MIT b/lib/openzeppelin-contracts/lib/forge-std/LICENSE-MIT deleted file mode 100644 index 28f9830..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/README.md b/lib/openzeppelin-contracts/lib/forge-std/README.md deleted file mode 100644 index 8494a7d..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/foundry.toml b/lib/openzeppelin-contracts/lib/forge-std/foundry.toml deleted file mode 100644 index f9679ee..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/lib/ds-test/.github/workflows/build.yml b/lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/.github/workflows/build.yml deleted file mode 100644 index d2ff97d..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/lib/ds-test/.gitignore b/lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/.gitignore deleted file mode 100644 index 462a994..0000000 --- a/lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/.dapple -/build -/out -/cache/ diff --git a/lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/LICENSE b/lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/LICENSE deleted file mode 100644 index 94a9ed0..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/lib/ds-test/Makefile b/lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/Makefile deleted file mode 100644 index 661dac4..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/lib/ds-test/default.nix b/lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/default.nix deleted file mode 100644 index cf65419..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/lib/ds-test/demo/demo.sol b/lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/demo/demo.sol deleted file mode 100644 index f3bb48e..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/lib/ds-test/package.json b/lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/package.json deleted file mode 100644 index 4802ada..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/test.sol b/lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/test.sol deleted file mode 100644 index 2bf3375..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/test.t.sol b/lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/test.t.sol deleted file mode 100644 index d277a30..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/package.json b/lib/openzeppelin-contracts/lib/forge-std/package.json deleted file mode 100644 index acc004b..0000000 --- a/lib/openzeppelin-contracts/lib/forge-std/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "forge-std", - "version": "1.7.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/openzeppelin-contracts/lib/forge-std/scripts/vm.py b/lib/openzeppelin-contracts/lib/forge-std/scripts/vm.py deleted file mode 100755 index 3cb8452..0000000 --- a/lib/openzeppelin-contracts/lib/forge-std/scripts/vm.py +++ /dev/null @@ -1,635 +0,0 @@ -#!/usr/bin/env python3 - -import copy -import json -import re -import subprocess -from enum import Enum as PyEnum -from typing import Callable -from urllib import request - -VoidFn = Callable[[], None] - -CHEATCODES_JSON_URL = "https://raw.githubusercontent.com/foundry-rs/foundry/master/crates/cheatcodes/assets/cheatcodes.json" -OUT_PATH = "src/Vm.sol" - -VM_SAFE_DOC = """\ -/// The `VmSafe` interface does not allow manipulation of the EVM state or other actions that may -/// result in Script simulations differing from on-chain execution. It is recommended to only use -/// these cheats in scripts. -""" - -VM_DOC = """\ -/// The `Vm` interface does allow manipulation of the EVM state. These are all intended to be used -/// in tests, but it is not recommended to use these cheats in scripts. -""" - - -def main(): - json_str = request.urlopen(CHEATCODES_JSON_URL).read().decode("utf-8") - contract = Cheatcodes.from_json(json_str) - - ccs = contract.cheatcodes - ccs = list(filter(lambda cc: cc.status != "experimental", ccs)) - ccs.sort(key=lambda cc: cc.func.id) - - safe = list(filter(lambda cc: cc.safety == "safe", ccs)) - safe.sort(key=CmpCheatcode) - unsafe = list(filter(lambda cc: cc.safety == "unsafe", ccs)) - unsafe.sort(key=CmpCheatcode) - assert len(safe) + len(unsafe) == len(ccs) - - prefix_with_group_headers(safe) - prefix_with_group_headers(unsafe) - - out = "" - - out += "// Automatically @generated by scripts/vm.py. Do not modify manually.\n\n" - - pp = CheatcodesPrinter( - spdx_identifier="MIT OR Apache-2.0", - solidity_requirement=">=0.6.2 <0.9.0", - abicoder_pragma=True, - ) - pp.p_prelude() - pp.prelude = False - out += pp.finish() - - out += "\n\n" - out += VM_SAFE_DOC - vm_safe = Cheatcodes( - # TODO: Custom errors were introduced in 0.8.4 - errors=[], # contract.errors - events=contract.events, - enums=contract.enums, - structs=contract.structs, - cheatcodes=safe, - ) - pp.p_contract(vm_safe, "VmSafe") - out += pp.finish() - - out += "\n\n" - out += VM_DOC - vm_unsafe = Cheatcodes( - errors=[], - events=[], - enums=[], - structs=[], - cheatcodes=unsafe, - ) - pp.p_contract(vm_unsafe, "Vm", "VmSafe") - out += pp.finish() - - # Compatibility with <0.8.0 - def memory_to_calldata(m: re.Match) -> str: - return " calldata " + m.group(1) - - out = re.sub(r" memory (.*returns)", memory_to_calldata, out) - - with open(OUT_PATH, "w") as f: - f.write(out) - - forge_fmt = ["forge", "fmt", OUT_PATH] - res = subprocess.run(forge_fmt) - assert res.returncode == 0, f"command failed: {forge_fmt}" - - print(f"Wrote to {OUT_PATH}") - - -class CmpCheatcode: - cheatcode: "Cheatcode" - - def __init__(self, cheatcode: "Cheatcode"): - self.cheatcode = cheatcode - - def __lt__(self, other: "CmpCheatcode") -> bool: - return cmp_cheatcode(self.cheatcode, other.cheatcode) < 0 - - def __eq__(self, other: "CmpCheatcode") -> bool: - return cmp_cheatcode(self.cheatcode, other.cheatcode) == 0 - - def __gt__(self, other: "CmpCheatcode") -> bool: - return cmp_cheatcode(self.cheatcode, other.cheatcode) > 0 - - -def cmp_cheatcode(a: "Cheatcode", b: "Cheatcode") -> int: - if a.group != b.group: - return -1 if a.group < b.group else 1 - if a.status != b.status: - return -1 if a.status < b.status else 1 - if a.safety != b.safety: - return -1 if a.safety < b.safety else 1 - if a.func.id != b.func.id: - return -1 if a.func.id < b.func.id else 1 - return 0 - - -# HACK: A way to add group header comments without having to modify printer code -def prefix_with_group_headers(cheats: list["Cheatcode"]): - s = set() - for i, cheat in enumerate(cheats): - if cheat.group in s: - continue - - s.add(cheat.group) - - c = copy.deepcopy(cheat) - c.func.description = "" - c.func.declaration = f"// ======== {group(c.group)} ========" - cheats.insert(i, c) - return cheats - - -def group(s: str) -> str: - if s == "evm": - return "EVM" - if s == "json": - return "JSON" - return s[0].upper() + s[1:] - - -class Visibility(PyEnum): - EXTERNAL: str = "external" - PUBLIC: str = "public" - INTERNAL: str = "internal" - PRIVATE: str = "private" - - def __str__(self): - return self.value - - -class Mutability(PyEnum): - PURE: str = "pure" - VIEW: str = "view" - NONE: str = "" - - def __str__(self): - return self.value - - -class Function: - id: str - description: str - declaration: str - visibility: Visibility - mutability: Mutability - signature: str - selector: str - selector_bytes: bytes - - def __init__( - self, - id: str, - description: str, - declaration: str, - visibility: Visibility, - mutability: Mutability, - signature: str, - selector: str, - selector_bytes: bytes, - ): - self.id = id - self.description = description - self.declaration = declaration - self.visibility = visibility - self.mutability = mutability - self.signature = signature - self.selector = selector - self.selector_bytes = selector_bytes - - @staticmethod - def from_dict(d: dict) -> "Function": - return Function( - d["id"], - d["description"], - d["declaration"], - Visibility(d["visibility"]), - Mutability(d["mutability"]), - d["signature"], - d["selector"], - bytes(d["selectorBytes"]), - ) - - -class Cheatcode: - func: Function - group: str - status: str - safety: str - - def __init__(self, func: Function, group: str, status: str, safety: str): - self.func = func - self.group = group - self.status = status - self.safety = safety - - @staticmethod - def from_dict(d: dict) -> "Cheatcode": - return Cheatcode( - Function.from_dict(d["func"]), - str(d["group"]), - str(d["status"]), - str(d["safety"]), - ) - - -class Error: - name: str - description: str - declaration: str - - def __init__(self, name: str, description: str, declaration: str): - self.name = name - self.description = description - self.declaration = declaration - - @staticmethod - def from_dict(d: dict) -> "Error": - return Error(**d) - - -class Event: - name: str - description: str - declaration: str - - def __init__(self, name: str, description: str, declaration: str): - self.name = name - self.description = description - self.declaration = declaration - - @staticmethod - def from_dict(d: dict) -> "Event": - return Event(**d) - - -class EnumVariant: - name: str - description: str - - def __init__(self, name: str, description: str): - self.name = name - self.description = description - - -class Enum: - name: str - description: str - variants: list[EnumVariant] - - def __init__(self, name: str, description: str, variants: list[EnumVariant]): - self.name = name - self.description = description - self.variants = variants - - @staticmethod - def from_dict(d: dict) -> "Enum": - return Enum( - d["name"], - d["description"], - list(map(lambda v: EnumVariant(**v), d["variants"])), - ) - - -class StructField: - name: str - ty: str - description: str - - def __init__(self, name: str, ty: str, description: str): - self.name = name - self.ty = ty - self.description = description - - -class Struct: - name: str - description: str - fields: list[StructField] - - def __init__(self, name: str, description: str, fields: list[StructField]): - self.name = name - self.description = description - self.fields = fields - - @staticmethod - def from_dict(d: dict) -> "Struct": - return Struct( - d["name"], - d["description"], - list(map(lambda f: StructField(**f), d["fields"])), - ) - - -class Cheatcodes: - errors: list[Error] - events: list[Event] - enums: list[Enum] - structs: list[Struct] - cheatcodes: list[Cheatcode] - - def __init__( - self, - errors: list[Error], - events: list[Event], - enums: list[Enum], - structs: list[Struct], - cheatcodes: list[Cheatcode], - ): - self.errors = errors - self.events = events - self.enums = enums - self.structs = structs - self.cheatcodes = cheatcodes - - @staticmethod - def from_dict(d: dict) -> "Cheatcodes": - return Cheatcodes( - errors=[Error.from_dict(e) for e in d["errors"]], - events=[Event.from_dict(e) for e in d["events"]], - enums=[Enum.from_dict(e) for e in d["enums"]], - structs=[Struct.from_dict(e) for e in d["structs"]], - cheatcodes=[Cheatcode.from_dict(e) for e in d["cheatcodes"]], - ) - - @staticmethod - def from_json(s) -> "Cheatcodes": - return Cheatcodes.from_dict(json.loads(s)) - - @staticmethod - def from_json_file(file_path: str) -> "Cheatcodes": - with open(file_path, "r") as f: - return Cheatcodes.from_dict(json.load(f)) - - -class Item(PyEnum): - ERROR: str = "error" - EVENT: str = "event" - ENUM: str = "enum" - STRUCT: str = "struct" - FUNCTION: str = "function" - - -class ItemOrder: - _list: list[Item] - - def __init__(self, list: list[Item]) -> None: - assert len(list) <= len(Item), "list must not contain more items than Item" - assert len(list) == len(set(list)), "list must not contain duplicates" - self._list = list - pass - - def get_list(self) -> list[Item]: - return self._list - - @staticmethod - def default() -> "ItemOrder": - return ItemOrder( - [ - Item.ERROR, - Item.EVENT, - Item.ENUM, - Item.STRUCT, - Item.FUNCTION, - ] - ) - - -class CheatcodesPrinter: - buffer: str - - prelude: bool - spdx_identifier: str - solidity_requirement: str - abicoder_v2: bool - - block_doc_style: bool - - indent_level: int - _indent_str: str - - nl_str: str - - items_order: ItemOrder - - def __init__( - self, - buffer: str = "", - prelude: bool = True, - spdx_identifier: str = "UNLICENSED", - solidity_requirement: str = "", - abicoder_pragma: bool = False, - block_doc_style: bool = False, - indent_level: int = 0, - indent_with: int | str = 4, - nl_str: str = "\n", - items_order: ItemOrder = ItemOrder.default(), - ): - self.prelude = prelude - self.spdx_identifier = spdx_identifier - self.solidity_requirement = solidity_requirement - self.abicoder_v2 = abicoder_pragma - self.block_doc_style = block_doc_style - self.buffer = buffer - self.indent_level = indent_level - self.nl_str = nl_str - - if isinstance(indent_with, int): - assert indent_with >= 0 - self._indent_str = " " * indent_with - elif isinstance(indent_with, str): - self._indent_str = indent_with - else: - assert False, "indent_with must be int or str" - - self.items_order = items_order - - def finish(self) -> str: - ret = self.buffer.rstrip() - self.buffer = "" - return ret - - def p_contract(self, contract: Cheatcodes, name: str, inherits: str = ""): - if self.prelude: - self.p_prelude(contract) - - self._p_str("interface ") - name = name.strip() - if name != "": - self._p_str(name) - self._p_str(" ") - if inherits != "": - self._p_str("is ") - self._p_str(inherits) - self._p_str(" ") - self._p_str("{") - self._p_nl() - self._with_indent(lambda: self._p_items(contract)) - self._p_str("}") - self._p_nl() - - def _p_items(self, contract: Cheatcodes): - for item in self.items_order.get_list(): - if item == Item.ERROR: - self.p_errors(contract.errors) - elif item == Item.EVENT: - self.p_events(contract.events) - elif item == Item.ENUM: - self.p_enums(contract.enums) - elif item == Item.STRUCT: - self.p_structs(contract.structs) - elif item == Item.FUNCTION: - self.p_functions(contract.cheatcodes) - else: - assert False, f"unknown item {item}" - - def p_prelude(self, contract: Cheatcodes | None = None): - self._p_str(f"// SPDX-License-Identifier: {self.spdx_identifier}") - self._p_nl() - - if self.solidity_requirement != "": - req = self.solidity_requirement - elif contract and len(contract.errors) > 0: - req = ">=0.8.4 <0.9.0" - else: - req = ">=0.6.0 <0.9.0" - self._p_str(f"pragma solidity {req};") - self._p_nl() - - if self.abicoder_v2: - self._p_str("pragma experimental ABIEncoderV2;") - self._p_nl() - - self._p_nl() - - def p_errors(self, errors: list[Error]): - for error in errors: - self._p_line(lambda: self.p_error(error)) - - def p_error(self, error: Error): - self._p_comment(error.description, doc=True) - self._p_line(lambda: self._p_str(error.declaration)) - - def p_events(self, events: list[Event]): - for event in events: - self._p_line(lambda: self.p_event(event)) - - def p_event(self, event: Event): - self._p_comment(event.description, doc=True) - self._p_line(lambda: self._p_str(event.declaration)) - - def p_enums(self, enums: list[Enum]): - for enum in enums: - self._p_line(lambda: self.p_enum(enum)) - - def p_enum(self, enum: Enum): - self._p_comment(enum.description, doc=True) - self._p_line(lambda: self._p_str(f"enum {enum.name} {{")) - self._with_indent(lambda: self.p_enum_variants(enum.variants)) - self._p_line(lambda: self._p_str("}")) - - def p_enum_variants(self, variants: list[EnumVariant]): - for i, variant in enumerate(variants): - self._p_indent() - self._p_comment(variant.description) - - self._p_indent() - self._p_str(variant.name) - if i < len(variants) - 1: - self._p_str(",") - self._p_nl() - - def p_structs(self, structs: list[Struct]): - for struct in structs: - self._p_line(lambda: self.p_struct(struct)) - - def p_struct(self, struct: Struct): - self._p_comment(struct.description, doc=True) - self._p_line(lambda: self._p_str(f"struct {struct.name} {{")) - self._with_indent(lambda: self.p_struct_fields(struct.fields)) - self._p_line(lambda: self._p_str("}")) - - def p_struct_fields(self, fields: list[StructField]): - for field in fields: - self._p_line(lambda: self.p_struct_field(field)) - - def p_struct_field(self, field: StructField): - self._p_comment(field.description) - self._p_indented(lambda: self._p_str(f"{field.ty} {field.name};")) - - def p_functions(self, cheatcodes: list[Cheatcode]): - for cheatcode in cheatcodes: - self._p_line(lambda: self.p_function(cheatcode.func)) - - def p_function(self, func: Function): - self._p_comment(func.description, doc=True) - self._p_line(lambda: self._p_str(func.declaration)) - - def _p_comment(self, s: str, doc: bool = False): - s = s.strip() - if s == "": - return - - s = map(lambda line: line.lstrip(), s.split("\n")) - if self.block_doc_style: - self._p_str("/*") - if doc: - self._p_str("*") - self._p_nl() - for line in s: - self._p_indent() - self._p_str(" ") - if doc: - self._p_str("* ") - self._p_str(line) - self._p_nl() - self._p_indent() - self._p_str(" */") - self._p_nl() - else: - first_line = True - for line in s: - if not first_line: - self._p_indent() - first_line = False - - if doc: - self._p_str("/// ") - else: - self._p_str("// ") - self._p_str(line) - self._p_nl() - - def _with_indent(self, f: VoidFn): - self._inc_indent() - f() - self._dec_indent() - - def _p_line(self, f: VoidFn): - self._p_indent() - f() - self._p_nl() - - def _p_indented(self, f: VoidFn): - self._p_indent() - f() - - def _p_indent(self): - for _ in range(self.indent_level): - self._p_str(self._indent_str) - - def _p_nl(self): - self._p_str(self.nl_str) - - def _p_str(self, txt: str): - self.buffer += txt - - def _inc_indent(self): - self.indent_level += 1 - - def _dec_indent(self): - self.indent_level -= 1 - - -if __name__ == "__main__": - main() diff --git a/lib/openzeppelin-contracts/lib/forge-std/src/Base.sol b/lib/openzeppelin-contracts/lib/forge-std/src/Base.sol deleted file mode 100644 index 851ac0c..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/src/Script.sol b/lib/openzeppelin-contracts/lib/forge-std/src/Script.sol deleted file mode 100644 index 94e75f6..0000000 --- a/lib/openzeppelin-contracts/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 ScriptBase, StdChains, StdCheatsSafe, StdUtils { - // Note: IS_SCRIPT() must return true. - bool public IS_SCRIPT = true; -} diff --git a/lib/openzeppelin-contracts/lib/forge-std/src/StdAssertions.sol b/lib/openzeppelin-contracts/lib/forge-std/src/StdAssertions.sol deleted file mode 100644 index 2778b3a..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/src/StdChains.sol b/lib/openzeppelin-contracts/lib/forge-std/src/StdChains.sol deleted file mode 100644 index bdc1c56..0000000 --- a/lib/openzeppelin-contracts/lib/forge-std/src/StdChains.sol +++ /dev/null @@ -1,248 +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 - view - 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' - // The upstream error thrown by forge for failing cheats changed so we check both the old and new versions - bytes memory oldNotFoundError = - abi.encodeWithSignature("CheatCodeError", string(abi.encodePacked("invalid rpc url ", chainAlias))); - bytes memory newNotFoundError = abi.encodeWithSignature( - "CheatcodeError(string)", string(abi.encodePacked("invalid rpc url: ", chainAlias)) - ); - bytes32 errHash = keccak256(err); - if ( - (errHash != keccak256(oldNotFoundError) && errHash != keccak256(newNotFoundError)) - || 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")); - setChainWithDefaultRpcUrl("moonbeam", ChainData("Moonbeam", 1284, "https://rpc.api.moonbeam.network")); - setChainWithDefaultRpcUrl( - "moonriver", ChainData("Moonriver", 1285, "https://rpc.api.moonriver.moonbeam.network") - ); - setChainWithDefaultRpcUrl("moonbase", ChainData("Moonbase", 1287, "https://rpc.testnet.moonbeam.network")); - setChainWithDefaultRpcUrl("base_goerli", ChainData("Base Goerli", 84531, "https://goerli.base.org")); - setChainWithDefaultRpcUrl("base", ChainData("Base", 8453, "https://mainnet.base.org")); - } - - // 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/openzeppelin-contracts/lib/forge-std/src/StdCheats.sol b/lib/openzeppelin-contracts/lib/forge-std/src/StdCheats.sol deleted file mode 100644 index f293313..0000000 --- a/lib/openzeppelin-contracts/lib/forge-std/src/StdCheats.sol +++ /dev/null @@ -1,817 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import {StdStorage, stdStorage} from "./StdStorage.sol"; -import {console2} from "./console2.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, console, and Create2Deployer addresses - vm.assume( - addr != address(vm) && addr != 0x000000000000000000636F6e736F6c652e6c6f67 - && addr != 0x4e59b44847b379578588920cA78FbF26c0B4956C - ); - } - - 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"))))); - address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67; - - // 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 { - console2_log_StdCheats("changePrank is deprecated. Please use vm.startPrank instead."); - 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); - } - - // Used to prevent the compilation of console, which shortens the compilation time when console is not used elsewhere. - function console2_log_StdCheats(string memory p0) private view { - (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature("log(string)", p0)); - status; - } -} diff --git a/lib/openzeppelin-contracts/lib/forge-std/src/StdError.sol b/lib/openzeppelin-contracts/lib/forge-std/src/StdError.sol deleted file mode 100644 index a302191..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/src/StdInvariant.sol b/lib/openzeppelin-contracts/lib/forge-std/src/StdInvariant.sol deleted file mode 100644 index bcd9ac0..0000000 --- a/lib/openzeppelin-contracts/lib/forge-std/src/StdInvariant.sol +++ /dev/null @@ -1,107 +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; - } - - struct FuzzInterface { - address addr; - string[] artifacts; - } - - address[] private _excludedContracts; - address[] private _excludedSenders; - address[] private _targetedContracts; - address[] private _targetedSenders; - - string[] private _excludedArtifacts; - string[] private _targetedArtifacts; - - FuzzSelector[] private _targetedArtifactSelectors; - FuzzSelector[] private _targetedSelectors; - - FuzzInterface[] private _targetedInterfaces; - - // 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_); - } - - function targetInterface(FuzzInterface memory newTargetedInterface_) internal { - _targetedInterfaces.push(newTargetedInterface_); - } - - // 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; - } - - function targetInterfaces() public view returns (FuzzInterface[] memory targetedInterfaces_) { - targetedInterfaces_ = _targetedInterfaces; - } -} diff --git a/lib/openzeppelin-contracts/lib/forge-std/src/StdJson.sol b/lib/openzeppelin-contracts/lib/forge-std/src/StdJson.sol deleted file mode 100644 index 42d9bb7..0000000 --- a/lib/openzeppelin-contracts/lib/forge-std/src/StdJson.sol +++ /dev/null @@ -1,183 +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 pure returns (uint256) { - return vm.parseJsonUint(json, key); - } - - function readUintArray(string memory json, string memory key) internal pure returns (uint256[] memory) { - return vm.parseJsonUintArray(json, key); - } - - function readInt(string memory json, string memory key) internal pure returns (int256) { - return vm.parseJsonInt(json, key); - } - - function readIntArray(string memory json, string memory key) internal pure returns (int256[] memory) { - return vm.parseJsonIntArray(json, key); - } - - function readBytes32(string memory json, string memory key) internal pure returns (bytes32) { - return vm.parseJsonBytes32(json, key); - } - - function readBytes32Array(string memory json, string memory key) internal pure returns (bytes32[] memory) { - return vm.parseJsonBytes32Array(json, key); - } - - function readString(string memory json, string memory key) internal pure returns (string memory) { - return vm.parseJsonString(json, key); - } - - function readStringArray(string memory json, string memory key) internal pure returns (string[] memory) { - return vm.parseJsonStringArray(json, key); - } - - function readAddress(string memory json, string memory key) internal pure returns (address) { - return vm.parseJsonAddress(json, key); - } - - function readAddressArray(string memory json, string memory key) internal pure returns (address[] memory) { - return vm.parseJsonAddressArray(json, key); - } - - function readBool(string memory json, string memory key) internal pure returns (bool) { - return vm.parseJsonBool(json, key); - } - - function readBoolArray(string memory json, string memory key) internal pure returns (bool[] memory) { - return vm.parseJsonBoolArray(json, key); - } - - function readBytes(string memory json, string memory key) internal pure returns (bytes memory) { - return vm.parseJsonBytes(json, key); - } - - function readBytesArray(string memory json, string memory key) internal pure returns (bytes[] memory) { - return vm.parseJsonBytesArray(json, key); - } - - function serialize(string memory jsonKey, string memory rootObject) internal returns (string memory) { - return vm.serializeJson(jsonKey, rootObject); - } - - 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/openzeppelin-contracts/lib/forge-std/src/StdMath.sol b/lib/openzeppelin-contracts/lib/forge-std/src/StdMath.sol deleted file mode 100644 index 459523b..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/src/StdStorage.sol b/lib/openzeppelin-contracts/lib/forge-std/src/StdStorage.sol deleted file mode 100644 index e5ded70..0000000 --- a/lib/openzeppelin-contracts/lib/forge-std/src/StdStorage.sol +++ /dev/null @@ -1,378 +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])); - } - if (prev != fdat) { - continue; - } - bytes32 new_val = ~prev; - // store - vm.store(who, reads[i], new_val); - bool success; - { - bytes memory rdat; - (success, rdat) = who.staticcall(cald); - fdat = bytesToBytes32(rdat, 32 * field_depth); - } - - if (success && fdat == new_val) { - // 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 parent(StdStorage storage self) internal returns (uint256, bytes32) { - address who = self._target; - uint256 field_depth = self._depth; - vm.startMappingRecording(); - uint256 child = find(self) - field_depth; - (bool found, bytes32 key, bytes32 parent_slot) = vm.getMappingKeyAndParentOf(who, bytes32(child)); - if (!found) { - revert( - "stdStorage read_bool(StdStorage): Cannot find parent. Make sure you give a slot and startMappingRecording() has been called." - ); - } - return (uint256(parent_slot), key); - } - - function root(StdStorage storage self) internal returns (uint256) { - address who = self._target; - uint256 field_depth = self._depth; - vm.startMappingRecording(); - uint256 child = find(self) - field_depth; - bool found; - bytes32 root_slot; - bytes32 parent_slot; - (found,, parent_slot) = vm.getMappingKeyAndParentOf(who, bytes32(child)); - if (!found) { - revert( - "stdStorage read_bool(StdStorage): Cannot find parent. Make sure you give a slot and startMappingRecording() has been called." - ); - } - while (found) { - root_slot = parent_slot; - (found,, parent_slot) = vm.getMappingKeyAndParentOf(who, bytes32(root_slot)); - } - return uint256(root_slot); - } - - 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); - } - - function parent(StdStorage storage self) internal returns (uint256, bytes32) { - return stdStorageSafe.parent(self); - } - - function root(StdStorage storage self) internal returns (uint256) { - return stdStorageSafe.root(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/openzeppelin-contracts/lib/forge-std/src/StdStyle.sol b/lib/openzeppelin-contracts/lib/forge-std/src/StdStyle.sol deleted file mode 100644 index d371e0c..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/src/StdUtils.sol b/lib/openzeppelin-contracts/lib/forge-std/src/StdUtils.sol deleted file mode 100644 index 0f61305..0000000 --- a/lib/openzeppelin-contracts/lib/forge-std/src/StdUtils.sol +++ /dev/null @@ -1,226 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import {IMulticall3} from "./interfaces/IMulticall3.sol"; -import {MockERC20} from "./mocks/MockERC20.sol"; -import {MockERC721} from "./mocks/MockERC721.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 pure virtual returns (uint256 result) { - result = _bound(x, min, max); - console2_log_StdUtils("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 pure virtual returns (int256 result) { - result = _bound(x, min, max); - console2_log_StdUtils("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) { - console2_log_StdUtils("computeCreateAddress is deprecated. Please use vm.computeCreateAddress instead."); - return vm.computeCreateAddress(deployer, nonce); - } - - function computeCreate2Address(bytes32 salt, bytes32 initcodeHash, address deployer) - internal - pure - virtual - returns (address) - { - console2_log_StdUtils("computeCreate2Address is deprecated. Please use vm.computeCreate2Address instead."); - return vm.computeCreate2Address(salt, initcodeHash, deployer); - } - - /// @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) { - console2_log_StdUtils("computeCreate2Address is deprecated. Please use vm.computeCreate2Address instead."); - return vm.computeCreate2Address(salt, initCodeHash); - } - - /// @dev returns an initialized mock ERC20 contract - function deployMockERC20(string memory name, string memory symbol, uint8 decimals) - internal - returns (MockERC20 mock) - { - mock = new MockERC20(); - mock.initialize(name, symbol, decimals); - } - - /// @dev returns an initialized mock ERC721 contract - function deployMockERC721(string memory name, string memory symbol) internal returns (MockERC721 mock) { - mock = new MockERC721(); - mock.initialize(name, symbol); - } - - /// @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))); - } - - // This section is used to prevent the compilation of console, which shortens the compilation time when console is - // not used elsewhere. We also trick the compiler into letting us make the console log methods as `pure` to avoid - // any breaking changes to function signatures. - 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 = CONSOLE2_ADDRESS; - /// @solidity memory-safe-assembly - assembly { - let payloadStart := add(payload, 32) - let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) - } - } - - function console2_log_StdUtils(string memory p0) private pure { - _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); - } - - function console2_log_StdUtils(string memory p0, uint256 p1) private pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1)); - } - - function console2_log_StdUtils(string memory p0, string memory p1) private pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); - } -} diff --git a/lib/openzeppelin-contracts/lib/forge-std/src/Test.sol b/lib/openzeppelin-contracts/lib/forge-std/src/Test.sol deleted file mode 100644 index 743c183..0000000 --- a/lib/openzeppelin-contracts/lib/forge-std/src/Test.sol +++ /dev/null @@ -1,33 +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 -abstract contract Test is TestBase, DSTest, StdAssertions, StdChains, StdCheats, StdInvariant, StdUtils { -// 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/openzeppelin-contracts/lib/forge-std/src/Vm.sol b/lib/openzeppelin-contracts/lib/forge-std/src/Vm.sol deleted file mode 100644 index cbb3e4a..0000000 --- a/lib/openzeppelin-contracts/lib/forge-std/src/Vm.sol +++ /dev/null @@ -1,1114 +0,0 @@ -// Automatically @generated by scripts/vm.py. Do not modify manually. - -// SPDX-License-Identifier: MIT OR Apache-2.0 -pragma solidity >=0.6.2 <0.9.0; -pragma experimental ABIEncoderV2; - -/// The `VmSafe` interface does not allow manipulation of the EVM state or other actions that may -/// result in Script simulations differing from on-chain execution. It is recommended to only use -/// these cheats in scripts. -interface VmSafe { - /// A modification applied to either `msg.sender` or `tx.origin`. Returned by `readCallers`. - enum CallerMode { - // No caller modification is currently active. - None, - // A one time broadcast triggered by a `vm.broadcast()` call is currently active. - Broadcast, - // A recurrent broadcast triggered by a `vm.startBroadcast()` call is currently active. - RecurrentBroadcast, - // A one time prank triggered by a `vm.prank()` call is currently active. - Prank, - // A recurrent prank triggered by a `vm.startPrank()` call is currently active. - RecurrentPrank - } - - /// The kind of account access that occurred. - enum AccountAccessKind { - // The account was called. - Call, - // The account was called via delegatecall. - DelegateCall, - // The account was called via callcode. - CallCode, - // The account was called via staticcall. - StaticCall, - // The account was created. - Create, - // The account was selfdestructed. - SelfDestruct, - // Synthetic access indicating the current context has resumed after a previous sub-context (AccountAccess). - Resume, - // The account's balance was read. - Balance, - // The account's codesize was read. - Extcodesize, - // The account's codehash was read. - Extcodehash, - // The account's code was copied. - Extcodecopy - } - - /// An Ethereum log. Returned by `getRecordedLogs`. - struct Log { - // The topics of the log, including the signature, if any. - bytes32[] topics; - // The raw data of the log. - bytes data; - // The address of the log's emitter. - address emitter; - } - - /// An RPC URL and its alias. Returned by `rpcUrlStructs`. - struct Rpc { - // The alias of the RPC URL. - string key; - // The RPC URL. - string url; - } - - /// An RPC log object. Returned by `eth_getLogs`. - struct EthGetLogs { - // The address of the log's emitter. - address emitter; - // The topics of the log, including the signature, if any. - bytes32[] topics; - // The raw data of the log. - bytes data; - // The block hash. - bytes32 blockHash; - // The block number. - uint64 blockNumber; - // The transaction hash. - bytes32 transactionHash; - // The transaction index in the block. - uint64 transactionIndex; - // The log index. - uint256 logIndex; - // Whether the log was removed. - bool removed; - } - - /// A single entry in a directory listing. Returned by `readDir`. - struct DirEntry { - // The error message, if any. - string errorMessage; - // The path of the entry. - string path; - // The depth of the entry. - uint64 depth; - // Whether the entry is a directory. - bool isDir; - // Whether the entry is a symlink. - bool isSymlink; - } - - /// Metadata information about a file. - /// This structure is returned from the `fsMetadata` function and represents known - /// metadata about a file such as its permissions, size, modification - /// times, etc. - struct FsMetadata { - // True if this metadata is for a directory. - bool isDir; - // True if this metadata is for a symlink. - bool isSymlink; - // The size of the file, in bytes, this metadata is for. - uint256 length; - // True if this metadata is for a readonly (unwritable) file. - bool readOnly; - // The last modification time listed in this metadata. - uint256 modified; - // The last access time of this metadata. - uint256 accessed; - // The creation time listed in this metadata. - uint256 created; - } - - /// A wallet with a public and private key. - struct Wallet { - // The wallet's address. - address addr; - // The wallet's public key `X`. - uint256 publicKeyX; - // The wallet's public key `Y`. - uint256 publicKeyY; - // The wallet's private key. - uint256 privateKey; - } - - /// The result of a `tryFfi` call. - struct FfiResult { - // The exit code of the call. - int32 exitCode; - // The optionally hex-decoded `stdout` data. - bytes stdout; - // The `stderr` data. - bytes stderr; - } - - /// Information on the chain and fork. - struct ChainInfo { - // The fork identifier. Set to zero if no fork is active. - uint256 forkId; - // The chain ID of the current fork. - uint256 chainId; - } - - /// The result of a `stopAndReturnStateDiff` call. - struct AccountAccess { - // The chain and fork the access occurred. - ChainInfo chainInfo; - // The kind of account access that determines what the account is. - // If kind is Call, DelegateCall, StaticCall or CallCode, then the account is the callee. - // If kind is Create, then the account is the newly created account. - // If kind is SelfDestruct, then the account is the selfdestruct recipient. - // If kind is a Resume, then account represents a account context that has resumed. - AccountAccessKind kind; - // The account that was accessed. - // It's either the account created, callee or a selfdestruct recipient for CREATE, CALL or SELFDESTRUCT. - address account; - // What accessed the account. - address accessor; - // If the account was initialized or empty prior to the access. - // An account is considered initialized if it has code, a - // non-zero nonce, or a non-zero balance. - bool initialized; - // The previous balance of the accessed account. - uint256 oldBalance; - // The potential new balance of the accessed account. - // That is, all balance changes are recorded here, even if reverts occurred. - uint256 newBalance; - // Code of the account deployed by CREATE. - bytes deployedCode; - // Value passed along with the account access - uint256 value; - // Input data provided to the CREATE or CALL - bytes data; - // If this access reverted in either the current or parent context. - bool reverted; - // An ordered list of storage accesses made during an account access operation. - StorageAccess[] storageAccesses; - } - - /// The storage accessed during an `AccountAccess`. - struct StorageAccess { - // The account whose storage was accessed. - address account; - // The slot that was accessed. - bytes32 slot; - // If the access was a write. - bool isWrite; - // The previous value of the slot. - bytes32 previousValue; - // The new value of the slot. - bytes32 newValue; - // If the access was reverted. - bool reverted; - } - - // ======== Environment ======== - - /// Gets the environment variable `name` and parses it as `address`. - /// Reverts if the variable was not found or could not be parsed. - function envAddress(string calldata name) external view returns (address value); - - /// Gets the environment variable `name` and parses it as an array of `address`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envAddress(string calldata name, string calldata delim) external view returns (address[] memory value); - - /// Gets the environment variable `name` and parses it as `bool`. - /// Reverts if the variable was not found or could not be parsed. - function envBool(string calldata name) external view returns (bool value); - - /// Gets the environment variable `name` and parses it as an array of `bool`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envBool(string calldata name, string calldata delim) external view returns (bool[] memory value); - - /// Gets the environment variable `name` and parses it as `bytes32`. - /// Reverts if the variable was not found or could not be parsed. - function envBytes32(string calldata name) external view returns (bytes32 value); - - /// Gets the environment variable `name` and parses it as an array of `bytes32`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envBytes32(string calldata name, string calldata delim) external view returns (bytes32[] memory value); - - /// Gets the environment variable `name` and parses it as `bytes`. - /// Reverts if the variable was not found or could not be parsed. - function envBytes(string calldata name) external view returns (bytes memory value); - - /// Gets the environment variable `name` and parses it as an array of `bytes`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envBytes(string calldata name, string calldata delim) external view returns (bytes[] memory value); - - /// Gets the environment variable `name` and parses it as `int256`. - /// Reverts if the variable was not found or could not be parsed. - function envInt(string calldata name) external view returns (int256 value); - - /// Gets the environment variable `name` and parses it as an array of `int256`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envInt(string calldata name, string calldata delim) external view returns (int256[] memory value); - - /// Gets the environment variable `name` and parses it as `bool`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, bool defaultValue) external view returns (bool value); - - /// Gets the environment variable `name` and parses it as `uint256`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, uint256 defaultValue) external view returns (uint256 value); - - /// Gets the environment variable `name` and parses it as an array of `address`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, address[] calldata defaultValue) - external - view - returns (address[] memory value); - - /// Gets the environment variable `name` and parses it as an array of `bytes32`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, bytes32[] calldata defaultValue) - external - view - returns (bytes32[] memory value); - - /// Gets the environment variable `name` and parses it as an array of `string`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, string[] calldata defaultValue) - external - view - returns (string[] memory value); - - /// Gets the environment variable `name` and parses it as an array of `bytes`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, bytes[] calldata defaultValue) - external - view - returns (bytes[] memory value); - - /// Gets the environment variable `name` and parses it as `int256`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, int256 defaultValue) external view returns (int256 value); - - /// Gets the environment variable `name` and parses it as `address`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, address defaultValue) external view returns (address value); - - /// Gets the environment variable `name` and parses it as `bytes32`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, bytes32 defaultValue) external view returns (bytes32 value); - - /// Gets the environment variable `name` and parses it as `string`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata defaultValue) external view returns (string memory value); - - /// Gets the environment variable `name` and parses it as `bytes`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, bytes calldata defaultValue) external view returns (bytes memory value); - - /// Gets the environment variable `name` and parses it as an array of `bool`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, bool[] calldata defaultValue) - external - view - returns (bool[] memory value); - - /// Gets the environment variable `name` and parses it as an array of `uint256`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, uint256[] calldata defaultValue) - external - view - returns (uint256[] memory value); - - /// Gets the environment variable `name` and parses it as an array of `int256`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, int256[] calldata defaultValue) - external - view - returns (int256[] memory value); - - /// Gets the environment variable `name` and parses it as `string`. - /// Reverts if the variable was not found or could not be parsed. - function envString(string calldata name) external view returns (string memory value); - - /// Gets the environment variable `name` and parses it as an array of `string`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envString(string calldata name, string calldata delim) external view returns (string[] memory value); - - /// Gets the environment variable `name` and parses it as `uint256`. - /// Reverts if the variable was not found or could not be parsed. - function envUint(string calldata name) external view returns (uint256 value); - - /// Gets the environment variable `name` and parses it as an array of `uint256`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envUint(string calldata name, string calldata delim) external view returns (uint256[] memory value); - - /// Sets environment variables. - function setEnv(string calldata name, string calldata value) external; - - // ======== EVM ======== - - /// Gets all accessed reads and write slot from a `vm.record` session, for a given address. - function accesses(address target) external returns (bytes32[] memory readSlots, bytes32[] memory writeSlots); - - /// Gets the address for a given private key. - function addr(uint256 privateKey) external pure returns (address keyAddr); - - /// Gets all the logs according to specified filter. - function eth_getLogs(uint256 fromBlock, uint256 toBlock, address target, bytes32[] calldata topics) - external - returns (EthGetLogs[] memory logs); - - /// Gets the current `block.number`. - /// You should use this instead of `block.number` if you use `vm.roll`, as `block.number` is assumed to be constant across a transaction, - /// and as a result will get optimized out by the compiler. - /// See https://github.com/foundry-rs/foundry/issues/6180 - function getBlockNumber() external view returns (uint256 height); - - /// Gets the current `block.timestamp`. - /// You should use this instead of `block.timestamp` if you use `vm.warp`, as `block.timestamp` is assumed to be constant across a transaction, - /// and as a result will get optimized out by the compiler. - /// See https://github.com/foundry-rs/foundry/issues/6180 - function getBlockTimestamp() external view returns (uint256 timestamp); - - /// Gets the map key and parent of a mapping at a given slot, for a given address. - function getMappingKeyAndParentOf(address target, bytes32 elementSlot) - external - returns (bool found, bytes32 key, bytes32 parent); - - /// Gets the number of elements in the mapping at the given slot, for a given address. - function getMappingLength(address target, bytes32 mappingSlot) external returns (uint256 length); - - /// Gets the elements at index idx of the mapping at the given slot, for a given address. The - /// index must be less than the length of the mapping (i.e. the number of keys in the mapping). - function getMappingSlotAt(address target, bytes32 mappingSlot, uint256 idx) external returns (bytes32 value); - - /// Gets the nonce of an account. - function getNonce(address account) external view returns (uint64 nonce); - - /// Gets all the recorded logs. - function getRecordedLogs() external returns (Log[] memory logs); - - /// Loads a storage slot from an address. - function load(address target, bytes32 slot) external view returns (bytes32 data); - - /// Pauses gas metering (i.e. gas usage is not counted). Noop if already paused. - function pauseGasMetering() external; - - /// Records all storage reads and writes. - function record() external; - - /// Record all the transaction logs. - function recordLogs() external; - - /// Resumes gas metering (i.e. gas usage is counted again). Noop if already on. - function resumeGasMetering() external; - - /// Performs an Ethereum JSON-RPC request to the current fork URL. - function rpc(string calldata method, string calldata params) external returns (bytes memory data); - - /// Signs `digest` with `privateKey` using the secp256r1 curve. - function signP256(uint256 privateKey, bytes32 digest) external pure returns (bytes32 r, bytes32 s); - - /// Signs `digest` with `privateKey` using the secp256k1 curve. - function sign(uint256 privateKey, bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s); - - /// Starts recording all map SSTOREs for later retrieval. - function startMappingRecording() external; - - /// Record all account accesses as part of CREATE, CALL or SELFDESTRUCT opcodes in order, - /// along with the context of the calls - function startStateDiffRecording() external; - - /// Returns an ordered array of all account accesses from a `vm.startStateDiffRecording` session. - function stopAndReturnStateDiff() external returns (AccountAccess[] memory accountAccesses); - - /// Stops recording all map SSTOREs for later retrieval and clears the recorded data. - function stopMappingRecording() external; - - // ======== Filesystem ======== - - /// 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; - - /// Copies the contents of one file to another. This function will **overwrite** the contents of `to`. - /// On success, the total number of bytes copied is returned and it is equal to the length of the `to` file as reported by `metadata`. - /// Both `from` and `to` are relative to the project root. - function copyFile(string calldata from, string calldata to) external returns (uint64 copied); - - /// 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; - - /// Returns true if the given path points to an existing entity, else returns false. - function exists(string calldata path) external returns (bool result); - - /// Performs a foreign function call via the terminal. - function ffi(string[] calldata commandInput) external returns (bytes memory result); - - /// 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); - - /// 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); - - /// Returns true if the path exists on disk and is pointing at a directory, else returns false. - function isDir(string calldata path) external returns (bool result); - - /// Returns true if the path exists on disk and is pointing at a regular file, else returns false. - function isFile(string calldata path) external returns (bool result); - - /// Get the path of the current project root. - function projectRoot() external view returns (string memory path); - - /// Reads the directory at the given path recursively, up to `maxDepth`. - /// `maxDepth` defaults to 1, meaning only the direct children of the given directory will be returned. - /// Follows symbolic links if `followLinks` is true. - function readDir(string calldata path) external view returns (DirEntry[] memory entries); - - /// See `readDir(string)`. - function readDir(string calldata path, uint64 maxDepth) external view returns (DirEntry[] memory entries); - - /// See `readDir(string)`. - function readDir(string calldata path, uint64 maxDepth, bool followLinks) - external - view - returns (DirEntry[] memory entries); - - /// 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); - - /// 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); - - /// 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; - - /// 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; - - /// Performs a foreign function call via terminal and returns the exit code, stdout, and stderr. - function tryFfi(string[] calldata commandInput) external returns (FfiResult memory result); - - /// Returns the time since unix epoch in milliseconds. - function unixTime() external returns (uint256 milliseconds); - - /// 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; - - // ======== JSON ======== - - /// Checks if `key` exists in a JSON object. - function keyExists(string calldata json, string calldata key) external view returns (bool); - - /// Parses a string of JSON data at `key` and coerces it to `address`. - function parseJsonAddress(string calldata json, string calldata key) external pure returns (address); - - /// Parses a string of JSON data at `key` and coerces it to `address[]`. - function parseJsonAddressArray(string calldata json, string calldata key) - external - pure - returns (address[] memory); - - /// Parses a string of JSON data at `key` and coerces it to `bool`. - function parseJsonBool(string calldata json, string calldata key) external pure returns (bool); - - /// Parses a string of JSON data at `key` and coerces it to `bool[]`. - function parseJsonBoolArray(string calldata json, string calldata key) external pure returns (bool[] memory); - - /// Parses a string of JSON data at `key` and coerces it to `bytes`. - function parseJsonBytes(string calldata json, string calldata key) external pure returns (bytes memory); - - /// Parses a string of JSON data at `key` and coerces it to `bytes32`. - function parseJsonBytes32(string calldata json, string calldata key) external pure returns (bytes32); - - /// Parses a string of JSON data at `key` and coerces it to `bytes32[]`. - function parseJsonBytes32Array(string calldata json, string calldata key) - external - pure - returns (bytes32[] memory); - - /// Parses a string of JSON data at `key` and coerces it to `bytes[]`. - function parseJsonBytesArray(string calldata json, string calldata key) external pure returns (bytes[] memory); - - /// Parses a string of JSON data at `key` and coerces it to `int256`. - function parseJsonInt(string calldata json, string calldata key) external pure returns (int256); - - /// Parses a string of JSON data at `key` and coerces it to `int256[]`. - function parseJsonIntArray(string calldata json, string calldata key) external pure returns (int256[] memory); - - /// Returns an array of all the keys in a JSON object. - function parseJsonKeys(string calldata json, string calldata key) external pure returns (string[] memory keys); - - /// Parses a string of JSON data at `key` and coerces it to `string`. - function parseJsonString(string calldata json, string calldata key) external pure returns (string memory); - - /// Parses a string of JSON data at `key` and coerces it to `string[]`. - function parseJsonStringArray(string calldata json, string calldata key) external pure returns (string[] memory); - - /// Parses a string of JSON data at `key` and coerces it to `uint256`. - function parseJsonUint(string calldata json, string calldata key) external pure returns (uint256); - - /// Parses a string of JSON data at `key` and coerces it to `uint256[]`. - function parseJsonUintArray(string calldata json, string calldata key) external pure returns (uint256[] memory); - - /// ABI-encodes a JSON object. - function parseJson(string calldata json) external pure returns (bytes memory abiEncodedData); - - /// ABI-encodes a JSON object at `key`. - function parseJson(string calldata json, string calldata key) external pure returns (bytes memory abiEncodedData); - - /// See `serializeJson`. - function serializeAddress(string calldata objectKey, string calldata valueKey, address value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeAddress(string calldata objectKey, string calldata valueKey, address[] calldata values) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeBool(string calldata objectKey, string calldata valueKey, bool value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeBool(string calldata objectKey, string calldata valueKey, bool[] calldata values) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32 value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32[] calldata values) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeBytes(string calldata objectKey, string calldata valueKey, bytes calldata value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeBytes(string calldata objectKey, string calldata valueKey, bytes[] calldata values) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeInt(string calldata objectKey, string calldata valueKey, int256 value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeInt(string calldata objectKey, string calldata valueKey, int256[] calldata values) - external - returns (string memory json); - - /// Serializes a key and value to a JSON object stored in-memory that can be later written to a file. - /// Returns the stringified version of the specific JSON file up to that moment. - function serializeJson(string calldata objectKey, string calldata value) external returns (string memory json); - - /// See `serializeJson`. - function serializeString(string calldata objectKey, string calldata valueKey, string calldata value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeString(string calldata objectKey, string calldata valueKey, string[] calldata values) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeUint(string calldata objectKey, string calldata valueKey, uint256 value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeUint(string calldata objectKey, string calldata valueKey, uint256[] calldata values) - external - returns (string memory json); - - /// Write a serialized JSON object to a file. If the file exists, it will be overwritten. - 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; - - // ======== Scripting ======== - - /// 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; - - // ======== String ======== - - /// Parses the given `string` into an `address`. - function parseAddress(string calldata stringifiedValue) external pure returns (address parsedValue); - - /// Parses the given `string` into a `bool`. - function parseBool(string calldata stringifiedValue) external pure returns (bool parsedValue); - - /// Parses the given `string` into `bytes`. - function parseBytes(string calldata stringifiedValue) external pure returns (bytes memory parsedValue); - - /// Parses the given `string` into a `bytes32`. - function parseBytes32(string calldata stringifiedValue) external pure returns (bytes32 parsedValue); - - /// Parses the given `string` into a `int256`. - function parseInt(string calldata stringifiedValue) external pure returns (int256 parsedValue); - - /// Parses the given `string` into a `uint256`. - function parseUint(string calldata stringifiedValue) external pure returns (uint256 parsedValue); - - /// Converts the given value to a `string`. - function toString(address value) external pure returns (string memory stringifiedValue); - - /// Converts the given value to a `string`. - function toString(bytes calldata value) external pure returns (string memory stringifiedValue); - - /// Converts the given value to a `string`. - function toString(bytes32 value) external pure returns (string memory stringifiedValue); - - /// Converts the given value to a `string`. - function toString(bool value) external pure returns (string memory stringifiedValue); - - /// Converts the given value to a `string`. - function toString(uint256 value) external pure returns (string memory stringifiedValue); - - /// Converts the given value to a `string`. - function toString(int256 value) external pure returns (string memory stringifiedValue); - - // ======== Testing ======== - - /// If the condition is false, discard this run's fuzz inputs and generate new ones. - function assume(bool condition) external pure; - - /// 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; - - /// 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 as structs. - function rpcUrlStructs() external view returns (Rpc[] memory urls); - - /// Returns all rpc urls and their aliases `[alias, url][]`. - function rpcUrls() external view returns (string[2][] memory urls); - - /// Suspends execution of the main thread for `duration` milliseconds. - function sleep(uint256 duration) external; - - // ======== Utilities ======== - - /// Compute the address of a contract created with CREATE2 using the given CREATE2 deployer. - function computeCreate2Address(bytes32 salt, bytes32 initCodeHash, address deployer) - external - pure - returns (address); - - /// Compute the address of a contract created with CREATE2 using the default CREATE2 deployer. - function computeCreate2Address(bytes32 salt, bytes32 initCodeHash) external pure returns (address); - - /// Compute the address a contract will be deployed at for a given deployer address and nonce. - function computeCreateAddress(address deployer, uint256 nonce) external pure returns (address); - - /// Derives a private key from the name, labels the account with that name, and returns the wallet. - function createWallet(string calldata walletLabel) external returns (Wallet memory wallet); - - /// Generates a wallet from the private key and returns the wallet. - function createWallet(uint256 privateKey) external returns (Wallet memory wallet); - - /// Generates a wallet from the private key, labels the account with that name, and returns the wallet. - function createWallet(uint256 privateKey, string calldata walletLabel) external returns (Wallet memory wallet); - - /// 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); - - /// Derive a private key from a provided mnenomic string (or mnenomic file path) in the specified language - /// at the derivation path `m/44'/60'/0'/0/{index}`. - function deriveKey(string calldata mnemonic, uint32 index, string calldata language) - external - pure - returns (uint256 privateKey); - - /// Derive a private key from a provided mnenomic string (or mnenomic file path) in the specified language - /// at `{derivationPath}{index}`. - function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index, string calldata language) - external - pure - returns (uint256 privateKey); - - /// Gets the label for the specified address. - function getLabel(address account) external view returns (string memory currentLabel); - - /// Get a `Wallet`'s nonce. - function getNonce(Wallet calldata wallet) external returns (uint64 nonce); - - /// Labels an address in call traces. - function label(address account, string calldata newLabel) external; - - /// Adds a private key to the local forge wallet and returns the address. - function rememberKey(uint256 privateKey) external returns (address keyAddr); - - /// Signs data with a `Wallet`. - function sign(Wallet calldata wallet, bytes32 digest) external returns (uint8 v, bytes32 r, bytes32 s); - - /// Encodes a `bytes` value to a base64url string. - function toBase64URL(bytes calldata data) external pure returns (string memory); - - /// Encodes a `string` value to a base64url string. - function toBase64URL(string calldata data) external pure returns (string memory); - - /// Encodes a `bytes` value to a base64 string. - function toBase64(bytes calldata data) external pure returns (string memory); - - /// Encodes a `string` value to a base64 string. - function toBase64(string calldata data) external pure returns (string memory); -} - -/// The `Vm` interface does allow manipulation of the EVM state. These are all intended to be used -/// in tests, but it is not recommended to use these cheats in scripts. -interface Vm is VmSafe { - // ======== EVM ======== - - /// Returns the identifier of the currently active fork. Reverts if no fork is currently active. - function activeFork() external view returns (uint256 forkId); - - /// In forking mode, explicitly grant the given address cheatcode access. - function allowCheatcodes(address account) external; - - /// Sets `block.chainid`. - function chainId(uint256 newChainId) external; - - /// Clears all mocked calls. - function clearMockedCalls() external; - - /// Sets `block.coinbase`. - function coinbase(address newCoinbase) external; - - /// 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 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 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 the latest block and returns the identifier of the fork. - function createSelectFork(string calldata urlOrAlias) 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); - - /// Sets an address' balance. - function deal(address account, uint256 newBalance) external; - - /// Removes the snapshot with the given ID created by `snapshot`. - /// Takes the snapshot ID to delete. - /// Returns `true` if the snapshot was successfully deleted. - /// Returns `false` if the snapshot does not exist. - function deleteSnapshot(uint256 snapshotId) external returns (bool success); - - /// Removes _all_ snapshots previously created by `snapshot`. - function deleteSnapshots() external; - - /// Sets `block.difficulty`. - /// Not available on EVM versions from Paris onwards. Use `prevrandao` instead. - /// Reverts if used on unsupported EVM versions. - function difficulty(uint256 newDifficulty) external; - - /// Dump a genesis JSON file's `allocs` to disk. - function dumpState(string calldata pathToStateJson) external; - - /// Sets an address' code. - function etch(address target, bytes calldata newRuntimeBytecode) external; - - /// Sets `block.basefee`. - function fee(uint256 newBasefee) external; - - /// Returns true if the account is marked as persistent. - function isPersistent(address account) external view returns (bool persistent); - - /// Load a genesis JSON file's `allocs` into the in-memory revm state. - function loadAllocs(string calldata pathToAllocsJson) 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; - - /// See `makePersistent(address)`. - function makePersistent(address account0, address account1) external; - - /// See `makePersistent(address)`. - function makePersistent(address account0, address account1, address account2) external; - - /// See `makePersistent(address)`. - function makePersistent(address[] calldata accounts) 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; - - /// 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; - - /// Sets the *next* call's `msg.sender` to be the input address. - function prank(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 `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; - - /// 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); - - /// Resets the nonce of an account to 0 for EOAs and 1 for contract accounts. - function resetNonce(address account) external; - - /// Revert the state of the EVM to a previous snapshot - /// Takes the snapshot ID to revert to. - /// Returns `true` if the snapshot was successfully reverted. - /// Returns `false` if the snapshot does not exist. - /// **Note:** This does not automatically delete the snapshot. To delete the snapshot use `deleteSnapshot`. - function revertTo(uint256 snapshotId) external returns (bool success); - - /// Revert the state of the EVM to a previous snapshot and automatically deletes the snapshots - /// Takes the snapshot ID to revert to. - /// Returns `true` if the snapshot was successfully reverted and deleted. - /// Returns `false` if the snapshot does not exist. - function revertToAndDelete(uint256 snapshotId) external returns (bool success); - - /// Revokes persistent status from the address, previously added via `makePersistent`. - function revokePersistent(address account) external; - - /// See `revokePersistent(address)`. - function revokePersistent(address[] calldata accounts) external; - - /// Sets `block.height`. - function roll(uint256 newHeight) external; - - /// 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; - - /// Takes a fork identifier created by `createFork` and sets the corresponding forked state as active. - function selectFork(uint256 forkId) 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; - - /// 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); - - /// Sets all subsequent calls' `msg.sender` to be the input address until `stopPrank` is called. - function startPrank(address msgSender) 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; - - /// Stores a value to an address' storage slot. - function store(address target, bytes32 slot, bytes32 value) 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; - - /// Sets `tx.gasprice`. - function txGasPrice(uint256 newGasPrice) external; - - /// Sets `block.timestamp`. - function warp(uint256 newTimestamp) external; - - // ======== Testing ======== - - /// 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; - - /// 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; - - /// 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; - - /// Same as the previous method, but also checks supplied address against emitting contract. - function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData, address emitter) - external; - - /// Prepare an expected log with all topic and data 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. - function expectEmit() external; - - /// Same as the previous method, but also checks supplied address against emitting contract. - function expectEmit(address emitter) external; - - /// Expects an error on next call with any revert data. - function expectRevert() external; - - /// Expects an error on next call that starts with the revert data. - function expectRevert(bytes4 revertData) external; - - /// Expects an error on next call that exactly matches the revert data. - function expectRevert(bytes calldata revertData) 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; - - /// Marks a test as skipped. Must be called at the top of the test. - function skip(bool skipTest) external; -} diff --git a/lib/openzeppelin-contracts/lib/forge-std/src/console.sol b/lib/openzeppelin-contracts/lib/forge-std/src/console.sol deleted file mode 100644 index ad57e53..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/src/console2.sol b/lib/openzeppelin-contracts/lib/forge-std/src/console2.sol deleted file mode 100644 index c1e2cd7..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/src/interfaces/IERC1155.sol b/lib/openzeppelin-contracts/lib/forge-std/src/interfaces/IERC1155.sol deleted file mode 100644 index f7dd2b4..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/src/interfaces/IERC165.sol b/lib/openzeppelin-contracts/lib/forge-std/src/interfaces/IERC165.sol deleted file mode 100644 index 9af4bf8..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/src/interfaces/IERC20.sol b/lib/openzeppelin-contracts/lib/forge-std/src/interfaces/IERC20.sol deleted file mode 100644 index ba40806..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/src/interfaces/IERC4626.sol b/lib/openzeppelin-contracts/lib/forge-std/src/interfaces/IERC4626.sol deleted file mode 100644 index bfe3a11..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/src/interfaces/IERC721.sol b/lib/openzeppelin-contracts/lib/forge-std/src/interfaces/IERC721.sol deleted file mode 100644 index 0a16f45..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/src/interfaces/IMulticall3.sol b/lib/openzeppelin-contracts/lib/forge-std/src/interfaces/IMulticall3.sol deleted file mode 100644 index 0d031b7..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/src/mocks/MockERC20.sol b/lib/openzeppelin-contracts/lib/forge-std/src/mocks/MockERC20.sol deleted file mode 100644 index 6b825a0..0000000 --- a/lib/openzeppelin-contracts/lib/forge-std/src/mocks/MockERC20.sol +++ /dev/null @@ -1,216 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -/// @notice This is a mock contract of the ERC20 standard for testing purposes only, it SHOULD NOT be used in production. -/// @dev Forked from: https://github.com/transmissions11/solmate/blob/0384dbaaa4fcb5715738a9254a7c0a4cb62cf458/src/tokens/ERC20.sol -contract MockERC20 { - /*////////////////////////////////////////////////////////////// - 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 decimals; - - /*////////////////////////////////////////////////////////////// - ERC20 STORAGE - //////////////////////////////////////////////////////////////*/ - - uint256 public totalSupply; - - mapping(address => uint256) public balanceOf; - - mapping(address => mapping(address => uint256)) public allowance; - - /*////////////////////////////////////////////////////////////// - EIP-2612 STORAGE - //////////////////////////////////////////////////////////////*/ - - uint256 internal INITIAL_CHAIN_ID; - - bytes32 internal INITIAL_DOMAIN_SEPARATOR; - - mapping(address => uint256) public nonces; - - /*////////////////////////////////////////////////////////////// - INITIALIZE - //////////////////////////////////////////////////////////////*/ - - /// @dev A bool to track whether the contract has been initialized. - bool private initialized; - - /// @dev To hide constructor warnings across solc versions due to different constructor visibility requirements and - /// syntaxes, we add an initialization function that can be called only once. - function initialize(string memory _name, string memory _symbol, uint8 _decimals) public { - require(!initialized, "ALREADY_INITIALIZED"); - - name = _name; - symbol = _symbol; - decimals = _decimals; - - INITIAL_CHAIN_ID = _pureChainId(); - INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator(); - - initialized = true; - } - - /*////////////////////////////////////////////////////////////// - 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] = _sub(balanceOf[msg.sender], amount); - balanceOf[to] = _add(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 != ~uint256(0)) allowance[from][msg.sender] = _sub(allowed, amount); - - balanceOf[from] = _sub(balanceOf[from], amount); - balanceOf[to] = _add(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"); - - 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 _pureChainId() == 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"), - _pureChainId(), - address(this) - ) - ); - } - - /*////////////////////////////////////////////////////////////// - INTERNAL MINT/BURN LOGIC - //////////////////////////////////////////////////////////////*/ - - function _mint(address to, uint256 amount) internal virtual { - totalSupply = _add(totalSupply, amount); - balanceOf[to] = _add(balanceOf[to], amount); - - emit Transfer(address(0), to, amount); - } - - function _burn(address from, uint256 amount) internal virtual { - balanceOf[from] = _sub(balanceOf[from], amount); - totalSupply = _sub(totalSupply, amount); - - emit Transfer(from, address(0), amount); - } - - /*////////////////////////////////////////////////////////////// - INTERNAL SAFE MATH LOGIC - //////////////////////////////////////////////////////////////*/ - - function _add(uint256 a, uint256 b) internal pure returns (uint256) { - uint256 c = a + b; - require(c >= a, "ERC20: addition overflow"); - return c; - } - - function _sub(uint256 a, uint256 b) internal pure returns (uint256) { - require(a >= b, "ERC20: subtraction underflow"); - return a - b; - } - - /*////////////////////////////////////////////////////////////// - HELPERS - //////////////////////////////////////////////////////////////*/ - - // 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(); - } -} diff --git a/lib/openzeppelin-contracts/lib/forge-std/src/mocks/MockERC721.sol b/lib/openzeppelin-contracts/lib/forge-std/src/mocks/MockERC721.sol deleted file mode 100644 index 7584087..0000000 --- a/lib/openzeppelin-contracts/lib/forge-std/src/mocks/MockERC721.sol +++ /dev/null @@ -1,221 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -/// @notice This is a mock contract of the ERC721 standard for testing purposes only, it SHOULD NOT be used in production. -/// @dev Forked from: https://github.com/transmissions11/solmate/blob/0384dbaaa4fcb5715738a9254a7c0a4cb62cf458/src/tokens/ERC721.sol -contract MockERC721 { - /*////////////////////////////////////////////////////////////// - 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; - - /*////////////////////////////////////////////////////////////// - INITIALIZE - //////////////////////////////////////////////////////////////*/ - - /// @dev A bool to track whether the contract has been initialized. - bool private initialized; - - /// @dev To hide constructor warnings across solc versions due to different constructor visibility requirements and - /// syntaxes, we add an initialization function that can be called only once. - function initialize(string memory _name, string memory _symbol) public { - require(!initialized, "ALREADY_INITIALIZED"); - - name = _name; - symbol = _symbol; - - initialized = true; - } - - /*////////////////////////////////////////////////////////////// - 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. - _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( - !_isContract(to) - || IERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") - == IERC721TokenReceiver.onERC721Received.selector, - "UNSAFE_RECIPIENT" - ); - } - - function safeTransferFrom(address from, address to, uint256 id, bytes memory data) public virtual { - transferFrom(from, to, id); - - require( - !_isContract(to) - || IERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) - == IERC721TokenReceiver.onERC721Received.selector, - "UNSAFE_RECIPIENT" - ); - } - - /*////////////////////////////////////////////////////////////// - ERC165 LOGIC - //////////////////////////////////////////////////////////////*/ - - function supportsInterface(bytes4 interfaceId) public pure 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. - - _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"); - - _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( - !_isContract(to) - || IERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") - == IERC721TokenReceiver.onERC721Received.selector, - "UNSAFE_RECIPIENT" - ); - } - - function _safeMint(address to, uint256 id, bytes memory data) internal virtual { - _mint(to, id); - - require( - !_isContract(to) - || IERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) - == IERC721TokenReceiver.onERC721Received.selector, - "UNSAFE_RECIPIENT" - ); - } - - /*////////////////////////////////////////////////////////////// - HELPERS - //////////////////////////////////////////////////////////////*/ - - function _isContract(address _addr) private view returns (bool) { - uint256 codeLength; - - // Assembly required for versions < 0.8.0 to check extcodesize. - assembly { - codeLength := extcodesize(_addr) - } - - return codeLength > 0; - } -} - -interface IERC721TokenReceiver { - function onERC721Received(address, address, uint256, bytes calldata) external returns (bytes4); -} diff --git a/lib/openzeppelin-contracts/lib/forge-std/src/safeconsole.sol b/lib/openzeppelin-contracts/lib/forge-std/src/safeconsole.sol deleted file mode 100644 index 5714d09..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/test/StdAssertions.t.sol b/lib/openzeppelin-contracts/lib/forge-std/test/StdAssertions.t.sol deleted file mode 100644 index ae998f1..0000000 --- a/lib/openzeppelin-contracts/lib/forge-std/test/StdAssertions.t.sol +++ /dev/null @@ -1,1015 +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 test_ShouldFail() external { - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._fail(CUSTOM_ERROR); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_FALSE - //////////////////////////////////////////////////////////////////////////*/ - - function test_AssertFalse_Pass() external { - t._assertFalse(false, EXPECT_PASS); - } - - function test_AssertFalse_Fail() external { - vm.expectEmit(false, false, false, true); - emit log("Error: Assertion Failed"); - t._assertFalse(true, EXPECT_FAIL); - } - - function test_AssertFalse_Err_Pass() external { - t._assertFalse(false, CUSTOM_ERROR, EXPECT_PASS); - } - - function test_AssertFalse_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 testFuzz_AssertEq_Bool_Pass(bool a) external { - t._assertEq(a, a, EXPECT_PASS); - } - - function testFuzz_AssertEq_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 testFuzz_AssertEq_BoolErr_Pass(bool a) external { - t._assertEq(a, a, CUSTOM_ERROR, EXPECT_PASS); - } - - function testFuzz_AssertEq_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 testFuzz_AssertEq_Bytes_Pass(bytes calldata a) external { - t._assertEq(a, a, EXPECT_PASS); - } - - function testFuzz_AssertEq_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 testFuzz_AssertEq_BytesErr_Pass(bytes calldata a) external { - t._assertEq(a, a, CUSTOM_ERROR, EXPECT_PASS); - } - - function testFuzz_AssertEq_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 testFuzz_AssertEq_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 testFuzz_AssertEq_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 testFuzz_AssertEq_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 testFuzz_AssertEq_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 testFuzz_AssertEq_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 testFuzz_AssertEq_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 testFuzz_AssertEq_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 testFuzz_AssertEq_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 testFuzz_AssertEq_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 testFuzz_AssertEq_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 testFuzz_AssertEq_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 testFuzz_AssertEq_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 testFuzz_AssertEq_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 testFuzz_AssertEq_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 testFuzz_AssertEq_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 test_AssertEqUint() public { - assertEqUint(uint8(1), uint128(1)); - assertEqUint(uint64(2), uint64(2)); - } - - function testFail_AssertEqUint() public { - assertEqUint(uint64(1), uint96(2)); - assertEqUint(uint160(3), uint160(4)); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_ABS(UINT) - //////////////////////////////////////////////////////////////////////////*/ - - function testFuzz_AssertApproxEqAbs_Uint_Pass(uint256 a, uint256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbs(a, b, maxDelta, EXPECT_PASS); - } - - function testFuzz_AssertApproxEqAbs_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 testFuzz_AssertApproxEqAbs_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 testFuzz_AssertApproxEqAbs_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 testFuzz_AssertApproxEqAbsDecimal_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 testFuzz_AssertApproxEqAbsDecimal_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 testFuzz_AssertApproxEqAbsDecimal_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 testFuzz_AssertApproxEqAbsDecimal_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 testFuzz_AssertApproxEqAbs_Int_Pass(int256 a, int256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbs(a, b, maxDelta, EXPECT_PASS); - } - - function testFuzz_AssertApproxEqAbs_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 testFuzz_AssertApproxEqAbs_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 testFuzz_AssertApproxEqAbs_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 testFuzz_AssertApproxEqAbsDecimal_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 testFuzz_AssertApproxEqAbsDecimal_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 testFuzz_AssertApproxEqAbsDecimal_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 testFuzz_AssertApproxEqAbsDecimal_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 testFuzz_AssertApproxEqRel_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 testFuzz_AssertApproxEqRel_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 testFuzz_AssertApproxEqRel_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 testFuzz_AssertApproxEqRel_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 testFuzz_AssertApproxEqRelDecimal_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 testFuzz_AssertApproxEqRelDecimal_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 testFuzz_AssertApproxEqRelDecimal_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 testFuzz_AssertApproxEqRelDecimal_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 testFuzz_AssertApproxEqRel_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 testFuzz_AssertApproxEqRel_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 testFuzz_AssertApproxEqRel_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 testFuzz_AssertApproxEqRel_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 testFuzz_AssertEqCall_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 testFuzz_RevertWhenCalled_AssertEqCall_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 testFuzz_AssertEqCall_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 testFuzz_RevertWhenCalled_AssertEqCall_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 testFuzz_RevertWhenCalled_AssertEqCall_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 testFuzz_AssertNotEq_Bytes_Pass(bytes32 a, bytes32 b) external { - vm.assume(a != b); - t._assertNotEq(a, b, EXPECT_PASS); - } - - function testFuzz_AssertNotEq_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 testFuzz_AssertNotEq_BytesErr_Pass(bytes32 a, bytes32 b) external { - vm.assume(a != b); - t._assertNotEq(a, b, CUSTOM_ERROR, EXPECT_PASS); - } - - function testFuzz_AsserNottEq_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 test_AssertNotEqUint() public { - assertNotEq(uint8(1), uint128(2)); - assertNotEq(uint64(3), uint64(4)); - } - - function testFail_AssertNotEqUint() 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/openzeppelin-contracts/lib/forge-std/test/StdChains.t.sol b/lib/openzeppelin-contracts/lib/forge-std/test/StdChains.t.sol deleted file mode 100644 index b329125..0000000 --- a/lib/openzeppelin-contracts/lib/forge-std/test/StdChains.t.sol +++ /dev/null @@ -1,216 +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 test_ChainRpcInitialization() 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 testFuzz_Rpc(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"); - // testRpc("moonbeam"); - // testRpc("moonriver"); - // testRpc("moonbase"); - // testRpc("base_goerli"); - // testRpc("base"); - // } - - function test_ChainNoDefault() 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 test_SetChainFirstFails() 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 test_ChainBubbleUp() 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 test_CannotSetChain_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 test_SetChain() 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 test_SetNoEmptyAlias() 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 test_SetNoChainId0() 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 test_GetNoChainId0() 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 test_GetNoEmptyAlias() 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 test_ChainIdNotFound() 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 test_ChainAliasNotFound() 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 test_SetChain_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 test_DontUseDefaultRpcUrl() 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(); - stdChainsMock.exposed_getChain(31337); - vm.expectRevert(); - stdChainsMock.exposed_getChain("sepolia"); - } -} diff --git a/lib/openzeppelin-contracts/lib/forge-std/test/StdCheats.t.sol b/lib/openzeppelin-contracts/lib/forge-std/test/StdCheats.t.sol deleted file mode 100644 index e94923c..0000000 --- a/lib/openzeppelin-contracts/lib/forge-std/test/StdCheats.t.sol +++ /dev/null @@ -1,610 +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 test_Skip() public { - vm.warp(100); - skip(25); - assertEq(block.timestamp, 125); - } - - function test_Rewind() public { - vm.warp(100); - rewind(25); - assertEq(block.timestamp, 75); - } - - function test_Hoax() public { - hoax(address(1337)); - test.bar{value: 100}(address(1337)); - } - - function test_HoaxOrigin() public { - hoax(address(1337), address(1337)); - test.origin{value: 100}(address(1337)); - } - - function test_HoaxDifferentAddresses() public { - hoax(address(1337), address(7331)); - test.origin{value: 100}(address(1337), address(7331)); - } - - function test_StartHoax() public { - startHoax(address(1337)); - test.bar{value: 100}(address(1337)); - test.bar{value: 100}(address(1337)); - vm.stopPrank(); - test.bar(address(this)); - } - - function test_StartHoaxOrigin() 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 test_ChangePrankMsgSender() 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 test_ChangePrankMsgSenderAndTxOrigin() 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 test_MakeAccountEquivalence() public { - Account memory account = makeAccount("1337"); - (address addr, uint256 key) = makeAddrAndKey("1337"); - assertEq(account.addr, addr); - assertEq(account.key, key); - } - - function test_MakeAddrEquivalence() public { - (address addr,) = makeAddrAndKey("1337"); - assertEq(makeAddr("1337"), addr); - } - - function test_MakeAddrSigning() 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 test_Deal() public { - deal(address(this), 1 ether); - assertEq(address(this).balance, 1 ether); - } - - function test_DealToken() public { - Bar barToken = new Bar(); - address bar = address(barToken); - deal(bar, address(this), 10000e18); - assertEq(barToken.balanceOf(address(this)), 10000e18); - } - - function test_DealTokenAdjustTotalSupply() 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 test_DealERC1155Token() public { - BarERC1155 barToken = new BarERC1155(); - address bar = address(barToken); - dealERC1155(bar, address(this), 0, 10000e18, false); - assertEq(barToken.balanceOf(address(this), 0), 10000e18); - } - - function test_DealERC1155TokenAdjustTotalSupply() 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 test_DealERC721Token() 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 test_DeployCode() public { - address deployed = deployCode("StdCheats.t.sol:Bar", bytes("")); - assertEq(string(getCode(deployed)), string(getCode(address(test)))); - } - - function test_DestroyAccount() 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 test_DeployCodeNoArgs() public { - address deployed = deployCode("StdCheats.t.sol:Bar"); - assertEq(string(getCode(deployed)), string(getCode(address(test)))); - } - - function test_DeployCodeVal() 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 test_DeployCodeValNoArgs() 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 test_DeployCodeFail() 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 test_DeriveRememberKey() 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 test_BytesToUint() 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 test_ParseJsonTxDetail() 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 test_ReadEIP1559Transaction() 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 test_ReadEIP1559Transactions() 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 test_ReadReceipt() 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 test_ReadReceipts() 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 test_GasMeteringModifier() 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 testFuzz_AssumeAddressIsNot(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 test_AssumePayable() 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 test_AssumeNotPayable() 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 testFuzz_AssumeNotPrecompile(address addr) external { - assumeNotPrecompile(addr, getChain("optimism_goerli").chainId); - assertTrue( - addr < address(1) || (addr > address(9) && addr < address(0x4200000000000000000000000000000000000000)) - || addr > address(0x4200000000000000000000000000000000000800) - ); - } - - function testFuzz_AssumeNotForgeAddress(address addr) external { - assumeNotForgeAddress(addr); - assertTrue( - addr != address(vm) && addr != 0x000000000000000000636F6e736F6c652e6c6f67 - && addr != 0x4e59b44847b379578588920cA78FbF26c0B4956C - ); - } - - function test_CannotDeployCodeTo() 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 test_DeployCodeTo() 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 test_CannotAssumeNoBlacklisted_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 testFuzz_AssumeNotBlacklisted_TokenWithoutBlacklist(address addr) external { - assumeNotBlacklisted(SHIB, addr); - assertTrue(true); - } - - function test_AssumeNoBlacklisted_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 testFuzz_AssumeNotBlacklisted_USDC(address addr) external { - assumeNotBlacklisted(USDC, addr); - assertFalse(USDCLike(USDC).isBlacklisted(addr)); - } - - function test_AssumeNoBlacklisted_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 testFuzz_AssumeNotBlacklisted_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/openzeppelin-contracts/lib/forge-std/test/StdError.t.sol b/lib/openzeppelin-contracts/lib/forge-std/test/StdError.t.sol deleted file mode 100644 index a306eaa..0000000 --- a/lib/openzeppelin-contracts/lib/forge-std/test/StdError.t.sol +++ /dev/null @@ -1,120 +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 test_ExpectAssertion() public { - vm.expectRevert(stdError.assertionError); - test.assertionError(); - } - - function test_ExpectArithmetic() public { - vm.expectRevert(stdError.arithmeticError); - test.arithmeticError(10); - } - - function test_ExpectDiv() public { - vm.expectRevert(stdError.divisionError); - test.divError(0); - } - - function test_ExpectMod() public { - vm.expectRevert(stdError.divisionError); - test.modError(0); - } - - function test_ExpectEnum() public { - vm.expectRevert(stdError.enumConversionError); - test.enumConversion(1); - } - - function test_ExpectEncodeStg() public { - vm.expectRevert(stdError.encodeStorageError); - test.encodeStgError(); - } - - function test_ExpectPop() public { - vm.expectRevert(stdError.popError); - test.pop(); - } - - function test_ExpectOOB() public { - vm.expectRevert(stdError.indexOOBError); - test.indexOOBError(1); - } - - function test_ExpectMem() public { - vm.expectRevert(stdError.memOverflowError); - test.mem(); - } - - function test_ExpectIntern() 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/openzeppelin-contracts/lib/forge-std/test/StdMath.t.sol b/lib/openzeppelin-contracts/lib/forge-std/test/StdMath.t.sol deleted file mode 100644 index 6f50638..0000000 --- a/lib/openzeppelin-contracts/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 test_GetAbs() 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 testFuzz_GetAbs(int256 a) external { - uint256 manualAbs = getAbs(a); - - uint256 abs = stdMath.abs(a); - - assertEq(abs, manualAbs); - } - - function test_GetDelta_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 testFuzz_GetDelta_Uint(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 test_GetDelta_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 testFuzz_GetDelta_Int(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 test_GetPercentDelta_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 testFuzz_GetPercentDelta_Uint(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 test_GetPercentDelta_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 testFuzz_GetPercentDelta_Int(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/openzeppelin-contracts/lib/forge-std/test/StdStorage.t.sol b/lib/openzeppelin-contracts/lib/forge-std/test/StdStorage.t.sol deleted file mode 100644 index 0b3ca9b..0000000 --- a/lib/openzeppelin-contracts/lib/forge-std/test/StdStorage.t.sol +++ /dev/null @@ -1,315 +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 test_StorageHidden() public { - assertEq(uint256(keccak256("my.random.var")), stdstore.target(address(test)).sig("hidden()").find()); - } - - function test_StorageObvious() public { - assertEq(uint256(0), stdstore.target(address(test)).sig("exists()").find()); - } - - function test_StorageExtraSload() public { - assertEq(16, stdstore.target(address(test)).sig(test.extra_sload.selector).find()); - } - - function test_StorageCheckedWriteHidden() public { - stdstore.target(address(test)).sig(test.hidden.selector).checked_write(100); - assertEq(uint256(test.hidden()), 100); - } - - function test_StorageCheckedWriteObvious() public { - stdstore.target(address(test)).sig(test.exists.selector).checked_write(100); - assertEq(test.exists(), 100); - } - - function test_StorageCheckedWriteSignedIntegerHidden() public { - stdstore.target(address(test)).sig(test.hidden.selector).checked_write_int(-100); - assertEq(int256(uint256(test.hidden())), -100); - } - - function test_StorageCheckedWriteSignedIntegerObvious() public { - stdstore.target(address(test)).sig(test.tG.selector).checked_write_int(-100); - assertEq(test.tG(), -100); - } - - function test_StorageMapStructA() 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 test_StorageMapStructB() 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 test_StorageDeepMap() 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 test_StorageCheckedWriteDeepMap() 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 test_StorageDeepMapStructA() 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 test_StorageDeepMapStructB() 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 test_StorageCheckedWriteDeepMapStructA() 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 test_StorageCheckedWriteDeepMapStructB() 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 test_StorageCheckedWriteMapStructA() 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 test_StorageCheckedWriteMapStructB() 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 test_StorageStructA() public { - uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(0).find(); - assertEq(uint256(7), slot); - } - - function test_StorageStructB() public { - uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(1).find(); - assertEq(uint256(7) + 1, slot); - } - - function test_StorageCheckedWriteStructA() 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 test_StorageCheckedWriteStructB() 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 test_StorageMapAddrFound() 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 test_StorageMapAddrRoot() public { - (uint256 slot, bytes32 key) = - stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).parent(); - assertEq(address(uint160(uint256(key))), address(this)); - assertEq(uint256(1), slot); - slot = stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).root(); - assertEq(uint256(1), slot); - } - - function test_StorageMapUintFound() 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 test_StorageCheckedWriteMapUint() public { - stdstore.target(address(test)).sig(test.map_uint.selector).with_key(100).checked_write(100); - assertEq(100, test.map_uint(100)); - } - - function test_StorageCheckedWriteMapAddr() 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 test_StorageCheckedWriteMapBool() public { - stdstore.target(address(test)).sig(test.map_bool.selector).with_key(address(this)).checked_write(true); - assertTrue(test.map_bool(address(this))); - } - - function testFail_StorageCheckedWriteMapPacked() 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 test_StorageCheckedWriteMapPackedSuccess() 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 testFail_StorageConst() public { - // vm.expectRevert(abi.encodeWithSignature("NotStorage(bytes4)", bytes4(keccak256("const()")))); - stdstore.target(address(test)).sig("const()").find(); - } - - function testFail_StorageNativePack() 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 test_StorageReadBytes32() public { - bytes32 val = stdstore.target(address(test)).sig(test.tE.selector).read_bytes32(); - assertEq(val, hex"1337"); - } - - function test_StorageReadBool_False() public { - bool val = stdstore.target(address(test)).sig(test.tB.selector).read_bool(); - assertEq(val, false); - } - - function test_StorageReadBool_True() public { - bool val = stdstore.target(address(test)).sig(test.tH.selector).read_bool(); - assertEq(val, true); - } - - function test_StorageReadBool_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 test_StorageReadAddress() public { - address val = stdstore.target(address(test)).sig(test.tF.selector).read_address(); - assertEq(val, address(1337)); - } - - function test_StorageReadUint() public { - uint256 val = stdstore.target(address(test)).sig(test.exists.selector).read_uint(); - assertEq(val, 1); - } - - function test_StorageReadInt() 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; - bytes32 private tI = ~bytes32(hex"1337"); - - 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"); - } - - function extra_sload() public view returns (bytes32 t) { - // trigger read on slot `tE`, and make a staticcall to make sure compiler doesn't optimize this SLOAD away - assembly { - pop(staticcall(gas(), sload(tE.slot), 0, 0, 0, 0)) - } - t = tI; - } -} diff --git a/lib/openzeppelin-contracts/lib/forge-std/test/StdStyle.t.sol b/lib/openzeppelin-contracts/lib/forge-std/test/StdStyle.t.sol deleted file mode 100644 index e12c005..0000000 --- a/lib/openzeppelin-contracts/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 test_StyleColor() 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 test_StyleFontWeight() 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 test_StyleCombined() 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 test_StyleCustom() 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/openzeppelin-contracts/lib/forge-std/test/StdUtils.t.sol b/lib/openzeppelin-contracts/lib/forge-std/test/StdUtils.t.sol deleted file mode 100644 index 80acc25..0000000 --- a/lib/openzeppelin-contracts/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 pure returns (int256) { - return bound(num, min, max); - } - - function exposed_bound(uint256 num, uint256 min, uint256 max) external pure 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 test_Bound() 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 test_Bound_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 test_Bound_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 test_Bound_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 test_Bound(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 test_BoundUint256Max() 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 test_CannotBoundMaxLessThanMin() 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 test_CannotBoundMaxLessThanMin(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 test_BoundInt() 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 test_BoundInt_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 test_BoundInt_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 test_BoundInt_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 test_BoundInt(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 test_BoundIntInt256Max() 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 test_BoundIntInt256Min() 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 test_CannotBoundIntMaxLessThanMin() 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 test_CannotBoundIntMaxLessThanMin(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 test_BoundPrivateKey() 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 test_BytesToUint() 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 test_CannotConvertGT32Bytes() 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 test_ComputeCreateAddress() external { - address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9; - uint256 nonce = 14; - address createAddress = computeCreateAddress(deployer, nonce); - assertEq(createAddress, 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45); - } - - /*////////////////////////////////////////////////////////////////////////// - COMPUTE CREATE2 ADDRESS - //////////////////////////////////////////////////////////////////////////*/ - - function test_ComputeCreate2Address() 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 test_ComputeCreate2AddressWithDefaultDeployer() 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 test_CannotGetTokenBalances_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 test_CannotGetTokenBalances_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 test_GetTokenBalances_Empty() external { - address[] memory addresses = new address[](0); - uint256[] memory balances = getTokenBalances(USDC, addresses); - assertEq(balances.length, 0); - } - - function test_GetTokenBalances_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 test_GetTokenBalances_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/openzeppelin-contracts/lib/forge-std/test/Vm.t.sol b/lib/openzeppelin-contracts/lib/forge-std/test/Vm.t.sol deleted file mode 100644 index 95d6145..0000000 --- a/lib/openzeppelin-contracts/lib/forge-std/test/Vm.t.sol +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0 <0.9.0; - -import {Test} from "../src/Test.sol"; -import {Vm, VmSafe} from "../src/Vm.sol"; - -contract VmTest is Test { - // This test ensures that functions are never accidentally removed from a Vm interface, or - // inadvertently moved between Vm and VmSafe. This test must be updated each time a function is - // added to or removed from Vm or VmSafe. - function test_interfaceId() public { - assertEq(type(VmSafe).interfaceId, bytes4(0x01ec102d), "VmSafe"); - assertEq(type(Vm).interfaceId, bytes4(0xa63eed6b), "Vm"); - } -} diff --git a/lib/openzeppelin-contracts/lib/forge-std/test/compilation/CompilationScript.sol b/lib/openzeppelin-contracts/lib/forge-std/test/compilation/CompilationScript.sol deleted file mode 100644 index e205cff..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/test/compilation/CompilationScriptBase.sol b/lib/openzeppelin-contracts/lib/forge-std/test/compilation/CompilationScriptBase.sol deleted file mode 100644 index ce8e0e9..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/test/compilation/CompilationTest.sol b/lib/openzeppelin-contracts/lib/forge-std/test/compilation/CompilationTest.sol deleted file mode 100644 index 9beeafe..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/test/compilation/CompilationTestBase.sol b/lib/openzeppelin-contracts/lib/forge-std/test/compilation/CompilationTestBase.sol deleted file mode 100644 index e993535..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/test/fixtures/broadcast.log.json b/lib/openzeppelin-contracts/lib/forge-std/test/fixtures/broadcast.log.json deleted file mode 100644 index 0a0200b..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/lib/forge-std/test/mocks/MockERC20.t.sol b/lib/openzeppelin-contracts/lib/forge-std/test/mocks/MockERC20.t.sol deleted file mode 100644 index 3649e60..0000000 --- a/lib/openzeppelin-contracts/lib/forge-std/test/mocks/MockERC20.t.sol +++ /dev/null @@ -1,441 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import {MockERC20} from "../../src/mocks/MockERC20.sol"; -import {StdCheats} from "../../src/StdCheats.sol"; -import {Test} from "../../src/Test.sol"; - -contract Token_ERC20 is MockERC20 { - constructor(string memory name, string memory symbol, uint8 decimals) { - initialize(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); - } -} - -contract MockERC20Test is StdCheats, Test { - Token_ERC20 token; - - bytes32 constant PERMIT_TYPEHASH = - keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); - - function setUp() public { - token = new Token_ERC20("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); - - vm.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); - - vm.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 = vm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = vm.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); - - vm.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); - - vm.prank(from); - token.approve(address(this), 1e18); - - token.transferFrom(from, address(0xBEEF), 1e18); - } - - function testFailPermitBadNonce() public { - uint256 privateKey = 0xBEEF; - address owner = vm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = vm.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 = vm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = vm.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 = vm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = vm.sign( - privateKey, - keccak256( - abi.encodePacked( - "\x19\x01", - token.DOMAIN_SEPARATOR(), - keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 0, oldTimestamp)) - ) - ) - ); - - vm.warp(block.timestamp + 1); - token.permit(owner, address(0xCAFE), 1e18, oldTimestamp, v, r, s); - } - - function testFailPermitReplay() public { - uint256 privateKey = 0xBEEF; - address owner = vm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = vm.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 { - Token_ERC20 tkn = new Token_ERC20(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); - - vm.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 = vm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = vm.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); - - vm.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); - - vm.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 = vm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = vm.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 = vm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = vm.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 = vm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = vm.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 = vm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = vm.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); - } -} diff --git a/lib/openzeppelin-contracts/lib/forge-std/test/mocks/MockERC721.t.sol b/lib/openzeppelin-contracts/lib/forge-std/test/mocks/MockERC721.t.sol deleted file mode 100644 index 3bf84c9..0000000 --- a/lib/openzeppelin-contracts/lib/forge-std/test/mocks/MockERC721.t.sol +++ /dev/null @@ -1,721 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import {MockERC721, IERC721TokenReceiver} from "../../src/mocks/MockERC721.sol"; -import {StdCheats} from "../../src/StdCheats.sol"; -import {Test} from "../../src/Test.sol"; - -contract ERC721Recipient is IERC721TokenReceiver { - 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 IERC721TokenReceiver.onERC721Received.selector; - } -} - -contract RevertingERC721Recipient is IERC721TokenReceiver { - function onERC721Received(address, address, uint256, bytes calldata) public virtual override returns (bytes4) { - revert(string(abi.encodePacked(IERC721TokenReceiver.onERC721Received.selector))); - } -} - -contract WrongReturnDataERC721Recipient is IERC721TokenReceiver { - function onERC721Received(address, address, uint256, bytes calldata) public virtual override returns (bytes4) { - return 0xCAFEBEEF; - } -} - -contract NonERC721Recipient {} - -contract Token_ERC721 is MockERC721 { - constructor(string memory _name, string memory _symbol) { - initialize(_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); - } -} - -contract MockERC721Test is StdCheats, Test { - Token_ERC721 token; - - function setUp() public { - token = new Token_ERC721("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); - - vm.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)); - - vm.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); - - vm.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); - - vm.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); - - vm.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); - - vm.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); - assertEq(recipient.data(), ""); - } - - function testSafeTransferFromToERC721RecipientWithData() public { - address from = address(0xABCD); - ERC721Recipient recipient = new ERC721Recipient(); - - token.mint(from, 1337); - - vm.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); - assertEq(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); - assertEq(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); - assertEq(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 Token_ERC721(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); - - vm.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)); - - vm.expectRevert("NOT_MINTED"); - token.ownerOf(id); - } - - function testApproveAll(address to, bool approved) public { - token.setApprovalForAll(to, approved); - - assertEq(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); - - vm.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); - - vm.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); - - vm.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); - - vm.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); - assertEq(recipient.data(), ""); - } - - function testSafeTransferFromToERC721RecipientWithData(uint256 id, bytes calldata data) public { - address from = address(0xABCD); - ERC721Recipient recipient = new ERC721Recipient(); - - token.mint(from, id); - - vm.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); - assertEq(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); - assertEq(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); - assertEq(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/openzeppelin-contracts/lib/halmos-cheatcodes/LICENSE b/lib/openzeppelin-contracts/lib/halmos-cheatcodes/LICENSE deleted file mode 100644 index 0ad25db..0000000 --- a/lib/openzeppelin-contracts/lib/halmos-cheatcodes/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/openzeppelin-contracts/lib/halmos-cheatcodes/README.md b/lib/openzeppelin-contracts/lib/halmos-cheatcodes/README.md deleted file mode 100644 index 209c2cf..0000000 --- a/lib/openzeppelin-contracts/lib/halmos-cheatcodes/README.md +++ /dev/null @@ -1,97 +0,0 @@ -# Halmos Cheat Codes - -Halmos cheatcodes are abstract functions designed to facilitate writing symbolic tests, such as the creation of new symbolic values at runtime. While these cheatcodes are currently exclusive to [Halmos][halmos], they are not limited to it and could potentially be supported by other symbolic testing tools in the future. - -Please refer to [the list of currently available cheatcodes][list]. More cheatcodes will be added in the future. - -Join the [Halmos Telegram Group][chat] for any inquiries or further discussions. - -[halmos]: -[list]: -[chat]: - -## Installation - -To install using Foundry: -``` -forge install a16z/halmos-cheatcodes -``` -Alternatively, you can directly add it as a submodule: -``` -git submodule add https://github.com/a16z/halmos-cheatcodes -``` - -## Example usage - -Below is an example of a symbolic test that checks for potential unauthorized access to others' tokens. The approach involves setting up an initial symbolic state of the token contract, executing an arbitrary function call to the token contract, and checking if there is an execution path that increases the caller's balance and/or decreases the balance of others. This example illustrates how to utilize cheatcodes to set up initial symbolic states and execute arbitrary function calls. - -```solidity -// import Halmos cheatcodes -import {SymTest} from "halmos-cheatcodes/SymTest.sol"; - -import {Test} from "forge-std/Test.sol"; - -import {Token} from "/path/to/Token.sol"; - -contract TokenTest is SymTest, Test { - Token token; - - function setUp() public { - token = new Token(); - - // set the balances of three arbitrary accounts to arbitrary symbolic values - for (uint256 i = 0; i < 3; i++) { - address receiver = svm.createAddress('receiver'); // create a new symbolic address - uint256 amount = svm.createUint256('amount'); // create a new symbolic uint256 value - token.transfer(receiver, amount); - } - } - - function checkBalanceUpdate() public { - // consider two arbitrary distinct accounts - address caller = svm.createAddress('caller'); // create a symbolic address - address others = svm.createAddress('others'); // create another symbolic address - vm.assume(others != caller); // assume the two addresses are different - - // record their current balances - uint256 oldBalanceCaller = token.balanceOf(caller); - uint256 oldBalanceOthers = token.balanceOf(others); - - // execute an arbitrary function call to the token from the caller - vm.prank(caller); - uint256 dataSize = 100; // the max calldata size for the public functions in the token - bytes memory data = svm.createBytes(dataSize, 'data'); // create a symbolic calldata - address(token).call(data); - - // ensure that the caller cannot spend others' tokens - assert(token.balanceOf(caller) <= oldBalanceCaller); // cannot increase their own balance - assert(token.balanceOf(others) >= oldBalanceOthers); // cannot decrease others' balance - } -} -``` - -When running the above test against the following buggy token contract, Halmos will provide a counterexample that may be overlooked during manual reviews. - -```solidity -/// @notice This is a buggy token contract. DO NOT use it in production. -contract Token { - mapping(address => uint) public balanceOf; - - constructor() public { - balanceOf[msg.sender] = 1e27; - } - - function transfer(address to, uint amount) public { - _transfer(msg.sender, to, amount); - } - - function _transfer(address from, address to, uint amount) public { - balanceOf[from] -= amount; - balanceOf[to] += amount; - } -} -``` - -## Disclaimer - -_These smart contracts and code are being provided as is. No guarantee, representation or warranty is being made, express or implied, as to the safety or correctness of the user interface or the smart contracts and code. They have not been audited and as such there can be no assurance they will work as intended, and users may experience delays, failures, errors, omissions or loss of transmitted information. THE SMART CONTRACTS AND CODE CONTAINED HEREIN ARE FURNISHED AS IS, WHERE IS, WITH ALL FAULTS AND WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING ANY WARRANTY OF MERCHANTABILITY, NON-INFRINGEMENT OR FITNESS FOR ANY PARTICULAR PURPOSE. Further, use of any of these smart contracts and code may be restricted or prohibited under applicable law, including securities laws, and it is therefore strongly advised for you to contact a reputable attorney in any jurisdiction where these smart contracts and code may be accessible for any questions or concerns with respect thereto. Further, no information provided in this repo should be construed as investment advice or legal advice for any particular facts or circumstances, and is not meant to replace competent counsel. a16z is not liable for any use of the foregoing, and users should proceed with caution and use at their own risk. See a16z.com/disclosures for more info._ diff --git a/lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/SVM.sol b/lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/SVM.sol deleted file mode 100644 index e9ba3ea..0000000 --- a/lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/SVM.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity >=0.8.0 <0.9.0; - -/// @notice Symbolic Virtual Machine -interface SVM { - // Create a new symbolic uint value ranging over [0, 2**bitSize - 1] (inclusive) - function createUint(uint256 bitSize, string memory name) external pure returns (uint256 value); - - // Create a new symbolic uint256 value - function createUint256(string memory name) external pure returns (uint256 value); - - // Create a new symbolic signed int value - function createInt(uint256 bitSize, string memory name) external pure returns (int256 value); - - // Create a new symbolic int256 value - function createInt256(string memory name) external pure returns (int256 value); - - // Create a new symbolic byte array with the given byte size - function createBytes(uint256 byteSize, string memory name) external pure returns (bytes memory value); - - // Create a new symbolic string backed by a symbolic array with the given byte size - function createString(uint256 byteSize, string memory name) external pure returns (string memory value); - - // Create a new symbolic bytes32 value - function createBytes32(string memory name) external pure returns (bytes32 value); - - // Create a new symbolic bytes4 value - function createBytes4(string memory name) external pure returns (bytes4 value); - - // Create a new symbolic address value - function createAddress(string memory name) external pure returns (address value); - - // Create a new symbolic boolean value - function createBool(string memory name) external pure returns (bool value); -} diff --git a/lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/SymTest.sol b/lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/SymTest.sol deleted file mode 100644 index 96684ed..0000000 --- a/lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/SymTest.sol +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity >=0.8.0 <0.9.0; - -import {SVM} from "./SVM.sol"; - -abstract contract SymTest { - // SVM cheat code address: 0xf3993a62377bcd56ae39d773740a5390411e8bc9 - address internal constant SVM_ADDRESS = address(uint160(uint256(keccak256("svm cheat code")))); - - SVM internal constant svm = SVM(SVM_ADDRESS); -} diff --git a/lib/openzeppelin-contracts/logo.svg b/lib/openzeppelin-contracts/logo.svg deleted file mode 100644 index f1e14c2..0000000 --- a/lib/openzeppelin-contracts/logo.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/lib/openzeppelin-contracts/netlify.toml b/lib/openzeppelin-contracts/netlify.toml deleted file mode 100644 index 0447f41..0000000 --- a/lib/openzeppelin-contracts/netlify.toml +++ /dev/null @@ -1,3 +0,0 @@ -[build] -command = "npm run docs" -publish = "build/site" diff --git a/lib/openzeppelin-contracts/package-lock.json b/lib/openzeppelin-contracts/package-lock.json deleted file mode 100644 index 7326aeb..0000000 --- a/lib/openzeppelin-contracts/package-lock.json +++ /dev/null @@ -1,11328 +0,0 @@ -{ - "name": "openzeppelin-solidity", - "version": "5.0.2", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "openzeppelin-solidity", - "version": "5.0.2", - "license": "MIT", - "devDependencies": { - "@changesets/changelog-github": "^0.5.0", - "@changesets/cli": "^2.26.0", - "@changesets/pre": "^2.0.0", - "@changesets/read": "^0.6.0", - "@nomicfoundation/hardhat-chai-matchers": "^2.0.6", - "@nomicfoundation/hardhat-ethers": "^3.0.4", - "@nomicfoundation/hardhat-network-helpers": "^1.0.3", - "@openzeppelin/docs-utils": "^0.1.5", - "@openzeppelin/merkle-tree": "^1.0.7", - "@openzeppelin/upgrade-safe-transpiler": "^0.3.32", - "@openzeppelin/upgrades-core": "^1.20.6", - "chai": "^4.2.0", - "eslint": "^8.30.0", - "eslint-config-prettier": "^9.0.0", - "ethers": "^6.7.1", - "glob": "^10.3.5", - "graphlib": "^2.1.8", - "hardhat": "^2.22.2", - "hardhat-exposed": "^0.3.15", - "hardhat-gas-reporter": "^2.0.0", - "hardhat-ignore-warnings": "^0.2.11", - "lodash.startcase": "^4.4.0", - "micromatch": "^4.0.2", - "p-limit": "^3.1.0", - "prettier": "^3.0.0", - "prettier-plugin-solidity": "^1.1.0", - "rimraf": "^6.0.0", - "semver": "^7.3.5", - "solhint": "^5.0.0", - "solhint-plugin-openzeppelin": "file:scripts/solhint-custom", - "solidity-ast": "^0.4.50", - "solidity-coverage": "^0.8.5", - "solidity-docgen": "^0.6.0-beta.29", - "undici": "^6.11.1", - "yargs": "^17.0.0" - } - }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@adraffy/ens-normalize": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.9.2.tgz", - "integrity": "sha512-0h+FrQDqe2Wn+IIGFkTCd4aAwTJ+7834Ek1COohCyV26AXhwQ7WQaz+4F/nLOeVl/3BtWHOHLPsq46V8YB46Eg==", - "dev": true - }, - "node_modules/@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.22.13", - "chalk": "^2.4.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", - "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz", - "integrity": "sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==", - "dev": true, - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@changesets/apply-release-plan": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-6.1.4.tgz", - "integrity": "sha512-FMpKF1fRlJyCZVYHr3CbinpZZ+6MwvOtWUuO8uo+svcATEoc1zRDcj23pAurJ2TZ/uVz1wFHH6K3NlACy0PLew==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.20.1", - "@changesets/config": "^2.3.1", - "@changesets/get-version-range-type": "^0.3.2", - "@changesets/git": "^2.0.0", - "@changesets/types": "^5.2.1", - "@manypkg/get-packages": "^1.1.3", - "detect-indent": "^6.0.0", - "fs-extra": "^7.0.1", - "lodash.startcase": "^4.4.0", - "outdent": "^0.5.0", - "prettier": "^2.7.1", - "resolve-from": "^5.0.0", - "semver": "^7.5.3" - } - }, - "node_modules/@changesets/apply-release-plan/node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/@changesets/assemble-release-plan": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-5.2.4.tgz", - "integrity": "sha512-xJkWX+1/CUaOUWTguXEbCDTyWJFECEhmdtbkjhn5GVBGxdP/JwaHBIU9sW3FR6gD07UwZ7ovpiPclQZs+j+mvg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.20.1", - "@changesets/errors": "^0.1.4", - "@changesets/get-dependents-graph": "^1.3.6", - "@changesets/types": "^5.2.1", - "@manypkg/get-packages": "^1.1.3", - "semver": "^7.5.3" - } - }, - "node_modules/@changesets/changelog-git": { - "version": "0.1.14", - "resolved": "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.1.14.tgz", - "integrity": "sha512-+vRfnKtXVWsDDxGctOfzJsPhaCdXRYoe+KyWYoq5X/GqoISREiat0l3L8B0a453B2B4dfHGcZaGyowHbp9BSaA==", - "dev": true, - "dependencies": { - "@changesets/types": "^5.2.1" - } - }, - "node_modules/@changesets/changelog-github": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@changesets/changelog-github/-/changelog-github-0.5.0.tgz", - "integrity": "sha512-zoeq2LJJVcPJcIotHRJEEA2qCqX0AQIeFE+L21L8sRLPVqDhSXY8ZWAt2sohtBpFZkBwu+LUwMSKRr2lMy3LJA==", - "dev": true, - "dependencies": { - "@changesets/get-github-info": "^0.6.0", - "@changesets/types": "^6.0.0", - "dotenv": "^8.1.0" - } - }, - "node_modules/@changesets/changelog-github/node_modules/@changesets/types": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@changesets/types/-/types-6.0.0.tgz", - "integrity": "sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==", - "dev": true - }, - "node_modules/@changesets/cli": { - "version": "2.26.2", - "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-2.26.2.tgz", - "integrity": "sha512-dnWrJTmRR8bCHikJHl9b9HW3gXACCehz4OasrXpMp7sx97ECuBGGNjJhjPhdZNCvMy9mn4BWdplI323IbqsRig==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.20.1", - "@changesets/apply-release-plan": "^6.1.4", - "@changesets/assemble-release-plan": "^5.2.4", - "@changesets/changelog-git": "^0.1.14", - "@changesets/config": "^2.3.1", - "@changesets/errors": "^0.1.4", - "@changesets/get-dependents-graph": "^1.3.6", - "@changesets/get-release-plan": "^3.0.17", - "@changesets/git": "^2.0.0", - "@changesets/logger": "^0.0.5", - "@changesets/pre": "^1.0.14", - "@changesets/read": "^0.5.9", - "@changesets/types": "^5.2.1", - "@changesets/write": "^0.2.3", - "@manypkg/get-packages": "^1.1.3", - "@types/is-ci": "^3.0.0", - "@types/semver": "^7.5.0", - "ansi-colors": "^4.1.3", - "chalk": "^2.1.0", - "enquirer": "^2.3.0", - "external-editor": "^3.1.0", - "fs-extra": "^7.0.1", - "human-id": "^1.0.2", - "is-ci": "^3.0.1", - "meow": "^6.0.0", - "outdent": "^0.5.0", - "p-limit": "^2.2.0", - "preferred-pm": "^3.0.0", - "resolve-from": "^5.0.0", - "semver": "^7.5.3", - "spawndamnit": "^2.0.0", - "term-size": "^2.1.0", - "tty-table": "^4.1.5" - }, - "bin": { - "changeset": "bin.js" - } - }, - "node_modules/@changesets/cli/node_modules/@changesets/pre": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-1.0.14.tgz", - "integrity": "sha512-dTsHmxQWEQekHYHbg+M1mDVYFvegDh9j/kySNuDKdylwfMEevTeDouR7IfHNyVodxZXu17sXoJuf2D0vi55FHQ==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.20.1", - "@changesets/errors": "^0.1.4", - "@changesets/types": "^5.2.1", - "@manypkg/get-packages": "^1.1.3", - "fs-extra": "^7.0.1" - } - }, - "node_modules/@changesets/cli/node_modules/@changesets/read": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/@changesets/read/-/read-0.5.9.tgz", - "integrity": "sha512-T8BJ6JS6j1gfO1HFq50kU3qawYxa4NTbI/ASNVVCBTsKquy2HYwM9r7ZnzkiMe8IEObAJtUVGSrePCOxAK2haQ==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.20.1", - "@changesets/git": "^2.0.0", - "@changesets/logger": "^0.0.5", - "@changesets/parse": "^0.3.16", - "@changesets/types": "^5.2.1", - "chalk": "^2.1.0", - "fs-extra": "^7.0.1", - "p-filter": "^2.1.0" - } - }, - "node_modules/@changesets/cli/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/@changesets/config": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@changesets/config/-/config-2.3.1.tgz", - "integrity": "sha512-PQXaJl82CfIXddUOppj4zWu+987GCw2M+eQcOepxN5s+kvnsZOwjEJO3DH9eVy+OP6Pg/KFEWdsECFEYTtbg6w==", - "dev": true, - "dependencies": { - "@changesets/errors": "^0.1.4", - "@changesets/get-dependents-graph": "^1.3.6", - "@changesets/logger": "^0.0.5", - "@changesets/types": "^5.2.1", - "@manypkg/get-packages": "^1.1.3", - "fs-extra": "^7.0.1", - "micromatch": "^4.0.2" - } - }, - "node_modules/@changesets/errors": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-0.1.4.tgz", - "integrity": "sha512-HAcqPF7snsUJ/QzkWoKfRfXushHTu+K5KZLJWPb34s4eCZShIf8BFO3fwq6KU8+G7L5KdtN2BzQAXOSXEyiY9Q==", - "dev": true, - "dependencies": { - "extendable-error": "^0.1.5" - } - }, - "node_modules/@changesets/get-dependents-graph": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-1.3.6.tgz", - "integrity": "sha512-Q/sLgBANmkvUm09GgRsAvEtY3p1/5OCzgBE5vX3vgb5CvW0j7CEljocx5oPXeQSNph6FXulJlXV3Re/v3K3P3Q==", - "dev": true, - "dependencies": { - "@changesets/types": "^5.2.1", - "@manypkg/get-packages": "^1.1.3", - "chalk": "^2.1.0", - "fs-extra": "^7.0.1", - "semver": "^7.5.3" - } - }, - "node_modules/@changesets/get-github-info": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@changesets/get-github-info/-/get-github-info-0.6.0.tgz", - "integrity": "sha512-v/TSnFVXI8vzX9/w3DU2Ol+UlTZcu3m0kXTjTT4KlAdwSvwutcByYwyYn9hwerPWfPkT2JfpoX0KgvCEi8Q/SA==", - "dev": true, - "dependencies": { - "dataloader": "^1.4.0", - "node-fetch": "^2.5.0" - } - }, - "node_modules/@changesets/get-release-plan": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-3.0.17.tgz", - "integrity": "sha512-6IwKTubNEgoOZwDontYc2x2cWXfr6IKxP3IhKeK+WjyD6y3M4Gl/jdQvBw+m/5zWILSOCAaGLu2ZF6Q+WiPniw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.20.1", - "@changesets/assemble-release-plan": "^5.2.4", - "@changesets/config": "^2.3.1", - "@changesets/pre": "^1.0.14", - "@changesets/read": "^0.5.9", - "@changesets/types": "^5.2.1", - "@manypkg/get-packages": "^1.1.3" - } - }, - "node_modules/@changesets/get-release-plan/node_modules/@changesets/pre": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-1.0.14.tgz", - "integrity": "sha512-dTsHmxQWEQekHYHbg+M1mDVYFvegDh9j/kySNuDKdylwfMEevTeDouR7IfHNyVodxZXu17sXoJuf2D0vi55FHQ==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.20.1", - "@changesets/errors": "^0.1.4", - "@changesets/types": "^5.2.1", - "@manypkg/get-packages": "^1.1.3", - "fs-extra": "^7.0.1" - } - }, - "node_modules/@changesets/get-release-plan/node_modules/@changesets/read": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/@changesets/read/-/read-0.5.9.tgz", - "integrity": "sha512-T8BJ6JS6j1gfO1HFq50kU3qawYxa4NTbI/ASNVVCBTsKquy2HYwM9r7ZnzkiMe8IEObAJtUVGSrePCOxAK2haQ==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.20.1", - "@changesets/git": "^2.0.0", - "@changesets/logger": "^0.0.5", - "@changesets/parse": "^0.3.16", - "@changesets/types": "^5.2.1", - "chalk": "^2.1.0", - "fs-extra": "^7.0.1", - "p-filter": "^2.1.0" - } - }, - "node_modules/@changesets/get-version-range-type": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.3.2.tgz", - "integrity": "sha512-SVqwYs5pULYjYT4op21F2pVbcrca4qA/bAA3FmFXKMN7Y+HcO8sbZUTx3TAy2VXulP2FACd1aC7f2nTuqSPbqg==", - "dev": true - }, - "node_modules/@changesets/git": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@changesets/git/-/git-2.0.0.tgz", - "integrity": "sha512-enUVEWbiqUTxqSnmesyJGWfzd51PY4H7mH9yUw0hPVpZBJ6tQZFMU3F3mT/t9OJ/GjyiM4770i+sehAn6ymx6A==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.20.1", - "@changesets/errors": "^0.1.4", - "@changesets/types": "^5.2.1", - "@manypkg/get-packages": "^1.1.3", - "is-subdir": "^1.1.1", - "micromatch": "^4.0.2", - "spawndamnit": "^2.0.0" - } - }, - "node_modules/@changesets/logger": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/@changesets/logger/-/logger-0.0.5.tgz", - "integrity": "sha512-gJyZHomu8nASHpaANzc6bkQMO9gU/ib20lqew1rVx753FOxffnCrJlGIeQVxNWCqM+o6OOleCo/ivL8UAO5iFw==", - "dev": true, - "dependencies": { - "chalk": "^2.1.0" - } - }, - "node_modules/@changesets/parse": { - "version": "0.3.16", - "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-0.3.16.tgz", - "integrity": "sha512-127JKNd167ayAuBjUggZBkmDS5fIKsthnr9jr6bdnuUljroiERW7FBTDNnNVyJ4l69PzR57pk6mXQdtJyBCJKg==", - "dev": true, - "dependencies": { - "@changesets/types": "^5.2.1", - "js-yaml": "^3.13.1" - } - }, - "node_modules/@changesets/pre": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-2.0.0.tgz", - "integrity": "sha512-HLTNYX/A4jZxc+Sq8D1AMBsv+1qD6rmmJtjsCJa/9MSRybdxh0mjbTvE6JYZQ/ZiQ0mMlDOlGPXTm9KLTU3jyw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.20.1", - "@changesets/errors": "^0.2.0", - "@changesets/types": "^6.0.0", - "@manypkg/get-packages": "^1.1.3", - "fs-extra": "^7.0.1" - } - }, - "node_modules/@changesets/pre/node_modules/@changesets/errors": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-0.2.0.tgz", - "integrity": "sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==", - "dev": true, - "dependencies": { - "extendable-error": "^0.1.5" - } - }, - "node_modules/@changesets/pre/node_modules/@changesets/types": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@changesets/types/-/types-6.0.0.tgz", - "integrity": "sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==", - "dev": true - }, - "node_modules/@changesets/read": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@changesets/read/-/read-0.6.0.tgz", - "integrity": "sha512-ZypqX8+/im1Fm98K4YcZtmLKgjs1kDQ5zHpc2U1qdtNBmZZfo/IBiG162RoP0CUF05tvp2y4IspH11PLnPxuuw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.20.1", - "@changesets/git": "^3.0.0", - "@changesets/logger": "^0.1.0", - "@changesets/parse": "^0.4.0", - "@changesets/types": "^6.0.0", - "chalk": "^2.1.0", - "fs-extra": "^7.0.1", - "p-filter": "^2.1.0" - } - }, - "node_modules/@changesets/read/node_modules/@changesets/errors": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-0.2.0.tgz", - "integrity": "sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==", - "dev": true, - "dependencies": { - "extendable-error": "^0.1.5" - } - }, - "node_modules/@changesets/read/node_modules/@changesets/git": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@changesets/git/-/git-3.0.0.tgz", - "integrity": "sha512-vvhnZDHe2eiBNRFHEgMiGd2CT+164dfYyrJDhwwxTVD/OW0FUD6G7+4DIx1dNwkwjHyzisxGAU96q0sVNBns0w==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.20.1", - "@changesets/errors": "^0.2.0", - "@changesets/types": "^6.0.0", - "@manypkg/get-packages": "^1.1.3", - "is-subdir": "^1.1.1", - "micromatch": "^4.0.2", - "spawndamnit": "^2.0.0" - } - }, - "node_modules/@changesets/read/node_modules/@changesets/logger": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@changesets/logger/-/logger-0.1.0.tgz", - "integrity": "sha512-pBrJm4CQm9VqFVwWnSqKEfsS2ESnwqwH+xR7jETxIErZcfd1u2zBSqrHbRHR7xjhSgep9x2PSKFKY//FAshA3g==", - "dev": true, - "dependencies": { - "chalk": "^2.1.0" - } - }, - "node_modules/@changesets/read/node_modules/@changesets/parse": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-0.4.0.tgz", - "integrity": "sha512-TS/9KG2CdGXS27S+QxbZXgr8uPsP4yNJYb4BC2/NeFUj80Rni3TeD2qwWmabymxmrLo7JEsytXH1FbpKTbvivw==", - "dev": true, - "dependencies": { - "@changesets/types": "^6.0.0", - "js-yaml": "^3.13.1" - } - }, - "node_modules/@changesets/read/node_modules/@changesets/types": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@changesets/types/-/types-6.0.0.tgz", - "integrity": "sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==", - "dev": true - }, - "node_modules/@changesets/types": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/@changesets/types/-/types-5.2.1.tgz", - "integrity": "sha512-myLfHbVOqaq9UtUKqR/nZA/OY7xFjQMdfgfqeZIBK4d0hA6pgxArvdv8M+6NUzzBsjWLOtvApv8YHr4qM+Kpfg==", - "dev": true - }, - "node_modules/@changesets/write": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@changesets/write/-/write-0.2.3.tgz", - "integrity": "sha512-Dbamr7AIMvslKnNYsLFafaVORx4H0pvCA2MHqgtNCySMe1blImEyAEOzDmcgKAkgz4+uwoLz7demIrX+JBr/Xw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.20.1", - "@changesets/types": "^5.2.1", - "fs-extra": "^7.0.1", - "human-id": "^1.0.2", - "prettier": "^2.7.1" - } - }, - "node_modules/@changesets/write/node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.1.tgz", - "integrity": "sha512-PWiOzLIUAjN/w5K17PoF4n6sKBw0gqLHPhywmYHP4t1VFQQVYeb1yWsJwnMVEMl3tUHME7X/SJPZLmtG7XBDxQ==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/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/@eslint/eslintrc/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/@eslint/js": { - "version": "8.49.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.49.0.tgz", - "integrity": "sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@ethereumjs/rlp": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", - "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", - "dev": true, - "bin": { - "rlp": "bin/rlp" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@ethereumjs/util": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", - "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", - "dev": true, - "dependencies": { - "@ethereumjs/rlp": "^4.0.1", - "ethereum-cryptography": "^2.0.0", - "micro-ftch": "^0.3.1" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@ethereumjs/util/node_modules/ethereum-cryptography": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz", - "integrity": "sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug==", - "dev": true, - "dependencies": { - "@noble/curves": "1.1.0", - "@noble/hashes": "1.3.1", - "@scure/bip32": "1.3.1", - "@scure/bip39": "1.2.1" - } - }, - "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/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/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/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.1", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", - "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", - "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/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/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/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/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/web": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", - "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", - "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/@fastify/busboy": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.0.0.tgz", - "integrity": "sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "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.11.11", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", - "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "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/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/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 - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@manypkg/find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@manypkg/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.5.5", - "@types/node": "^12.7.1", - "find-up": "^4.1.0", - "fs-extra": "^8.1.0" - } - }, - "node_modules/@manypkg/find-root/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/@manypkg/find-root/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/@manypkg/get-packages": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@manypkg/get-packages/-/get-packages-1.1.3.tgz", - "integrity": "sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.5.5", - "@changesets/types": "^4.0.1", - "@manypkg/find-root": "^1.1.0", - "fs-extra": "^8.1.0", - "globby": "^11.0.0", - "read-yaml-file": "^1.1.0" - } - }, - "node_modules/@manypkg/get-packages/node_modules/@changesets/types": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@changesets/types/-/types-4.1.0.tgz", - "integrity": "sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==", - "dev": true - }, - "node_modules/@manypkg/get-packages/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/@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/curves": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", - "integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==", - "dev": true, - "dependencies": { - "@noble/hashes": "1.3.1" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@noble/hashes": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", - "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==", - "dev": true, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@noble/secp256k1": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz", - "integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==", - "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/edr": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr/-/edr-0.3.3.tgz", - "integrity": "sha512-zP+e+3B1nEUx6bW5BPnIzCQbkhmYfdMBJdiVggTqqTfAA82sOkdOG7wsOMcz5qF3fYfx/irNRM1kgc9HVFIbpQ==", - "dev": true, - "engines": { - "node": ">= 18" - }, - "optionalDependencies": { - "@nomicfoundation/edr-darwin-arm64": "0.3.3", - "@nomicfoundation/edr-darwin-x64": "0.3.3", - "@nomicfoundation/edr-linux-arm64-gnu": "0.3.3", - "@nomicfoundation/edr-linux-arm64-musl": "0.3.3", - "@nomicfoundation/edr-linux-x64-gnu": "0.3.3", - "@nomicfoundation/edr-linux-x64-musl": "0.3.3", - "@nomicfoundation/edr-win32-arm64-msvc": "0.3.3", - "@nomicfoundation/edr-win32-ia32-msvc": "0.3.3", - "@nomicfoundation/edr-win32-x64-msvc": "0.3.3" - } - }, - "node_modules/@nomicfoundation/edr-darwin-arm64": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.3.3.tgz", - "integrity": "sha512-E9VGsUD+1Ga4mn/5ooHsMi8JEfhZbKP6CXN/BhJ8kXbIC10NqTD1RuhCKGRtYq4vqH/3Nfq25Xg8E8RWOF4KBQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 18" - } - }, - "node_modules/@nomicfoundation/edr-darwin-x64": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.3.3.tgz", - "integrity": "sha512-vkZXZ1ydPg+Ijb2iyqENA+KCkxGTCUWG5itCSliiA0Li2YE7ujDMGhheEpFp1WVlZadviz0bfk1rZXbCqlirpg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 18" - } - }, - "node_modules/@nomicfoundation/edr-linux-arm64-gnu": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.3.3.tgz", - "integrity": "sha512-gdIg0Yj1qqS9wVuywc5B/+DqKylfUGB6/CQn/shMqwAfsAVAVpchkhy66PR+REEx7fh/GkNctxLlENXPeLzDiA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 18" - } - }, - "node_modules/@nomicfoundation/edr-linux-arm64-musl": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.3.3.tgz", - "integrity": "sha512-AXZ08MFvhNeBZbOBNmz1SJ/DMrMOE2mHEJtaNnsctlxIunjxfrWww4q+WXB34jbr9iaVYYlPsaWe5sueuw6s3Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 18" - } - }, - "node_modules/@nomicfoundation/edr-linux-x64-gnu": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.3.3.tgz", - "integrity": "sha512-xElOs1U+E6lBLtv1mnJ+E8nr2MxZgKiLo8bZAgBboy9odYtmkDVwhMjtsFKSuZbGxFtsSyGRT4cXw3JAbtUDeA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 18" - } - }, - "node_modules/@nomicfoundation/edr-linux-x64-musl": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.3.3.tgz", - "integrity": "sha512-2Fe6gwm1RAGQ/PfMYiaSba2OrFp8zzYWh+am9lYObOFjV9D+A1zhIzfy0UC74glPks5eV8eY4pBPrVR042m2Nw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 18" - } - }, - "node_modules/@nomicfoundation/edr-win32-arm64-msvc": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-win32-arm64-msvc/-/edr-win32-arm64-msvc-0.3.3.tgz", - "integrity": "sha512-8NHyxIsFrl0ufSQ/ErqF2lKIa/gz1gaaa1a2vKkDEqvqCUcPhBTYhA5NHgTPhLETFTnCFr0z+YbctFCyjh4qrA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/edr-win32-ia32-msvc": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-win32-ia32-msvc/-/edr-win32-ia32-msvc-0.3.3.tgz", - "integrity": "sha512-0F6hM0kGia4dQVb/kauho9JcP1ozWisY2/She+ISR5ceuhzmAwQJluM0g+0TYDME0LtxBxiMPq/yPiZMQeq31w==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 18" - } - }, - "node_modules/@nomicfoundation/edr-win32-x64-msvc": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.3.3.tgz", - "integrity": "sha512-d75q1uaMb6z9i+GQZoblbOfFBvlBnWc+5rB13UWRkCOJSnoYwyFWhGJx5GeM59gC7aIblc5VD9qOAhHuvM9N+w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 18" - } - }, - "node_modules/@nomicfoundation/ethereumjs-common": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz", - "integrity": "sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-util": "9.0.4" - } - }, - "node_modules/@nomicfoundation/ethereumjs-rlp": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.4.tgz", - "integrity": "sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw==", - "dev": true, - "bin": { - "rlp": "bin/rlp.cjs" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@nomicfoundation/ethereumjs-tx": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.4.tgz", - "integrity": "sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-common": "4.0.4", - "@nomicfoundation/ethereumjs-rlp": "5.0.4", - "@nomicfoundation/ethereumjs-util": "9.0.4", - "ethereum-cryptography": "0.1.3" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "c-kzg": "^2.1.2" - }, - "peerDependenciesMeta": { - "c-kzg": { - "optional": true - } - } - }, - "node_modules/@nomicfoundation/ethereumjs-util": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.4.tgz", - "integrity": "sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-rlp": "5.0.4", - "ethereum-cryptography": "0.1.3" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "c-kzg": "^2.1.2" - }, - "peerDependenciesMeta": { - "c-kzg": { - "optional": true - } - } - }, - "node_modules/@nomicfoundation/hardhat-chai-matchers": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-2.0.6.tgz", - "integrity": "sha512-Te1Uyo9oJcTCF0Jy9dztaLpshmlpjLf2yPtWXlXuLjMt3RRSmJLm/+rKVTW6gfadAEs12U/it6D0ZRnnRGiICQ==", - "dev": true, - "dependencies": { - "@types/chai-as-promised": "^7.1.3", - "chai-as-promised": "^7.1.1", - "deep-eql": "^4.0.1", - "ordinal": "^1.0.3" - }, - "peerDependencies": { - "@nomicfoundation/hardhat-ethers": "^3.0.0", - "chai": "^4.2.0", - "ethers": "^6.1.0", - "hardhat": "^2.9.4" - } - }, - "node_modules/@nomicfoundation/hardhat-ethers": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.4.tgz", - "integrity": "sha512-k9qbLoY7qn6C6Y1LI0gk2kyHXil2Tauj4kGzQ8pgxYXIGw8lWn8tuuL72E11CrlKaXRUvOgF0EXrv/msPI2SbA==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "lodash.isequal": "^4.5.0" - }, - "peerDependencies": { - "ethers": "^6.1.0", - "hardhat": "^2.0.0" - } - }, - "node_modules/@nomicfoundation/hardhat-network-helpers": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.9.tgz", - "integrity": "sha512-OXWCv0cHpwLUO2u7bFxBna6dQtCC2Gg/aN/KtJLO7gmuuA28vgmVKYFRCDUqrbjujzgfwQ2aKyZ9Y3vSmDqS7Q==", - "dev": true, - "dependencies": { - "ethereumjs-util": "^7.1.4" - }, - "peerDependencies": { - "hardhat": "^2.9.5" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz", - "integrity": "sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg==", - "dev": true, - "engines": { - "node": ">= 12" - }, - "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" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-darwin-arm64": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.1.tgz", - "integrity": "sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-darwin-x64": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.1.tgz", - "integrity": "sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-freebsd-x64": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.1.tgz", - "integrity": "sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.1.tgz", - "integrity": "sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-musl": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.1.tgz", - "integrity": "sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-gnu": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.1.tgz", - "integrity": "sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-musl": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.1.tgz", - "integrity": "sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-win32-arm64-msvc": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.1.tgz", - "integrity": "sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-win32-ia32-msvc": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.1.tgz", - "integrity": "sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-win32-x64-msvc": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.1.tgz", - "integrity": "sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@openzeppelin/docs-utils": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@openzeppelin/docs-utils/-/docs-utils-0.1.5.tgz", - "integrity": "sha512-GfqXArKmdq8rv+hsP+g8uS1VEkvMIzWs31dCONffzmqFwJ+MOsaNQNZNXQnLRgUkzk8i5mTNDjJuxDy+aBZImQ==", - "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/docs-utils/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/@openzeppelin/docs-utils/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/@openzeppelin/docs-utils/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/@openzeppelin/docs-utils/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/@openzeppelin/docs-utils/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/@openzeppelin/docs-utils/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/@openzeppelin/merkle-tree": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@openzeppelin/merkle-tree/-/merkle-tree-1.0.7.tgz", - "integrity": "sha512-i93t0YYv6ZxTCYU3CdO5Q+DXK0JH10A4dCBOMlzYbX+ujTXm+k1lXiEyVqmf94t3sqmv8sm/XT5zTa0+efnPgQ==", - "dev": true, - "dependencies": { - "@ethersproject/abi": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0" - } - }, - "node_modules/@openzeppelin/upgrade-safe-transpiler": { - "version": "0.3.32", - "resolved": "https://registry.npmjs.org/@openzeppelin/upgrade-safe-transpiler/-/upgrade-safe-transpiler-0.3.32.tgz", - "integrity": "sha512-ypgj6MXXcDG0dOuMwENXt0H4atCtCsPgpDgWZYewb2egfUCMpj6d2GO4pcNZgdn1zYsmUHfm5ZA/Nga/8qkdKA==", - "dev": true, - "dependencies": { - "ajv": "^8.0.0", - "compare-versions": "^6.0.0", - "ethereum-cryptography": "^2.0.0", - "lodash": "^4.17.20", - "minimatch": "^9.0.0", - "minimist": "^1.2.5", - "solidity-ast": "^0.4.51" - }, - "bin": { - "upgrade-safe-transpiler": "dist/cli.js" - } - }, - "node_modules/@openzeppelin/upgrade-safe-transpiler/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "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/@openzeppelin/upgrade-safe-transpiler/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/@openzeppelin/upgrade-safe-transpiler/node_modules/ethereum-cryptography": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz", - "integrity": "sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug==", - "dev": true, - "dependencies": { - "@noble/curves": "1.1.0", - "@noble/hashes": "1.3.1", - "@scure/bip32": "1.3.1", - "@scure/bip39": "1.2.1" - } - }, - "node_modules/@openzeppelin/upgrade-safe-transpiler/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/@openzeppelin/upgrade-safe-transpiler/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@openzeppelin/upgrade-safe-transpiler/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/@openzeppelin/upgrades-core": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.29.0.tgz", - "integrity": "sha512-csZvAMNqUJjMDNBPbaXcV9Nlo4oagMD/HkOBHTpYbBTpnmUhwPVHOMv+Rl0RatBdLHuGc6hw88h80k5PWkEeWw==", - "dev": true, - "dependencies": { - "cbor": "^9.0.0", - "chalk": "^4.1.0", - "compare-versions": "^6.0.0", - "debug": "^4.1.1", - "ethereumjs-util": "^7.0.3", - "minimist": "^1.2.7", - "proper-lockfile": "^4.1.1", - "solidity-ast": "^0.4.26" - }, - "bin": { - "openzeppelin-upgrades-core": "dist/cli/cli.js" - } - }, - "node_modules/@openzeppelin/upgrades-core/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/@openzeppelin/upgrades-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/@openzeppelin/upgrades-core/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/@openzeppelin/upgrades-core/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/@openzeppelin/upgrades-core/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/@openzeppelin/upgrades-core/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/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@pnpm/config.env-replace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", - "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", - "dev": true, - "engines": { - "node": ">=12.22.0" - } - }, - "node_modules/@pnpm/network.ca-file": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", - "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", - "dev": true, - "dependencies": { - "graceful-fs": "4.2.10" - }, - "engines": { - "node": ">=12.22.0" - } - }, - "node_modules/@pnpm/network.ca-file/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/@pnpm/npm-conf": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz", - "integrity": "sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==", - "dev": true, - "dependencies": { - "@pnpm/config.env-replace": "^1.1.0", - "@pnpm/network.ca-file": "^1.0.1", - "config-chain": "^1.1.11" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@scure/base": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.6.tgz", - "integrity": "sha512-ok9AWwhcgYuGG3Zfhyqg+zwl+Wn5uE+dwC0NV/2qQkx4dABbb/bx96vWu8NSj+BNjjSjno+JRYRjle1jV08k3g==", - "dev": true, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip32": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.1.tgz", - "integrity": "sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==", - "dev": true, - "dependencies": { - "@noble/curves": "~1.1.0", - "@noble/hashes": "~1.3.1", - "@scure/base": "~1.1.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip39": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz", - "integrity": "sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==", - "dev": true, - "dependencies": { - "@noble/hashes": "~1.3.0", - "@scure/base": "~1.1.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "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": "5.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", - "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", - "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@solidity-parser/parser": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.18.0.tgz", - "integrity": "sha512-yfORGUIPgLck41qyN7nbwJRAx17/jAIXCTanHOJZhB6PJ1iAk/84b/xlsVKFSyNyLXIj0dhppoE0+CRws7wlzA==", - "dev": true - }, - "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/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/@types/bn.js": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.2.tgz", - "integrity": "sha512-dkpZu0szUtn9UXTmw+e0AJFd4D2XAxDnsCLdc05SfqpqzPEBft8eQr8uaFitfo/dUUOZERaLec2hHMG87A4Dxg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/chai": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.6.tgz", - "integrity": "sha512-VOVRLM1mBxIRxydiViqPcKn6MIxZytrbMpd6RJLIWKxUNr3zux8no0Oc7kJx0WAPIitgZ0gkrDS+btlqQpubpw==", - "dev": true - }, - "node_modules/@types/chai-as-promised": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.6.tgz", - "integrity": "sha512-cQLhk8fFarRVZAXUQV1xEnZgMoPxqKojBvRkqPCKPQCzEhpbbSKl1Uu75kDng7k5Ln6LQLUmNBjLlFthCgm1NA==", - "dev": true, - "dependencies": { - "@types/chai": "*" - } - }, - "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.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", - "dev": true - }, - "node_modules/@types/is-ci": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/is-ci/-/is-ci-3.0.0.tgz", - "integrity": "sha512-Q0Op0hdWbYd1iahB+IFNQcWXFq4O0Q5MwQP7uN0souuQ4rPg1vEYcnIOfr1gY+M+6rc8FGoRaBO1mOOvL29sEQ==", - "dev": true, - "dependencies": { - "ci-info": "^3.1.0" - } - }, - "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/minimist": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", - "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", - "dev": true - }, - "node_modules/@types/node": { - "version": "20.9.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.0.tgz", - "integrity": "sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", - "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", - "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/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/@types/semver": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.2.tgz", - "integrity": "sha512-7aqorHYgdNO4DM36stTiGO3DvKoex9TQRwsJU6vMaFGyqpBA1MNZkz+PG3gaNUPpTAOYhT1WR7M1JyA3fbS9Cw==", - "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/abitype": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.0.0.tgz", - "integrity": "sha512-NMeMah//6bJ56H5XRj8QCV4AwuW6hB6zqz2LnhhLdcWVQOsXki6/Pn3APeqxCma62nXIcmZWdu1DlHWS74umVQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/wevm" - }, - "peerDependencies": { - "typescript": ">=5.0.4", - "zod": "^3 >=3.22.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - }, - "zod": { - "optional": true - } - } - }, - "node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", - "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/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/address": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", - "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", - "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/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-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "dev": true, - "dependencies": { - "string-width": "^4.1.0" - } - }, - "node_modules/ansi-align/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/ansi-align/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/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/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": "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/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/antlr4": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.13.1.tgz", - "integrity": "sha512-kiXTspaRYvnIArgE97z5YVVf/cDVQABr3abFRR6mE7yesLMkgu4ujuyV/sgxafQ8wgve0DJQUJ38Z8tkgA2izA==", - "dev": true, - "engines": { - "node": ">=16" - } - }, - "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.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, - "optional": true, - "peer": true - }, - "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-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" - }, - "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.prototype.findlast": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.3.tgz", - "integrity": "sha512-kcBubumjciBg4JKp5KTKtI7ec7tRefPk88yjkWJwaVKYd9QfTaxcsOxoMNKd7iBr447zCfDV0z1kOF47umv42g==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", - "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-array-buffer": "^3.0.2", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", - "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/axios": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", - "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", - "dev": true, - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "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/better-path-resolve": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/better-path-resolve/-/better-path-resolve-1.0.0.tgz", - "integrity": "sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==", - "dev": true, - "dependencies": { - "is-windows": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "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/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/boxen": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", - "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", - "dev": true, - "dependencies": { - "ansi-align": "^3.0.0", - "camelcase": "^6.2.0", - "chalk": "^4.1.0", - "cli-boxes": "^2.2.1", - "string-width": "^4.2.2", - "type-fest": "^0.20.2", - "widest-line": "^3.1.0", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/boxen/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/boxen/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/boxen/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/boxen/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/boxen/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/boxen/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/boxen/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/boxen/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/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.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/breakword": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/breakword/-/breakword-1.0.6.tgz", - "integrity": "sha512-yjxDAYyK/pBvws9H4xKYpLDpYKEH6CzrBPAuXq3x18I+c/2MkVtT3qAr7Oloi6Dss9qNhPVueAAVU1CSeNDIXw==", - "dev": true, - "dependencies": { - "wcwidth": "^1.0.1" - } - }, - "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/brotli-wasm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brotli-wasm/-/brotli-wasm-2.0.1.tgz", - "integrity": "sha512-+3USgYsC7bzb5yU0/p2HnnynZl0ak0E6uoIm4UW4Aby/8s8HFCq6NCfrrf1E9c3O8OCSzq3oYO1tUVqIi61Nww==", - "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/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-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-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.7", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.7.tgz", - "integrity": "sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "peer": 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": "7.0.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", - "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", - "dev": true, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/cacheable-request": { - "version": "10.2.14", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", - "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", - "dev": true, - "dependencies": { - "@types/http-cache-semantics": "^4.0.2", - "get-stream": "^6.0.1", - "http-cache-semantics": "^4.1.1", - "keyv": "^4.5.3", - "mimic-response": "^4.0.0", - "normalize-url": "^8.0.0", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dev": true, - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "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": "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/camelcase-keys": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", - "dev": true, - "dependencies": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/camelcase-keys/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/cbor": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-9.0.1.tgz", - "integrity": "sha512-/TQOWyamDxvVIv+DY9cOLNuABkoyz8K/F3QE56539pGVYohx0+MEA1f4lChFTX79dBTBS7R1PF6ovH7G+VtBfQ==", - "dev": true, - "dependencies": { - "nofilter": "^3.1.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/chai": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.8.tgz", - "integrity": "sha512-vX4YvVVtxlfSZ2VecZgFUTU5qPCYsobVI2O9FmwEXBhDigYGQA6jRXCycIs1yJnnWbZ6/+a2zNIF5DfVCcJBFQ==", - "dev": true, - "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" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chai-as-promised": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", - "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", - "dev": true, - "dependencies": { - "check-error": "^1.0.2" - }, - "peerDependencies": { - "chai": ">= 2.1.2 < 5" - } - }, - "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/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/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/ci-info": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", - "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "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/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-boxes": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "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/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "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/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/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": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/compare-versions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.0.tgz", - "integrity": "sha512-LNZQXhqUvqUTotpZ00qLSaify3b4VFD588aRr8MKFw4CMUr98ytzCW5wDH5qx/DEY5kCDXcbcRuCqL0szEf2tg==", - "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/config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", - "dev": true, - "dependencies": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "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/cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", - "dev": true, - "dependencies": { - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/cosmiconfig/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/cosmiconfig/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/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/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, - "optional": true, - "peer": true - }, - "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/csv": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/csv/-/csv-5.5.3.tgz", - "integrity": "sha512-QTaY0XjjhTQOdguARF0lGKm5/mEq9PD9/VhZZegHDIBq2tQwgNpHc3dneD4mGo2iJs+fTKv5Bp0fZ+BRuY3Z0g==", - "dev": true, - "dependencies": { - "csv-generate": "^3.4.3", - "csv-parse": "^4.16.3", - "csv-stringify": "^5.6.5", - "stream-transform": "^2.1.3" - }, - "engines": { - "node": ">= 0.1.90" - } - }, - "node_modules/csv-generate": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/csv-generate/-/csv-generate-3.4.3.tgz", - "integrity": "sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw==", - "dev": true - }, - "node_modules/csv-parse": { - "version": "4.16.3", - "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-4.16.3.tgz", - "integrity": "sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg==", - "dev": true - }, - "node_modules/csv-stringify": { - "version": "5.6.5", - "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-5.6.5.tgz", - "integrity": "sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A==", - "dev": true - }, - "node_modules/dataloader": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-1.4.0.tgz", - "integrity": "sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==", - "dev": true - }, - "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": "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/decamelize-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", - "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", - "dev": true, - "dependencies": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decamelize-keys/node_modules/map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "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, - "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/defaults": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", - "dev": true, - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "dependencies": { - "define-data-property": "^1.0.1", - "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/detect-indent": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", - "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/detect-port": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", - "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", - "dev": true, - "dependencies": { - "address": "^1.0.1", - "debug": "4" - }, - "bin": { - "detect": "bin/detect-port.js", - "detect-port": "bin/detect-port.js" - } - }, - "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/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/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/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "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": "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/enquirer": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", - "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1", - "strip-ansi": "^6.0.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==", - "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.22.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.2.tgz", - "integrity": "sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.2", - "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.6", - "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.12", - "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.1", - "safe-array-concat": "^1.0.1", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.8", - "string.prototype.trimend": "^1.0.7", - "string.prototype.trimstart": "^1.0.7", - "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.11" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "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/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-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/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": "8.49.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.49.0.tgz", - "integrity": "sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.49.0", - "@humanwhocodes/config-array": "^0.11.11", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-prettier": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz", - "integrity": "sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==", - "dev": true, - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/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/eslint/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/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/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/eslint/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/eslint/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/eslint/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/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/eslint/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/eslint/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/eslint/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/eslint/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/eslint/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/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "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.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "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/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/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/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/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/ethers": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.7.1.tgz", - "integrity": "sha512-qX5kxIFMfg1i+epfgb0xF4WM7IqapIIu50pOJ17aebkxxa4BacW5jFrQRmCJpDEg2ZK2oNtR5QjrQ1WDBF29dA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/ethers-io/" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "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" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/ethers/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/ethers/node_modules/@types/node": { - "version": "18.15.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz", - "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==", - "dev": true - }, - "node_modules/ethers/node_modules/aes-js": { - "version": "4.0.0-beta.5", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", - "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==", - "dev": true - }, - "node_modules/ethers/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/ethers/node_modules/ws": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", - "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": 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/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/extendable-error": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/extendable-error/-/extendable-error-0.1.7.tgz", - "integrity": "sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==", - "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/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.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", - "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.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "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.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "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/find-yarn-workspace-root2": { - "version": "1.2.16", - "resolved": "https://registry.npmjs.org/find-yarn-workspace-root2/-/find-yarn-workspace-root2-1.2.16.tgz", - "integrity": "sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==", - "dev": true, - "dependencies": { - "micromatch": "^4.0.2", - "pkg-dir": "^4.2.0" - } - }, - "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.1.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.0.tgz", - "integrity": "sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==", - "dev": true, - "dependencies": { - "flatted": "^3.2.7", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/flat-cache/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/flat-cache/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/flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", - "dev": true - }, - "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", - "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/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "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/form-data-encoder": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", - "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", - "dev": true, - "engines": { - "node": ">= 14.17" - } - }, - "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/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.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.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "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.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/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/glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", - "dev": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "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": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "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.22.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.22.0.tgz", - "integrity": "sha512-H1Ddc/PbZHTDVJSnj8kWptIRSD6AM3pK+mKytuIVF4uoBV7rshFlhhvA58ceJ5wp3Er58w6zj7bykMpYXt3ETw==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/got": { - "version": "12.6.1", - "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", - "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", - "dev": true, - "dependencies": { - "@sindresorhus/is": "^5.2.0", - "@szmarczak/http-timer": "^5.0.1", - "cacheable-lookup": "^7.0.0", - "cacheable-request": "^10.2.8", - "decompress-response": "^6.0.0", - "form-data-encoder": "^2.1.2", - "get-stream": "^6.0.1", - "http2-wrapper": "^2.1.10", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^3.0.0", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "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/handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.2", - "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/hard-rejection": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/hardhat": { - "version": "2.22.2", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.22.2.tgz", - "integrity": "sha512-0xZ7MdCZ5sJem4MrvpQWLR3R3zGDoHw5lsR+pBFimqwagimIOn3bWuZv69KA+veXClwI1s/zpqgwPwiFrd4Dxw==", - "dev": true, - "dependencies": { - "@ethersproject/abi": "^5.1.2", - "@metamask/eth-sig-util": "^4.0.0", - "@nomicfoundation/edr": "^0.3.1", - "@nomicfoundation/ethereumjs-common": "4.0.4", - "@nomicfoundation/ethereumjs-tx": "5.0.4", - "@nomicfoundation/ethereumjs-util": "9.0.4", - "@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", - "boxen": "^5.1.2", - "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" - }, - "bin": { - "hardhat": "internal/cli/bootstrap.js" - }, - "peerDependencies": { - "ts-node": "*", - "typescript": "*" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - }, - "typescript": { - "optional": true - } - } - }, - "node_modules/hardhat-exposed": { - "version": "0.3.15", - "resolved": "https://registry.npmjs.org/hardhat-exposed/-/hardhat-exposed-0.3.15.tgz", - "integrity": "sha512-jqxErCnSWGYf4vAkLmh3H3u+IuLuCLw/EVeV13z1JKJMJAd/iO+G283n8T124S/Q2BF/BoA2zgzYAlqXgNyKew==", - "dev": true, - "dependencies": { - "micromatch": "^4.0.4", - "solidity-ast": "^0.4.52" - }, - "peerDependencies": { - "hardhat": "^2.3.0" - } - }, - "node_modules/hardhat-gas-reporter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-2.1.0.tgz", - "integrity": "sha512-d/WU/qHhBFnbweAm2fAAjcaaE0M7BKZ4r+/bqcFlfP6um28BXtlv2FrJ6oyQUGSFD0ttbmB7sH4ZFDzkYw5GzA==", - "dev": true, - "dependencies": { - "@ethersproject/abi": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/units": "^5.7.0", - "@solidity-parser/parser": "^0.18.0", - "axios": "^1.6.7", - "brotli-wasm": "^2.0.1", - "chalk": "4.1.2", - "cli-table3": "^0.6.3", - "ethereum-cryptography": "^2.1.3", - "glob": "^10.3.10", - "jsonschema": "^1.4.1", - "lodash": "^4.17.21", - "markdown-table": "2.0.0", - "sha1": "^1.1.1", - "viem": "2.7.14" - }, - "peerDependencies": { - "hardhat": "^2.16.0" - } - }, - "node_modules/hardhat-gas-reporter/node_modules/@noble/curves": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.3.0.tgz", - "integrity": "sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==", - "dev": true, - "dependencies": { - "@noble/hashes": "1.3.3" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/hardhat-gas-reporter/node_modules/@noble/hashes": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", - "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", - "dev": true, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/hardhat-gas-reporter/node_modules/@scure/bip32": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.3.tgz", - "integrity": "sha512-LJaN3HwRbfQK0X1xFSi0Q9amqOgzQnnDngIt+ZlsBC3Bm7/nE7K0kwshZHyaru79yIVRv/e1mQAjZyuZG6jOFQ==", - "dev": true, - "dependencies": { - "@noble/curves": "~1.3.0", - "@noble/hashes": "~1.3.2", - "@scure/base": "~1.1.4" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/hardhat-gas-reporter/node_modules/@scure/bip39": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.2.tgz", - "integrity": "sha512-HYf9TUXG80beW+hGAt3TRM8wU6pQoYur9iNypTROm42dorCGmLnFe3eWjz3gOq6G62H2WRh0FCzAR1PI+29zIA==", - "dev": true, - "dependencies": { - "@noble/hashes": "~1.3.2", - "@scure/base": "~1.1.4" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/hardhat-gas-reporter/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-gas-reporter/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-gas-reporter/node_modules/cli-table3": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.4.tgz", - "integrity": "sha512-Lm3L0p+/npIQWNIiyF/nAn7T5dnOwR3xNTHXYEBFBFVPXzCVNZ5lqEC/1eo/EVfpDsQ1I+TX4ORPQgp+UI0CRw==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "@colors/colors": "1.5.0" - } - }, - "node_modules/hardhat-gas-reporter/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-gas-reporter/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-gas-reporter/node_modules/ethereum-cryptography": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.3.tgz", - "integrity": "sha512-BlwbIL7/P45W8FGW2r7LGuvoEZ+7PWsniMvQ4p5s2xCyw9tmaDlpfsN9HjAucbF+t/qpVHwZUisgfK24TCW8aA==", - "dev": true, - "dependencies": { - "@noble/curves": "1.3.0", - "@noble/hashes": "1.3.3", - "@scure/bip32": "1.3.3", - "@scure/bip39": "1.2.2" - } - }, - "node_modules/hardhat-gas-reporter/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-gas-reporter/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/hardhat-gas-reporter/node_modules/markdown-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", - "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", - "dev": true, - "dependencies": { - "repeat-string": "^1.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/hardhat-gas-reporter/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/hardhat-gas-reporter/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-ignore-warnings": { - "version": "0.2.11", - "resolved": "https://registry.npmjs.org/hardhat-ignore-warnings/-/hardhat-ignore-warnings-0.2.11.tgz", - "integrity": "sha512-+nHnRbP6COFZaXE7HAY7TZNE3au5vHe5dkcnyq0XaP07ikT2fJ3NhFY0vn7Deh4Qbz0Z/9Xpnj2ki6Ktgk61pg==", - "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.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/hardhat/node_modules/@noble/hashes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", - "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] - }, - "node_modules/hardhat/node_modules/@scure/bip32": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", - "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "@noble/hashes": "~1.2.0", - "@noble/secp256k1": "~1.7.0", - "@scure/base": "~1.1.0" - } - }, - "node_modules/hardhat/node_modules/@scure/bip39": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", - "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "@noble/hashes": "~1.2.0", - "@scure/base": "~1.1.0" - } - }, - "node_modules/hardhat/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/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/ethereum-cryptography": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", - "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", - "dev": true, - "dependencies": { - "@noble/hashes": "1.2.0", - "@noble/secp256k1": "1.7.1", - "@scure/bip32": "1.1.5", - "@scure/bip39": "1.1.1" - } - }, - "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/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/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.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "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.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/hardhat/node_modules/undici": { - "version": "5.28.4", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", - "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", - "dev": true, - "dependencies": { - "@fastify/busboy": "^2.0.0" - }, - "engines": { - "node": ">=14.0" - } - }, - "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": "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/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "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/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "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/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/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/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", - "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/http2-wrapper": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", - "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", - "dev": true, - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, - "node_modules/http2-wrapper/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/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/human-id": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/human-id/-/human-id-1.0.2.tgz", - "integrity": "sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==", - "dev": true - }, - "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/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/immutable": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", - "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==", - "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/import-fresh/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/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/internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.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/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/is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" - }, - "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-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-ci": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", - "dev": true, - "dependencies": { - "ci-info": "^3.2.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==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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-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-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-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "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/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-subdir": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-subdir/-/is-subdir-1.2.0.tgz", - "integrity": "sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==", - "dev": true, - "dependencies": { - "better-path-resolve": "1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "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.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", - "dev": true, - "dependencies": { - "which-typed-array": "^1.1.11" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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-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/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "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/isows": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.3.tgz", - "integrity": "sha512-2cKei4vlmg2cxEjm3wVSqn8pcoRF/LX/wpifuuNquFO4SQmPwarClT+SUCA2lt+l581tTeZIPIZuIDo2jWN1fg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wagmi-dev" - } - ], - "peerDependencies": { - "ws": "*" - } - }, - "node_modules/jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", - "dev": true, - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "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/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-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-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/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/keccak": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", - "integrity": "sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==", - "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/keyv": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", - "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", - "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/kleur": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/latest-version": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", - "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", - "dev": true, - "dependencies": { - "package-json": "^8.1.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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/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-yaml-file": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/load-yaml-file/-/load-yaml-file-0.2.0.tgz", - "integrity": "sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.5", - "js-yaml": "^3.13.0", - "pify": "^4.0.1", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "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.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", - "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/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/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/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/log-symbols/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/log-symbols/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/log-symbols/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/log-symbols/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/loupe": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", - "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.0" - } - }, - "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": "11.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.0.tgz", - "integrity": "sha512-Qv32eSV1RSCfhY3fpPE2GNZ8jgM9X7rdAfemLWqTUxwiyIC4jJ6Sy0fZ8H+oLWevO6i4/bizg7c8d8i6bxrzbA==", - "dev": true, - "license": "ISC", - "engines": { - "node": "20 || >=22" - } - }, - "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, - "optional": true, - "peer": true - }, - "node_modules/map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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/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/meow": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-6.1.1.tgz", - "integrity": "sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==", - "dev": true, - "dependencies": { - "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.2.2", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "^4.0.2", - "normalize-package-data": "^2.5.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.13.1", - "yargs-parser": "^18.1.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/meow/node_modules/type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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/micro-ftch": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz", - "integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==", - "dev": true - }, - "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/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-response": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", - "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "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.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minimist-options": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", - "dev": true, - "dependencies": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/mixme": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/mixme/-/mixme-0.5.9.tgz", - "integrity": "sha512-VC5fg6ySUscaWUpI4gxCBTQMH2RdUpNrk+MsbpCYtIvf9SBJdiUey4qE7BXviJsJR4nDQxCZ+3yaYNW3guz/Pw==", - "dev": true, - "engines": { - "node": ">= 8.0.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/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.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", - "dev": true, - "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" - }, - "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/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/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/mocha/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/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/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/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/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/minimatch/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/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-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/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/mocha/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/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/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/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/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/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-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "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.6.1", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.1.tgz", - "integrity": "sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ==", - "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.1.2", - "resolved": "https://registry.npmjs.org/node-interval-tree/-/node-interval-tree-2.1.2.tgz", - "integrity": "sha512-bJ9zMDuNGzVQg1xv0bCPzyEDxHgbrx7/xGj6CDokvizZZmastPsOh0JJLuY8wA5q2SfX1TLNMk7XNV8WxbGxzA==", - "dev": true, - "dependencies": { - "shallowequal": "^1.1.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/nofilter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", - "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", - "dev": true, - "engines": { - "node": ">=12.19" - } - }, - "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.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "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": "8.0.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", - "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==", - "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "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/obliterator": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", - "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==", - "dev": true - }, - "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/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, - "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/ordinal": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ordinal/-/ordinal-1.0.3.tgz", - "integrity": "sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ==", - "dev": true - }, - "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/outdent": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/outdent/-/outdent-0.5.0.tgz", - "integrity": "sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==", - "dev": true - }, - "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-filter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", - "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", - "dev": true, - "dependencies": { - "p-map": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-filter/node_modules/p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "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/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-locate/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-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/package-json": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", - "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", - "dev": true, - "dependencies": { - "got": "^12.1.0", - "registry-auth-token": "^5.0.1", - "registry-url": "^6.0.0", - "semver": "^7.3.7" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/package-json-from-dist": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", - "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", - "dev": true, - "license": "BlueOak-1.0.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-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/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-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-scurry": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", - "dev": true, - "dependencies": { - "lru-cache": "^9.1.1 || ^10.0.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", - "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } - }, - "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/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/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pluralize": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", - "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/preferred-pm": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/preferred-pm/-/preferred-pm-3.1.2.tgz", - "integrity": "sha512-nk7dKrcW8hfCZ4H6klWcdRknBOXWzNQByJ0oJyX97BOupsYD+FzLS4hflgEu/uPUEHZCuRfMxzCBsuWd7OzT8Q==", - "dev": true, - "dependencies": { - "find-up": "^5.0.0", - "find-yarn-workspace-root2": "1.2.16", - "path-exists": "^4.0.0", - "which-pm": "2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/preferred-pm/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/preferred-pm/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/preferred-pm/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/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/prettier": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", - "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", - "dev": true, - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prettier-plugin-solidity": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.1.3.tgz", - "integrity": "sha512-fQ9yucPi2sBbA2U2Xjh6m4isUTJ7S7QLc/XDDsktqqxYfTwdYKJ0EnnywXHwCGAaYbQNK+HIYPL1OemxuMsgeg==", - "dev": true, - "dependencies": { - "@solidity-parser/parser": "^0.16.0", - "semver": "^7.3.8", - "solidity-comments-extractor": "^0.0.7" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "prettier": ">=2.3.0 || >=3.0.0-alpha.0" - } - }, - "node_modules/prettier-plugin-solidity/node_modules/@solidity-parser/parser": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.1.tgz", - "integrity": "sha512-PdhRFNhbTtu3x8Axm0uYpqOy/lODYQK+MlYSgqIsq2L8SFYEHJPHNUiOTAJbDGzNjjr1/n9AcIayxafR/fWmYw==", - "dev": true, - "dependencies": { - "antlr4ts": "^0.5.0-alpha.4" - } - }, - "node_modules/proper-lockfile": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", - "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "retry": "^0.12.0", - "signal-exit": "^3.0.2" - } - }, - "node_modules/proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", - "dev": true - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true - }, - "node_modules/pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", - "dev": true - }, - "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/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": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "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/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "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/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": 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/rc/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/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-yaml-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-yaml-file/-/read-yaml-file-1.1.0.tgz", - "integrity": "sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.5", - "js-yaml": "^3.6.1", - "pify": "^4.0.1", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "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.3", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", - "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", - "dev": true, - "dependencies": { - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dev": true, - "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/redent/node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", - "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==", - "dev": true - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", - "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "set-function-name": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/registry-auth-token": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", - "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", - "dev": true, - "dependencies": { - "@pnpm/npm-conf": "^2.1.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/registry-url": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", - "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", - "dev": true, - "dependencies": { - "rc": "1.2.8" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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/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-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.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/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": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/responselike": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", - "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", - "dev": true, - "dependencies": { - "lowercase-keys": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "dev": true, - "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": "6.0.0", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.0.tgz", - "integrity": "sha512-u+yqhM92LW+89cxUQK0SRyvXYQmyuKHx0jkx4W7KfwLGLqJnQM5031Uv1trE4gB9XEXBM/s6MxKlfW95IidqaA==", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^11.0.0" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/balanced-match": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-3.0.1.tgz", - "integrity": "sha512-vjtV3hiLqYDNRoiAv0zC4QaGAMPomEoq83PRmYIofPswwZurCeWR5LByXm7SyoL0Zh5+2z0+HC7jG8gSZJUh0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 16" - } - }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-4.0.0.tgz", - "integrity": "sha512-l/mOwLWs7BQIgOKrL46dIAbyCKvPV7YJPDspkuc88rHsZRlg3hptUGdU7Trv0VFP4d3xnSGBQrKu5ZvGB7UeIw==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^3.0.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", - "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^4.0.1", - "minimatch": "^10.0.0", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^2.0.0" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/jackspeak": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.1.tgz", - "integrity": "sha512-cub8rahkh0Q/bw1+GxP7aeSe29hHHn2V4m29nnDlvCdlgU+3UGxkZp7Z53jLUdpX3jdTO0nJZUDl3xvbWc2Xog==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.0.tgz", - "integrity": "sha512-S4phymWe5NHWbTV8sAlyNQfkmdhvaoHX43x4yLtJBjw2zJtEuzkihDjV5uKq+D/EoMkjbG6msw3ubbSd1pGkyg==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^4.0.0" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/path-scurry": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", - "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, - "engines": { - "node": "20 || >=22" - }, - "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/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-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/safe-array-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", - "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/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.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "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/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/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-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", - "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", - "dev": true, - "dependencies": { - "define-data-property": "^1.0.1", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "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/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.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "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/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/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/slice-ansi/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/slice-ansi/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/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/smartwrap": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/smartwrap/-/smartwrap-2.0.2.tgz", - "integrity": "sha512-vCsKNQxb7PnCNd2wY1WClWifAc2lwqsG8OaswpJkVJsvMGcnEntdTCDajZCkk93Ay1U3t/9puJmb525Rg5MZBA==", - "dev": true, - "dependencies": { - "array.prototype.flat": "^1.2.3", - "breakword": "^1.0.5", - "grapheme-splitter": "^1.0.4", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1", - "yargs": "^15.1.0" - }, - "bin": { - "smartwrap": "src/terminal-adapter.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/smartwrap/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/smartwrap/node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/smartwrap/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/smartwrap/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/smartwrap/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/smartwrap/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/smartwrap/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/smartwrap/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/smartwrap/node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.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": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/solhint": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/solhint/-/solhint-5.0.0.tgz", - "integrity": "sha512-pSRKkzRsruia6/xa9L5VSyd7dMZkiiTi/aYZcvUQo7KK+S16ojPwIbt2jfjbH5WEJ83grzIIE4WrYQfAxGWh/A==", - "dev": true, - "dependencies": { - "@solidity-parser/parser": "^0.18.0", - "ajv": "^6.12.6", - "antlr4": "^4.13.1-patch-1", - "ast-parents": "^0.0.1", - "chalk": "^4.1.2", - "commander": "^10.0.0", - "cosmiconfig": "^8.0.0", - "fast-diff": "^1.2.0", - "glob": "^8.0.3", - "ignore": "^5.2.4", - "js-yaml": "^4.1.0", - "latest-version": "^7.0.0", - "lodash": "^4.17.21", - "pluralize": "^8.0.0", - "semver": "^7.5.2", - "strip-ansi": "^6.0.1", - "table": "^6.8.1", - "text-table": "^0.2.0" - }, - "bin": { - "solhint": "solhint.js" - }, - "optionalDependencies": { - "prettier": "^2.8.3" - } - }, - "node_modules/solhint-plugin-openzeppelin": { - "resolved": "scripts/solhint-custom", - "link": true - }, - "node_modules/solhint/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/solhint/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/solhint/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/solhint/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/solhint/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/solhint/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/solhint/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "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/solhint/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/solhint/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/solhint/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/solhint/node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "optional": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/solhint/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/solidity-ast": { - "version": "0.4.52", - "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.52.tgz", - "integrity": "sha512-iOya9BSiB9jhM8Vf40n8lGELGzwrUc57rl5BhfNtJ5cvAaMvRcNlHeAMNvqJJyjoUnczqRbHqdivEqK89du3Cw==", - "dev": true, - "dependencies": { - "array.prototype.findlast": "^1.2.2" - } - }, - "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.5", - "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.5.tgz", - "integrity": "sha512-6C6N6OV2O8FQA0FWA95FdzVH+L16HU94iFgg5wAFZ29UpLFkgNI/DRR2HotG1bC0F4gAc/OMs2BJI44Q/DYlKQ==", - "dev": true, - "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": "10.2.0", - "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/@solidity-parser/parser": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.1.tgz", - "integrity": "sha512-PdhRFNhbTtu3x8Axm0uYpqOy/lODYQK+MlYSgqIsq2L8SFYEHJPHNUiOTAJbDGzNjjr1/n9AcIayxafR/fWmYw==", - "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/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/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-docgen": { - "version": "0.6.0-beta.36", - "resolved": "https://registry.npmjs.org/solidity-docgen/-/solidity-docgen-0.6.0-beta.36.tgz", - "integrity": "sha512-f/I5G2iJgU1h0XrrjRD0hHMr7C10u276vYvm//rw1TzFcYQ4xTOyAoi9oNAHRU0JU4mY9eTuxdVc2zahdMuhaQ==", - "dev": true, - "dependencies": { - "handlebars": "^4.7.7", - "solidity-ast": "^0.4.38" - }, - "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/spawndamnit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawndamnit/-/spawndamnit-2.0.0.tgz", - "integrity": "sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA==", - "dev": true, - "dependencies": { - "cross-spawn": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, - "node_modules/spawndamnit/node_modules/cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", - "dev": true, - "dependencies": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "node_modules/spawndamnit/node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "node_modules/spawndamnit/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/spawndamnit/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/spawndamnit/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/spawndamnit/node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", - "dev": true - }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "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.15", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.15.tgz", - "integrity": "sha512-lpT8hSQp9jAKp9mhtBU4Xjon8LPGBvLIuBiSVhMEtmLecTh2mO0tlqrAMp47tBXzMr13NJMQ2lf7RpQGLJ3HsQ==", - "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/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/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/stream-transform": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/stream-transform/-/stream-transform-2.1.3.tgz", - "integrity": "sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ==", - "dev": true, - "dependencies": { - "mixme": "^0.5.1" - } - }, - "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-cjs": { - "name": "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-cjs/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/string.prototype.trim": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", - "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", - "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", - "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/strip-ansi-cjs": { - "name": "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/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-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": "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/table": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", - "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", - "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.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "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/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/term-size": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", - "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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/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-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/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true - }, - "node_modules/trim-newlines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", - "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, - "optional": true, - "peer": true, - "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" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "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, - "optional": true, - "peer": 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==", - "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/tty-table": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/tty-table/-/tty-table-4.2.1.tgz", - "integrity": "sha512-xz0uKo+KakCQ+Dxj1D/tKn2FSyreSYWzdkL/BYhgN6oMW808g8QRMuh1atAV9fjTPbWBjfbkKQpI/5rEcnAc7g==", - "dev": true, - "dependencies": { - "chalk": "^4.1.2", - "csv": "^5.5.3", - "kleur": "^4.1.5", - "smartwrap": "^2.0.2", - "strip-ansi": "^6.0.1", - "wcwidth": "^1.0.1", - "yargs": "^17.7.1" - }, - "bin": { - "tty-table": "adapters/terminal-adapter.js" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/tty-table/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/tty-table/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/tty-table/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/tty-table/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/tty-table/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/tty-table/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/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-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/typed-array-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", - "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", - "dev": true, - "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" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", - "dev": true, - "optional": true, - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/uglify-js": { - "version": "3.17.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", - "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", - "dev": true, - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "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/undici": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.12.0.tgz", - "integrity": "sha512-d87yk8lqSFUYtR5fTFe2frpkMIrUEz+lgoJmhcL+J3StVl+8fj8ytE4lLnJOTPCE12YbumNGzf4LYsQyusdV5g==", - "dev": true, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "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==", - "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/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/utf-8-validate": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", - "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "peer": 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-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/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-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true, - "optional": true, - "peer": 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/viem": { - "version": "2.7.14", - "resolved": "https://registry.npmjs.org/viem/-/viem-2.7.14.tgz", - "integrity": "sha512-5b1KB1gXli02GOQHZIUsRluNUwssl2t4hqdFAzyWPwJ744N83jAOBOjOkrGz7K3qMIv9b0GQt3DoZIErSQTPkQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "dependencies": { - "@adraffy/ens-normalize": "1.10.0", - "@noble/curves": "1.2.0", - "@noble/hashes": "1.3.2", - "@scure/bip32": "1.3.2", - "@scure/bip39": "1.2.1", - "abitype": "1.0.0", - "isows": "1.0.3", - "ws": "8.13.0" - }, - "peerDependencies": { - "typescript": ">=5.0.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/viem/node_modules/@adraffy/ens-normalize": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz", - "integrity": "sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==", - "dev": true - }, - "node_modules/viem/node_modules/@noble/curves": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", - "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", - "dev": true, - "dependencies": { - "@noble/hashes": "1.3.2" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/viem/node_modules/@noble/hashes": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", - "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", - "dev": true, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/viem/node_modules/@scure/bip32": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.2.tgz", - "integrity": "sha512-N1ZhksgwD3OBlwTv3R6KFEcPojl/W4ElJOeCZdi+vuI5QmTFwLq3OFf2zd2ROpKvxFdgZ6hUpb0dx9bVNEwYCA==", - "dev": true, - "dependencies": { - "@noble/curves": "~1.2.0", - "@noble/hashes": "~1.3.2", - "@scure/base": "~1.1.2" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/viem/node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dev": true, - "dependencies": { - "defaults": "^1.0.3" - } - }, - "node_modules/web3-utils": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.2.tgz", - "integrity": "sha512-TdApdzdse5YR+5GCX/b/vQnhhbj1KSAtfrDtRW7YS0kcWp1gkJsN62gw6GzCaNTeXookB7UrLtmDUuMv65qgow==", - "dev": true, - "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" - }, - "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/web3-utils/node_modules/ethereum-cryptography": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz", - "integrity": "sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug==", - "dev": true, - "dependencies": { - "@noble/curves": "1.1.0", - "@noble/hashes": "1.3.1", - "@scure/bip32": "1.3.1", - "@scure/bip39": "1.2.1" - } - }, - "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/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.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true - }, - "node_modules/which-pm": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-pm/-/which-pm-2.0.0.tgz", - "integrity": "sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w==", - "dev": true, - "dependencies": { - "load-yaml-file": "^0.2.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8.15" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", - "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", - "dev": true, - "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" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/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/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "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-cjs": { - "name": "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-cjs/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/wrap-ansi-cjs/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/wrap-ansi-cjs/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/wrap-ansi-cjs/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-cjs/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/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/wrap-ansi/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/wrap-ansi/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/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/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/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/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/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "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" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs-parser/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/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/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/yargs-unparser/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/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/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/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "optional": true, - "peer": 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" - } - }, - "scripts/solhint-custom": { - "name": "solhint-plugin-openzeppelin", - "version": "0.0.0", - "dev": true - } - } -} diff --git a/lib/openzeppelin-contracts/package.json b/lib/openzeppelin-contracts/package.json deleted file mode 100644 index 868a4d3..0000000 --- a/lib/openzeppelin-contracts/package.json +++ /dev/null @@ -1,89 +0,0 @@ -{ - "name": "openzeppelin-solidity", - "description": "Secure Smart Contract library for Solidity", - "version": "5.0.2", - "private": true, - "files": [ - "/contracts/**/*.sol", - "!/contracts/mocks/**/*" - ], - "scripts": { - "compile": "hardhat compile", - "compile:harnesses": "env SRC=./certora/harnesses hardhat compile", - "coverage": "scripts/checks/coverage.sh", - "docs": "npm run prepare-docs && oz-docs", - "docs:watch": "oz-docs watch contracts docs/templates docs/config.js", - "prepare": "git config --local core.hooksPath .githooks", - "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": "prettier --log-level warn --ignore-path .gitignore '**/*.{js,ts}' --check && eslint --ignore-path .gitignore .", - "lint:js:fix": "prettier --log-level warn --ignore-path .gitignore '**/*.{js,ts}' --write && eslint --ignore-path .gitignore . --fix", - "lint:sol": "prettier --log-level warn --ignore-path .gitignore '{contracts,test}/**/*.sol' --check && solhint '{contracts,test}/**/*.sol'", - "lint:sol:fix": "prettier --log-level warn --ignore-path .gitignore '{contracts,test}/**/*.sol' --write", - "clean": "hardhat clean && rimraf build contracts/build", - "prepack": "scripts/prepack.sh", - "generate": "scripts/generate/run.js", - "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 ." - }, - "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": { - "@changesets/changelog-github": "^0.5.0", - "@changesets/cli": "^2.26.0", - "@changesets/pre": "^2.0.0", - "@changesets/read": "^0.6.0", - "@nomicfoundation/hardhat-chai-matchers": "^2.0.6", - "@nomicfoundation/hardhat-ethers": "^3.0.4", - "@nomicfoundation/hardhat-network-helpers": "^1.0.3", - "@openzeppelin/docs-utils": "^0.1.5", - "@openzeppelin/merkle-tree": "^1.0.7", - "@openzeppelin/upgrade-safe-transpiler": "^0.3.32", - "@openzeppelin/upgrades-core": "^1.20.6", - "chai": "^4.2.0", - "eslint": "^8.30.0", - "eslint-config-prettier": "^9.0.0", - "ethers": "^6.7.1", - "glob": "^10.3.5", - "graphlib": "^2.1.8", - "hardhat": "^2.22.2", - "hardhat-exposed": "^0.3.15", - "hardhat-gas-reporter": "^2.0.0", - "hardhat-ignore-warnings": "^0.2.11", - "lodash.startcase": "^4.4.0", - "micromatch": "^4.0.2", - "p-limit": "^3.1.0", - "prettier": "^3.0.0", - "prettier-plugin-solidity": "^1.1.0", - "rimraf": "^6.0.0", - "semver": "^7.3.5", - "solhint": "^5.0.0", - "solhint-plugin-openzeppelin": "file:scripts/solhint-custom", - "solidity-ast": "^0.4.50", - "solidity-coverage": "^0.8.5", - "solidity-docgen": "^0.6.0-beta.29", - "undici": "^6.11.1", - "yargs": "^17.0.0" - } -} diff --git a/lib/openzeppelin-contracts/remappings.txt b/lib/openzeppelin-contracts/remappings.txt deleted file mode 100644 index 304d138..0000000 --- a/lib/openzeppelin-contracts/remappings.txt +++ /dev/null @@ -1 +0,0 @@ -@openzeppelin/contracts/=contracts/ diff --git a/lib/openzeppelin-contracts/renovate.json b/lib/openzeppelin-contracts/renovate.json deleted file mode 100644 index c0b97d8..0000000 --- a/lib/openzeppelin-contracts/renovate.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "extends": ["github>OpenZeppelin/configs"], - "labels": ["ignore-changeset"] -} diff --git a/lib/openzeppelin-contracts/scripts/checks/compare-layout.js b/lib/openzeppelin-contracts/scripts/checks/compare-layout.js deleted file mode 100644 index 64ff439..0000000 --- a/lib/openzeppelin-contracts/scripts/checks/compare-layout.js +++ /dev/null @@ -1,20 +0,0 @@ -const fs = require('fs'); -const { getStorageUpgradeReport } = require('@openzeppelin/upgrades-core/dist/storage'); - -const { ref, head } = require('yargs').argv; - -const oldLayout = JSON.parse(fs.readFileSync(ref)); -const newLayout = JSON.parse(fs.readFileSync(head)); - -for (const name in oldLayout) { - if (name in newLayout) { - const report = getStorageUpgradeReport(oldLayout[name], newLayout[name], {}); - if (!report.ok) { - console.log(`Storage layout incompatibility found in ${name}:`); - console.log(report.explain()); - process.exitCode = 1; - } - } else { - console.log(`WARNING: ${name} is missing from the current branch`); - } -} diff --git a/lib/openzeppelin-contracts/scripts/checks/compareGasReports.js b/lib/openzeppelin-contracts/scripts/checks/compareGasReports.js deleted file mode 100755 index 2c7b4dc..0000000 --- a/lib/openzeppelin-contracts/scripts/checks/compareGasReports.js +++ /dev/null @@ -1,247 +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', - }, - hideEqual: { - type: 'boolean', - default: true, - }, - strictTesting: { - type: 'boolean', - default: false, - }, - }); - -// 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, strictTesting: false }) { - if (JSON.stringify(update.options?.solcInfo) !== JSON.stringify(ref.options?.solcInfo)) { - console.warn('WARNING: Reports produced with non matching metadata'); - } - - // gasReporter 1.0.0 uses ".info", but 2.0.0 uses ".data" - const updateInfo = update.info ?? update.data; - const refInfo = ref.info ?? ref.data; - - const deployments = updateInfo.deployments - .map(contract => - Object.assign(contract, { previousVersion: refInfo.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(updateInfo.methods) - .filter(key => refInfo.methods[key]) - .filter(key => updateInfo.methods[key].numberOfCalls > 0) - .filter( - key => !opts.strictTesting || updateInfo.methods[key].numberOfCalls === refInfo.methods[key].numberOfCalls, - ) - .map(key => ({ - contract: refInfo.methods[key].contract, - method: refInfo.methods[key].fnSig, - min: variation(...[updateInfo, refInfo].map(x => Math.min(...x.methods[key].gasData)), BASE_TX_COST), - max: variation(...[updateInfo, refInfo].map(x => Math.max(...x.methods[key].gasData)), BASE_TX_COST), - avg: variation(...[updateInfo, refInfo].map(x => Math.round(average(...x.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]), argv); - -switch (argv.style) { - case 'markdown': - console.log(formatCmpMarkdown(report)); - break; - case 'shell': - default: - console.log(formatCmpShell(report)); - break; -} diff --git a/lib/openzeppelin-contracts/scripts/checks/coverage.sh b/lib/openzeppelin-contracts/scripts/checks/coverage.sh deleted file mode 100755 index a591069..0000000 --- a/lib/openzeppelin-contracts/scripts/checks/coverage.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -export COVERAGE=true -export FOUNDRY_FUZZ_RUNS=10 - -# Hardhat coverage -hardhat coverage - -if [ "${CI:-"false"}" == "true" ]; then - # Foundry coverage - forge coverage --report lcov --ir-minimum - # Remove zero hits - sed -i '/,0/d' lcov.info -fi - -# Reports are then uploaded to Codecov automatically by workflow, and merged. diff --git a/lib/openzeppelin-contracts/scripts/checks/extract-layout.js b/lib/openzeppelin-contracts/scripts/checks/extract-layout.js deleted file mode 100644 index d0b9965..0000000 --- a/lib/openzeppelin-contracts/scripts/checks/extract-layout.js +++ /dev/null @@ -1,38 +0,0 @@ -const fs = require('fs'); -const { findAll, astDereferencer, srcDecoder } = require('solidity-ast/utils'); -const { extractStorageLayout } = require('@openzeppelin/upgrades-core/dist/storage/extract'); - -const { _ } = require('yargs').argv; - -const skipPath = ['contracts/mocks/', 'contracts-exposed/']; -const skipKind = ['interface', 'library']; - -function extractLayouts(path) { - const layout = {}; - const { input, output } = JSON.parse(fs.readFileSync(path)); - - const decoder = srcDecoder(input, output); - const deref = astDereferencer(output); - - for (const src in output.contracts) { - if (skipPath.some(prefix => src.startsWith(prefix))) { - continue; - } - - for (const contractDef of findAll('ContractDefinition', output.sources[src].ast)) { - if (skipKind.includes(contractDef.contractKind)) { - continue; - } - - layout[contractDef.name] = extractStorageLayout( - contractDef, - decoder, - deref, - output.contracts[src][contractDef.name].storageLayout, - ); - } - } - return layout; -} - -console.log(JSON.stringify(Object.assign(..._.map(extractLayouts)))); diff --git a/lib/openzeppelin-contracts/scripts/checks/generation.sh b/lib/openzeppelin-contracts/scripts/checks/generation.sh deleted file mode 100755 index 00d609f..0000000 --- a/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/openzeppelin-contracts/scripts/checks/inheritance-ordering.js b/lib/openzeppelin-contracts/scripts/checks/inheritance-ordering.js deleted file mode 100755 index 72aa37e..0000000 --- a/lib/openzeppelin-contracts/scripts/checks/inheritance-ordering.js +++ /dev/null @@ -1,54 +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 (['contracts-exposed/', 'contracts/mocks/'].some(pattern => source.startsWith(pattern))) { - 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/openzeppelin-contracts/scripts/gen-nav.js b/lib/openzeppelin-contracts/scripts/gen-nav.js deleted file mode 100644 index de3d0da..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/scripts/generate/format-lines.js b/lib/openzeppelin-contracts/scripts/generate/format-lines.js deleted file mode 100644 index fa3d6b1..0000000 --- a/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/openzeppelin-contracts/scripts/generate/run.js b/lib/openzeppelin-contracts/scripts/generate/run.js deleted file mode 100755 index b3215ad..0000000 --- a/lib/openzeppelin-contracts/scripts/generate/run.js +++ /dev/null @@ -1,56 +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; - } -} - -function generateFromTemplate(file, template, outputPrefix = '') { - const script = path.relative(path.join(__dirname, '../..'), __filename); - const input = path.join(path.dirname(script), template); - const output = path.join(outputPrefix, file); - const version = getVersion(output); - const content = format( - '// SPDX-License-Identifier: MIT', - ...(version ? [version + ` (${file})`] : []), - `// This file was procedurally generated from ${input}.`, - '', - require(template).trimEnd(), - ); - - fs.writeFileSync(output, content); - // cp.execFileSync('prettier', ['--write', output]); -} - -// Contracts -for (const [file, template] of Object.entries({ - 'utils/cryptography/MerkleProof.sol': './templates/MerkleProof.js', - 'utils/math/SafeCast.sol': './templates/SafeCast.js', - 'utils/structs/EnumerableSet.sol': './templates/EnumerableSet.js', - 'utils/structs/EnumerableMap.sol': './templates/EnumerableMap.js', - 'utils/structs/Checkpoints.sol': './templates/Checkpoints.js', - 'utils/SlotDerivation.sol': './templates/SlotDerivation.js', - 'utils/StorageSlot.sol': './templates/StorageSlot.js', - 'utils/Arrays.sol': './templates/Arrays.js', - 'utils/Packing.sol': './templates/Packing.js', - 'mocks/StorageSlotMock.sol': './templates/StorageSlotMock.js', -})) { - generateFromTemplate(file, template, './contracts/'); -} - -// Tests -for (const [file, template] of Object.entries({ - 'utils/structs/Checkpoints.t.sol': './templates/Checkpoints.t.js', - 'utils/Packing.t.sol': './templates/Packing.t.js', - 'utils/SlotDerivation.t.sol': './templates/SlotDerivation.t.js', -})) { - generateFromTemplate(file, template, './test/'); -} diff --git a/lib/openzeppelin-contracts/scripts/generate/templates/Arrays.js b/lib/openzeppelin-contracts/scripts/generate/templates/Arrays.js deleted file mode 100644 index 30a6e06..0000000 --- a/lib/openzeppelin-contracts/scripts/generate/templates/Arrays.js +++ /dev/null @@ -1,392 +0,0 @@ -const format = require('../format-lines'); -const { capitalize } = require('../../helpers'); -const { TYPES } = require('./Arrays.opts'); - -const header = `\ -pragma solidity ^0.8.20; - -import {SlotDerivation} from "./SlotDerivation.sol"; -import {StorageSlot} from "./StorageSlot.sol"; -import {Math} from "./math/Math.sol"; - -/** - * @dev Collection of functions related to array types. - */ -`; - -const sort = type => `\ -/** - * @dev Sort an array of ${type} (in memory) following the provided comparator function. - * - * This function does the sorting "in place", meaning that it overrides the input. The object is returned for - * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array. - * - * NOTE: this function's cost is \`O(n · log(n))\` in average and \`O(n²)\` in the worst case, with n the length of the - * array. Using it in view functions that are executed through \`eth_call\` is safe, but one should be very careful - * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may - * consume more gas than is available in a block, leading to potential DoS. - */ -function sort( - ${type}[] memory array, - function(${type}, ${type}) pure returns (bool) comp -) internal pure returns (${type}[] memory) { - ${ - type === 'bytes32' - ? '_quickSort(_begin(array), _end(array), comp);' - : 'sort(_castToBytes32Array(array), _castToBytes32Comp(comp));' - } - return array; -} - -/** - * @dev Variant of {sort} that sorts an array of ${type} in increasing order. - */ -function sort(${type}[] memory array) internal pure returns (${type}[] memory) { - ${type === 'bytes32' ? 'sort(array, _defaultComp);' : 'sort(_castToBytes32Array(array), _defaultComp);'} - return array; -} -`; - -const quickSort = `\ -/** - * @dev Performs a quick sort of a segment of memory. The segment sorted starts at \`begin\` (inclusive), and stops - * at end (exclusive). Sorting follows the \`comp\` comparator. - * - * Invariant: \`begin <= end\`. This is the case when initially called by {sort} and is preserved in subcalls. - * - * IMPORTANT: Memory locations between \`begin\` and \`end\` are not validated/zeroed. This function should - * be used only if the limits are within a memory array. - */ -function _quickSort(uint256 begin, uint256 end, function(bytes32, bytes32) pure returns (bool) comp) private pure { - unchecked { - if (end - begin < 0x40) return; - - // Use first element as pivot - bytes32 pivot = _mload(begin); - // Position where the pivot should be at the end of the loop - uint256 pos = begin; - - for (uint256 it = begin + 0x20; it < end; it += 0x20) { - if (comp(_mload(it), pivot)) { - // If the value stored at the iterator's position comes before the pivot, we increment the - // position of the pivot and move the value there. - pos += 0x20; - _swap(pos, it); - } - } - - _swap(begin, pos); // Swap pivot into place - _quickSort(begin, pos, comp); // Sort the left side of the pivot - _quickSort(pos + 0x20, end, comp); // Sort the right side of the pivot - } -} - -/** - * @dev Pointer to the memory location of the first element of \`array\`. - */ -function _begin(bytes32[] memory array) private pure returns (uint256 ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr := add(array, 0x20) - } -} - -/** - * @dev Pointer to the memory location of the first memory word (32bytes) after \`array\`. This is the memory word - * that comes just after the last element of the array. - */ -function _end(bytes32[] memory array) private pure returns (uint256 ptr) { - unchecked { - return _begin(array) + array.length * 0x20; - } -} - -/** - * @dev Load memory word (as a bytes32) at location \`ptr\`. - */ -function _mload(uint256 ptr) private pure returns (bytes32 value) { - assembly { - value := mload(ptr) - } -} - -/** - * @dev Swaps the elements memory location \`ptr1\` and \`ptr2\`. - */ -function _swap(uint256 ptr1, uint256 ptr2) private pure { - assembly { - let value1 := mload(ptr1) - let value2 := mload(ptr2) - mstore(ptr1, value2) - mstore(ptr2, value1) - } -} -`; - -const defaultComparator = `\ -/// @dev Comparator for sorting arrays in increasing order. -function _defaultComp(bytes32 a, bytes32 b) private pure returns (bool) { - return a < b; -} -`; - -const castArray = type => `\ -/// @dev Helper: low level cast ${type} memory array to uint256 memory array -function _castToBytes32Array(${type}[] memory input) private pure returns (bytes32[] memory output) { - assembly { - output := input - } -} -`; - -const castComparator = type => `\ -/// @dev Helper: low level cast ${type} comp function to bytes32 comp function -function _castToBytes32Comp( - function(${type}, ${type}) pure returns (bool) input -) private pure returns (function(bytes32, bytes32) pure returns (bool) output) { - assembly { - output := input - } -} -`; - -const search = `\ -/** - * @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). - * - * NOTE: The \`array\` is expected to be sorted in ascending order, and to - * contain no repeated elements. - * - * IMPORTANT: Deprecated. This implementation behaves as {lowerBound} but lacks - * support for repeated elements in the array. The {lowerBound} function should - * be used instead. - */ -function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) { - uint256 low = 0; - uint256 high = array.length; - - if (high == 0) { - return 0; - } - - 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 towards zero (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 Searches an \`array\` sorted in ascending order and returns the first - * index that contains a value greater or equal than \`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). - * - * See C++'s https://en.cppreference.com/w/cpp/algorithm/lower_bound[lower_bound]. - */ -function lowerBound(uint256[] storage array, uint256 element) internal view returns (uint256) { - uint256 low = 0; - uint256 high = array.length; - - if (high == 0) { - return 0; - } - - 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 towards zero (it does integer division with truncation). - if (unsafeAccess(array, mid).value < element) { - // this cannot overflow because mid < high - unchecked { - low = mid + 1; - } - } else { - high = mid; - } - } - - return low; -} - -/** - * @dev Searches an \`array\` sorted in ascending order and returns the first - * index that contains a value strictly greater than \`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). - * - * See C++'s https://en.cppreference.com/w/cpp/algorithm/upper_bound[upper_bound]. - */ -function upperBound(uint256[] storage array, uint256 element) internal view returns (uint256) { - uint256 low = 0; - uint256 high = array.length; - - if (high == 0) { - return 0; - } - - 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 towards zero (it does integer division with truncation). - if (unsafeAccess(array, mid).value > element) { - high = mid; - } else { - // this cannot overflow because mid < high - unchecked { - low = mid + 1; - } - } - } - - return low; -} - -/** - * @dev Same as {lowerBound}, but with an array in memory. - */ -function lowerBoundMemory(uint256[] memory array, uint256 element) internal pure returns (uint256) { - uint256 low = 0; - uint256 high = array.length; - - if (high == 0) { - return 0; - } - - 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 towards zero (it does integer division with truncation). - if (unsafeMemoryAccess(array, mid) < element) { - // this cannot overflow because mid < high - unchecked { - low = mid + 1; - } - } else { - high = mid; - } - } - - return low; -} - -/** - * @dev Same as {upperBound}, but with an array in memory. - */ -function upperBoundMemory(uint256[] memory array, uint256 element) internal pure returns (uint256) { - uint256 low = 0; - uint256 high = array.length; - - if (high == 0) { - return 0; - } - - 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 towards zero (it does integer division with truncation). - if (unsafeMemoryAccess(array, mid) > element) { - high = mid; - } else { - // this cannot overflow because mid < high - unchecked { - low = mid + 1; - } - } - } - - return low; -} -`; - -const unsafeAccessStorage = type => `\ -/** - * @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(${type}[] storage arr, uint256 pos) internal pure returns (StorageSlot.${capitalize( - type, -)}Slot storage) { - bytes32 slot; - /// @solidity memory-safe-assembly - assembly { - slot := arr.slot - } - return slot.deriveArray().offset(pos).get${capitalize(type)}Slot(); -} -`; - -const unsafeAccessMemory = type => `\ -/** - * @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 unsafeMemoryAccess(${type}[] memory arr, uint256 pos) internal pure returns (${type} res) { - assembly { - res := mload(add(add(arr, 0x20), mul(pos, 0x20))) - } -} -`; - -const unsafeSetLength = type => `\ -/** - * @dev Helper to set the length of an dynamic array. Directly writing to \`.length\` is forbidden. - * - * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased. - */ -function unsafeSetLength(${type}[] storage array, uint256 len) internal { - /// @solidity memory-safe-assembly - assembly { - sstore(array.slot, len) - } -} -`; - -// GENERATE -module.exports = format( - header.trimEnd(), - 'library Arrays {', - format( - [].concat( - 'using SlotDerivation for bytes32;', - 'using StorageSlot for bytes32;', - '', - // sorting, comparator, helpers and internal - sort('bytes32'), - TYPES.filter(type => type !== 'bytes32').map(sort), - quickSort, - defaultComparator, - TYPES.filter(type => type !== 'bytes32').map(castArray), - TYPES.filter(type => type !== 'bytes32').map(castComparator), - // lookup - search, - // unsafe (direct) storage and memory access - TYPES.map(unsafeAccessStorage), - TYPES.map(unsafeAccessMemory), - TYPES.map(unsafeSetLength), - ), - ).trimEnd(), - '}', -); diff --git a/lib/openzeppelin-contracts/scripts/generate/templates/Arrays.opts.js b/lib/openzeppelin-contracts/scripts/generate/templates/Arrays.opts.js deleted file mode 100644 index 67f3299..0000000 --- a/lib/openzeppelin-contracts/scripts/generate/templates/Arrays.opts.js +++ /dev/null @@ -1,3 +0,0 @@ -const TYPES = ['address', 'bytes32', 'uint256']; - -module.exports = { TYPES }; diff --git a/lib/openzeppelin-contracts/scripts/generate/templates/Checkpoints.js b/lib/openzeppelin-contracts/scripts/generate/templates/Checkpoints.js deleted file mode 100644 index 2291bab..0000000 --- a/lib/openzeppelin-contracts/scripts/generate/templates/Checkpoints.js +++ /dev/null @@ -1,235 +0,0 @@ -const format = require('../format-lines'); -const { OPTS } = require('./Checkpoints.opts'); - -// TEMPLATE -const header = `\ -pragma solidity ^0.8.20; - -import {Math} from "../math/Math.sol"; - -/** - * @dev This library defines the \`Trace*\` 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.Trace*\` in your contract, and store a new - * checkpoint for the current transaction block using the {push} function. - */ -`; - -const errors = `\ -/** - * @dev A value was attempted to be inserted on a past checkpoint. - */ -error CheckpointUnorderedInsertion(); -`; - -const template = opts => `\ -struct ${opts.historyTypeName} { - ${opts.checkpointTypeName}[] ${opts.checkpointFieldName}; -} - -struct ${opts.checkpointTypeName} { - ${opts.keyTypeName} ${opts.keyFieldName}; - ${opts.valueTypeName} ${opts.valueFieldName}; -} - -/** - * @dev Pushes a (\`key\`, \`value\`) pair into a ${opts.historyTypeName} so that it is stored as the checkpoint. - * - * Returns previous value and new value. - * - * IMPORTANT: Never accept \`key\` as a user input, since an arbitrary \`type(${opts.keyTypeName}).max\` key set will disable the - * library. - */ -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 first (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 last (most recent) checkpoint with key lower or equal than the search key, or zero - * if there is none. - */ -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}; -} - -/** - * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero - * if there is none. - * - * NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high - * keys). - */ -function upperLookupRecent(${opts.historyTypeName} storage self, ${opts.keyTypeName} key) internal view returns (${opts.valueTypeName}) { - 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)._key) { - 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 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} storage 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 Returns checkpoint at given position. - */ -function at(${opts.historyTypeName} storage self, uint32 pos) internal view returns (${opts.checkpointTypeName} memory) { - return self.${opts.checkpointFieldName}[pos]; -} - -/** - * @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) { - ${opts.checkpointTypeName} storage last = _unsafeAccess(self, pos - 1); - ${opts.keyTypeName} lastKey = last.${opts.keyFieldName}; - ${opts.valueTypeName} lastValue = last.${opts.valueFieldName}; - - // Checkpoint keys must be non-decreasing. - if (lastKey > key) { - revert CheckpointUnorderedInsertion(); - } - - // Update or push new checkpoint - if (lastKey == key) { - _unsafeAccess(self, pos - 1).${opts.valueFieldName} = value; - } else { - self.push(${opts.checkpointTypeName}({${opts.keyFieldName}: key, ${opts.valueFieldName}: value})); - } - return (lastValue, value); - } else { - self.push(${opts.checkpointTypeName}({${opts.keyFieldName}: key, ${opts.valueFieldName}: value})); - return (0, value); - } -} - -/** - * @dev Return the index of the last (most recent) checkpoint with key lower 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 _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 first (oldest) checkpoint with 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 */ - -// GENERATE -module.exports = format( - header.trimEnd(), - 'library Checkpoints {', - format( - [].concat( - errors, - OPTS.map(opts => template(opts)), - ), - ).trimEnd(), - '}', -); diff --git a/lib/openzeppelin-contracts/scripts/generate/templates/Checkpoints.opts.js b/lib/openzeppelin-contracts/scripts/generate/templates/Checkpoints.opts.js deleted file mode 100644 index 08b7b91..0000000 --- a/lib/openzeppelin-contracts/scripts/generate/templates/Checkpoints.opts.js +++ /dev/null @@ -1,17 +0,0 @@ -// OPTIONS -const VALUE_SIZES = [224, 208, 160]; - -const defaultOpts = size => ({ - historyTypeName: `Trace${size}`, - checkpointTypeName: `Checkpoint${size}`, - checkpointFieldName: '_checkpoints', - keyTypeName: `uint${256 - size}`, - keyFieldName: '_key', - valueTypeName: `uint${size}`, - valueFieldName: '_value', -}); - -module.exports = { - VALUE_SIZES, - OPTS: VALUE_SIZES.map(size => defaultOpts(size)), -}; diff --git a/lib/openzeppelin-contracts/scripts/generate/templates/Checkpoints.t.js b/lib/openzeppelin-contracts/scripts/generate/templates/Checkpoints.t.js deleted file mode 100644 index dd564e5..0000000 --- a/lib/openzeppelin-contracts/scripts/generate/templates/Checkpoints.t.js +++ /dev/null @@ -1,138 +0,0 @@ -const format = require('../format-lines'); -const { capitalize } = require('../../helpers'); -const { OPTS } = require('./Checkpoints.opts.js'); - -// TEMPLATE -const header = `\ -pragma solidity ^0.8.20; - -import {Test} from "forge-std/Test.sol"; -import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; -import {Checkpoints} from "@openzeppelin/contracts/utils/structs/Checkpoints.sol"; -`; - -/* eslint-disable max-len */ -const template = opts => `\ -using Checkpoints for Checkpoints.${opts.historyTypeName}; - -// Maximum gap between keys used during the fuzzing tests: the \`_prepareKeys\` function with make sure that -// key#n+1 is in the [key#n, key#n + _KEY_MAX_GAP] range. -uint8 internal constant _KEY_MAX_GAP = 64; - -Checkpoints.${opts.historyTypeName} internal _ckpts; - -// helpers -function _bound${capitalize(opts.keyTypeName)}(${opts.keyTypeName} x, ${opts.keyTypeName} min, ${ - opts.keyTypeName -} max) internal pure returns (${opts.keyTypeName}) { - return SafeCast.to${capitalize(opts.keyTypeName)}(bound(uint256(x), uint256(min), uint256(max))); -} - -function _prepareKeys(${opts.keyTypeName}[] memory keys, ${opts.keyTypeName} maxSpread) internal pure { - ${opts.keyTypeName} lastKey = 0; - for (uint256 i = 0; i < keys.length; ++i) { - ${opts.keyTypeName} key = _bound${capitalize(opts.keyTypeName)}(keys[i], lastKey, lastKey + maxSpread); - keys[i] = key; - lastKey = key; - } -} - -function _assertLatestCheckpoint(bool exist, ${opts.keyTypeName} key, ${opts.valueTypeName} value) internal { - (bool _exist, ${opts.keyTypeName} _key, ${opts.valueTypeName} _value) = _ckpts.latestCheckpoint(); - assertEq(_exist, exist); - assertEq(_key, key); - assertEq(_value, value); -} - -// tests -function testPush(${opts.keyTypeName}[] memory keys, ${opts.valueTypeName}[] memory values, ${ - opts.keyTypeName -} pastKey) public { - vm.assume(values.length > 0 && values.length <= keys.length); - _prepareKeys(keys, _KEY_MAX_GAP); - - // initial state - assertEq(_ckpts.length(), 0); - assertEq(_ckpts.latest(), 0); - _assertLatestCheckpoint(false, 0, 0); - - uint256 duplicates = 0; - for (uint256 i = 0; i < keys.length; ++i) { - ${opts.keyTypeName} key = keys[i]; - ${opts.valueTypeName} value = values[i % values.length]; - if (i > 0 && key == keys[i - 1]) ++duplicates; - - // push - _ckpts.push(key, value); - - // check length & latest - assertEq(_ckpts.length(), i + 1 - duplicates); - assertEq(_ckpts.latest(), value); - _assertLatestCheckpoint(true, key, value); - } - - if (keys.length > 0) { - ${opts.keyTypeName} lastKey = keys[keys.length - 1]; - if (lastKey > 0) { - pastKey = _bound${capitalize(opts.keyTypeName)}(pastKey, 0, lastKey - 1); - - vm.expectRevert(); - this.push(pastKey, values[keys.length % values.length]); - } - } -} - -// used to test reverts -function push(${opts.keyTypeName} key, ${opts.valueTypeName} value) external { - _ckpts.push(key, value); -} - -function testLookup(${opts.keyTypeName}[] memory keys, ${opts.valueTypeName}[] memory values, ${ - opts.keyTypeName -} lookup) public { - vm.assume(values.length > 0 && values.length <= keys.length); - _prepareKeys(keys, _KEY_MAX_GAP); - - ${opts.keyTypeName} lastKey = keys.length == 0 ? 0 : keys[keys.length - 1]; - lookup = _bound${capitalize(opts.keyTypeName)}(lookup, 0, lastKey + _KEY_MAX_GAP); - - ${opts.valueTypeName} upper = 0; - ${opts.valueTypeName} lower = 0; - ${opts.keyTypeName} lowerKey = type(${opts.keyTypeName}).max; - for (uint256 i = 0; i < keys.length; ++i) { - ${opts.keyTypeName} key = keys[i]; - ${opts.valueTypeName} value = values[i % values.length]; - - // push - _ckpts.push(key, value); - - // track expected result of lookups - if (key <= lookup) { - upper = value; - } - // find the first key that is not smaller than the lookup key - if (key >= lookup && (i == 0 || keys[i - 1] < lookup)) { - lowerKey = key; - } - if (key == lowerKey) { - lower = value; - } - } - - // check lookup - assertEq(_ckpts.lowerLookup(lookup), lower); - assertEq(_ckpts.upperLookup(lookup), upper); - assertEq(_ckpts.upperLookupRecent(lookup), upper); -} -`; - -// GENERATE -module.exports = format( - header, - ...OPTS.flatMap(opts => [ - `contract Checkpoints${opts.historyTypeName}Test is Test {`, - [template(opts).trimEnd()], - '}', - '', - ]), -); diff --git a/lib/openzeppelin-contracts/scripts/generate/templates/EnumerableMap.js b/lib/openzeppelin-contracts/scripts/generate/templates/EnumerableMap.js deleted file mode 100644 index bcc8edd..0000000 --- a/lib/openzeppelin-contracts/scripts/generate/templates/EnumerableMap.js +++ /dev/null @@ -1,275 +0,0 @@ -const format = require('../format-lines'); -const { fromBytes32, toBytes32 } = require('./conversion'); -const { TYPES } = require('./EnumerableMap.opts'); - -/* eslint-disable max-len */ -const header = `\ -pragma solidity ^0.8.20; - -import {EnumerableSet} from "./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. - * - * \`\`\`solidity - * 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 - * - \`uint256 -> bytes32\` (\`UintToBytes32Map\`) since v5.1.0 - * - \`address -> address\` (\`AddressToAddressMap\`) since v5.1.0 - * - \`address -> bytes32\` (\`AddressToBytes32Map\`) since v5.1.0 - * - \`bytes32 -> address\` (\`Bytes32ToAddressMap\`) since v5.1.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 \`UintToAddressMap\` are just wrappers around the underlying Map. -// This means that we can only create new EnumerableMaps for types that fit in bytes32. - -/** - * @dev Query for a nonexistent map key. - */ -error EnumerableMapNonexistentKey(bytes32 key); - -struct Bytes32ToBytes32Map { - // Storage of keys - EnumerableSet.Bytes32Set _keys; - mapping(bytes32 key => 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]; - if (value == 0 && !contains(map, key)) { - revert EnumerableMapNonexistentKey(key); - } - return value; -} - -/** - * @dev Return the an array containing all the keys - * - * 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 map grows to a point where copying to memory consumes too much gas to fit in a block. - */ -function keys(Bytes32ToBytes32Map storage map) internal view returns (bytes32[] memory) { - return map._keys.values(); -} -`; - -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 map. 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 map. 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 Return the an array containing all the keys - * - * 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 map grows to a point where copying to memory consumes too much gas to fit in a block. - */ -function keys(${name} storage map) internal view returns (${keyType}[] memory) { - bytes32[] memory store = keys(map._inner); - ${keyType}[] memory result; - - /// @solidity memory-safe-assembly - assembly { - result := store - } - - return result; -} -`; - -// GENERATE -module.exports = format( - header.trimEnd(), - 'library EnumerableMap {', - format( - [].concat( - 'using EnumerableSet for EnumerableSet.Bytes32Set;', - '', - defaultMap, - TYPES.map(details => customMap(details)), - ), - ).trimEnd(), - '}', -); diff --git a/lib/openzeppelin-contracts/scripts/generate/templates/EnumerableMap.opts.js b/lib/openzeppelin-contracts/scripts/generate/templates/EnumerableMap.opts.js deleted file mode 100644 index d26ab05..0000000 --- a/lib/openzeppelin-contracts/scripts/generate/templates/EnumerableMap.opts.js +++ /dev/null @@ -1,19 +0,0 @@ -const { capitalize } = require('../../helpers'); - -const mapType = str => (str == 'uint256' ? 'Uint' : capitalize(str)); - -const formatType = (keyType, valueType) => ({ - name: `${mapType(keyType)}To${mapType(valueType)}Map`, - keyType, - valueType, -}); - -const TYPES = ['uint256', 'address', 'bytes32'] - .flatMap((key, _, array) => array.map(value => [key, value])) - .slice(0, -1) // remove bytes32 → byte32 (last one) that is already defined - .map(args => formatType(...args)); - -module.exports = { - TYPES, - formatType, -}; diff --git a/lib/openzeppelin-contracts/scripts/generate/templates/EnumerableSet.js b/lib/openzeppelin-contracts/scripts/generate/templates/EnumerableSet.js deleted file mode 100644 index d187877..0000000 --- a/lib/openzeppelin-contracts/scripts/generate/templates/EnumerableSet.js +++ /dev/null @@ -1,250 +0,0 @@ -const format = require('../format-lines'); -const { fromBytes32, toBytes32 } = require('./conversion'); -const { TYPES } = require('./EnumerableSet.opts'); - -/* eslint-disable max-len */ -const header = `\ -pragma solidity ^0.8.20; - -/** - * @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. - * - * \`\`\`solidity - * 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 is the index of the value in the \`values\` array plus 1. - // Position 0 is used to mean a value is not in the set. - mapping(bytes32 value => uint256) _positions; -} - -/** - * @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._positions[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 cache the value's position to prevent multiple reads from the same storage slot - uint256 position = set._positions[value]; - - if (position != 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 valueIndex = position - 1; - uint256 lastIndex = set._values.length - 1; - - if (valueIndex != lastIndex) { - bytes32 lastValue = set._values[lastIndex]; - - // Move the lastValue to the index where the value to delete is - set._values[valueIndex] = lastValue; - // Update the tracked position of the lastValue (that was just moved) - set._positions[lastValue] = position; - } - - // Delete the slot where the moved value was stored - set._values.pop(); - - // Delete the tracked position for the deleted slot - delete set._positions[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._positions[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 {', - format( - [].concat( - defaultSet, - TYPES.map(details => customSet(details)), - ), - ).trimEnd(), - '}', -); diff --git a/lib/openzeppelin-contracts/scripts/generate/templates/EnumerableSet.opts.js b/lib/openzeppelin-contracts/scripts/generate/templates/EnumerableSet.opts.js deleted file mode 100644 index 739f0ac..0000000 --- a/lib/openzeppelin-contracts/scripts/generate/templates/EnumerableSet.opts.js +++ /dev/null @@ -1,12 +0,0 @@ -const { capitalize } = require('../../helpers'); - -const mapType = str => (str == 'uint256' ? 'Uint' : capitalize(str)); - -const formatType = type => ({ - name: `${mapType(type)}Set`, - type, -}); - -const TYPES = ['bytes32', 'address', 'uint256'].map(formatType); - -module.exports = { TYPES, formatType }; diff --git a/lib/openzeppelin-contracts/scripts/generate/templates/MerkleProof.js b/lib/openzeppelin-contracts/scripts/generate/templates/MerkleProof.js deleted file mode 100644 index 768a981..0000000 --- a/lib/openzeppelin-contracts/scripts/generate/templates/MerkleProof.js +++ /dev/null @@ -1,178 +0,0 @@ -const format = require('../format-lines'); -const { OPTS } = require('./MerkleProof.opts'); - -const DEFAULT_HASH = 'Hashes.commutativeKeccak256'; - -const formatArgsSingleLine = (...args) => args.filter(Boolean).join(', '); -const formatArgsMultiline = (...args) => '\n' + format(args.filter(Boolean).join(',\0').split('\0')); - -// TEMPLATE -const header = `\ -pragma solidity ^0.8.20; - -import {Hashes} from "./Hashes.sol"; - -/** - * @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. - * - * NOTE: This library supports proof verification for merkle trees built using - * custom _commutative_ hashing functions (i.e. \`H(a, b) == H(b, a)\`). Proving - * leaf inclusion in trees built using non-commutative hashing functions requires - * additional logic that is not supported by this library. - */ -`; - -const errors = `\ -/** - *@dev The multiproof provided is not valid. - */ -error MerkleProofInvalidMultiproof(); -`; - -/* eslint-disable max-len */ -const templateProof = ({ suffix, location, visibility, hash }) => `\ -/** - * @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. - * - * This version handles proofs in ${location} with ${hash ? 'a custom' : 'the default'} hashing function. - */ -function verify${suffix}(${(hash ? formatArgsMultiline : formatArgsSingleLine)( - `bytes32[] ${location} proof`, - 'bytes32 root', - 'bytes32 leaf', - hash && `function(bytes32, bytes32) view returns (bytes32) ${hash}`, -)}) internal ${visibility} returns (bool) { - return processProof(proof, leaf${hash ? `, ${hash}` : ''}) == 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. - * - * This version handles proofs in ${location} with ${hash ? 'a custom' : 'the default'} hashing function. - */ -function processProof${suffix}(${(hash ? formatArgsMultiline : formatArgsSingleLine)( - `bytes32[] ${location} proof`, - 'bytes32 leaf', - hash && `function(bytes32, bytes32) view returns (bytes32) ${hash}`, -)}) internal ${visibility} returns (bytes32) { - bytes32 computedHash = leaf; - for (uint256 i = 0; i < proof.length; i++) { - computedHash = ${hash ?? DEFAULT_HASH}(computedHash, proof[i]); - } - return computedHash; -} -`; - -const templateMultiProof = ({ suffix, location, visibility, hash }) => `\ -/** - * @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}. - * - * This version handles multiproofs in ${location} with ${hash ? 'a custom' : 'the default'} hashing function. - * - * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. - */ -function multiProofVerify${suffix}(${formatArgsMultiline( - `bytes32[] ${location} proof`, - `bool[] ${location} proofFlags`, - 'bytes32 root', - `bytes32[] ${location} leaves`, - hash && `function(bytes32, bytes32) view returns (bytes32) ${hash}`, -)}) internal ${visibility} returns (bool) { - return processMultiProof(proof, proofFlags, leaves${hash ? `, ${hash}` : ''}) == 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. - * - * This version handles multiproofs in ${location} with ${hash ? 'a custom' : 'the default'} hashing function. - * - * 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). - */ -function processMultiProof${suffix}(${formatArgsMultiline( - `bytes32[] ${location} proof`, - `bool[] ${location} proofFlags`, - `bytes32[] ${location} leaves`, - hash && `function(bytes32, bytes32) view returns (bytes32) ${hash}`, -)}) internal ${visibility} returns (bytes32 merkleRoot) { - // This function rebuilds 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; - - // Check proof validity. - if (leavesLen + proof.length != proofFlags.length + 1) { - revert MerkleProofInvalidMultiproof(); - } - - // 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[](proofFlags.length); - 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 from the "main queue" (merging branches) or an element from the - // \`proof\` array. - for (uint256 i = 0; i < proofFlags.length; i++) { - bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; - bytes32 b = proofFlags[i] - ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) - : proof[proofPos++]; - hashes[i] = ${hash ?? DEFAULT_HASH}(a, b); - } - - if (proofFlags.length > 0) { - if (proofPos != proof.length) { - revert MerkleProofInvalidMultiproof(); - } - unchecked { - return hashes[proofFlags.length - 1]; - } - } else if (leavesLen > 0) { - return leaves[0]; - } else { - return proof[0]; - } -} -`; -/* eslint-enable max-len */ - -// GENERATE -module.exports = format( - header.trimEnd(), - 'library MerkleProof {', - format( - [].concat( - errors, - OPTS.flatMap(opts => templateProof(opts)), - OPTS.flatMap(opts => templateMultiProof(opts)), - ), - ).trimEnd(), - '}', -); diff --git a/lib/openzeppelin-contracts/scripts/generate/templates/MerkleProof.opts.js b/lib/openzeppelin-contracts/scripts/generate/templates/MerkleProof.opts.js deleted file mode 100644 index 911f239..0000000 --- a/lib/openzeppelin-contracts/scripts/generate/templates/MerkleProof.opts.js +++ /dev/null @@ -1,11 +0,0 @@ -const { product } = require('../../helpers'); - -const OPTS = product( - [ - { suffix: '', location: 'memory' }, - { suffix: 'Calldata', location: 'calldata' }, - ], - [{ visibility: 'pure' }, { visibility: 'view', hash: 'hasher' }], -).map(objs => Object.assign({}, ...objs)); - -module.exports = { OPTS }; diff --git a/lib/openzeppelin-contracts/scripts/generate/templates/Packing.js b/lib/openzeppelin-contracts/scripts/generate/templates/Packing.js deleted file mode 100644 index a5ab2d4..0000000 --- a/lib/openzeppelin-contracts/scripts/generate/templates/Packing.js +++ /dev/null @@ -1,86 +0,0 @@ -const format = require('../format-lines'); -const { product } = require('../../helpers'); -const { SIZES } = require('./Packing.opts'); - -// TEMPLATE -const header = `\ -pragma solidity ^0.8.20; - -/** - * @dev Helper library packing and unpacking multiple values into bytesXX. - * - * Example usage: - * - * \`\`\`solidity - * library MyPacker { - * type MyType is bytes32; - * - * function _pack(address account, bytes4 selector, uint64 period) external pure returns (MyType) { - * bytes12 subpack = Packing.pack_4_8(selector, bytes8(period)); - * bytes32 pack = Packing.pack_20_12(bytes20(account), subpack); - * return MyType.wrap(pack); - * } - * - * function _unpack(MyType self) external pure returns (address, bytes4, uint64) { - * bytes32 pack = MyType.unwrap(self); - * return ( - * address(Packing.extract_32_20(pack, 0)), - * Packing.extract_32_4(pack, 20), - * uint64(Packing.extract_32_8(pack, 24)) - * ); - * } - * } - * \`\`\` - */ -// solhint-disable func-name-mixedcase -`; - -const errors = `\ -error OutOfRangeAccess(); -`; - -const pack = (left, right) => `\ -function pack_${left}_${right}(bytes${left} left, bytes${right} right) internal pure returns (bytes${ - left + right -} result) { - assembly ("memory-safe") { - result := or(left, shr(${8 * left}, right)) - } -} -`; - -const extract = (outer, inner) => `\ -function extract_${outer}_${inner}(bytes${outer} self, uint8 offset) internal pure returns (bytes${inner} result) { - if (offset > ${outer - inner}) revert OutOfRangeAccess(); - assembly ("memory-safe") { - result := and(shl(mul(8, offset), self), shl(${256 - 8 * inner}, not(0))) - } -} -`; - -const replace = (outer, inner) => `\ -function replace_${outer}_${inner}(bytes${outer} self, bytes${inner} value, uint8 offset) internal pure returns (bytes${outer} result) { - bytes${inner} oldValue = extract_${outer}_${inner}(self, offset); - assembly ("memory-safe") { - result := xor(self, shr(mul(8, offset), xor(oldValue, value))) - } -} -`; - -// GENERATE -module.exports = format( - header.trimEnd(), - 'library Packing {', - format( - [].concat( - errors, - product(SIZES, SIZES) - .filter(([left, right]) => SIZES.includes(left + right)) - .map(([left, right]) => pack(left, right)), - product(SIZES, SIZES) - .filter(([outer, inner]) => outer > inner) - .flatMap(([outer, inner]) => [extract(outer, inner), replace(outer, inner)]), - ), - ).trimEnd(), - '}', -); diff --git a/lib/openzeppelin-contracts/scripts/generate/templates/Packing.opts.js b/lib/openzeppelin-contracts/scripts/generate/templates/Packing.opts.js deleted file mode 100644 index de9ab77..0000000 --- a/lib/openzeppelin-contracts/scripts/generate/templates/Packing.opts.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - SIZES: [1, 2, 4, 6, 8, 12, 16, 20, 24, 28, 32], -}; diff --git a/lib/openzeppelin-contracts/scripts/generate/templates/Packing.t.js b/lib/openzeppelin-contracts/scripts/generate/templates/Packing.t.js deleted file mode 100644 index 56e9c0c..0000000 --- a/lib/openzeppelin-contracts/scripts/generate/templates/Packing.t.js +++ /dev/null @@ -1,48 +0,0 @@ -const format = require('../format-lines'); -const { product } = require('../../helpers'); -const { SIZES } = require('./Packing.opts'); - -// TEMPLATE -const header = `\ -pragma solidity ^0.8.20; - -import {Test} from "forge-std/Test.sol"; -import {Packing} from "@openzeppelin/contracts/utils/Packing.sol"; -`; - -const testPack = (left, right) => `\ -function testPack(bytes${left} left, bytes${right} right) external { - assertEq(left, Packing.pack_${left}_${right}(left, right).extract_${left + right}_${left}(0)); - assertEq(right, Packing.pack_${left}_${right}(left, right).extract_${left + right}_${right}(${left})); -} -`; - -const testReplace = (outer, inner) => `\ -function testReplace(bytes${outer} container, bytes${inner} newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, ${outer - inner})); - - bytes${inner} oldValue = container.extract_${outer}_${inner}(offset); - - assertEq(newValue, container.replace_${outer}_${inner}(newValue, offset).extract_${outer}_${inner}(offset)); - assertEq(container, container.replace_${outer}_${inner}(newValue, offset).replace_${outer}_${inner}(oldValue, offset)); -} -`; - -// GENERATE -module.exports = format( - header, - 'contract PackingTest is Test {', - format( - [].concat( - 'using Packing for *;', - '', - product(SIZES, SIZES) - .filter(([left, right]) => SIZES.includes(left + right)) - .map(([left, right]) => testPack(left, right)), - product(SIZES, SIZES) - .filter(([outer, inner]) => outer > inner) - .map(([outer, inner]) => testReplace(outer, inner)), - ), - ).trimEnd(), - '}', -); diff --git a/lib/openzeppelin-contracts/scripts/generate/templates/SafeCast.js b/lib/openzeppelin-contracts/scripts/generate/templates/SafeCast.js deleted file mode 100644 index 8a9ce9f..0000000 --- a/lib/openzeppelin-contracts/scripts/generate/templates/SafeCast.js +++ /dev/null @@ -1,139 +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.20; - -/** - * @dev Wrappers over Solidity's uintXX/intXX/bool 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. - */ -`; - -const errors = `\ -/** - * @dev Value doesn't fit in an uint of \`bits\` size. - */ -error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value); - -/** - * @dev An int value doesn't fit in an uint of \`bits\` size. - */ -error SafeCastOverflowedIntToUint(int256 value); - -/** - * @dev Value doesn't fit in an int of \`bits\` size. - */ -error SafeCastOverflowedIntDowncast(uint8 bits, int256 value); - -/** - * @dev An uint value doesn't fit in an int of \`bits\` size. - */ -error SafeCastOverflowedUintToInt(uint256 value); -`; - -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 - */ -function toUint${length}(uint256 value) internal pure returns (uint${length}) { - if (value > type(uint${length}).max) { - revert SafeCastOverflowedUintDowncast(${length}, value); - } - 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 - */ -function toInt${length}(int256 value) internal pure returns (int${length} downcasted) { - downcasted = int${length}(value); - if (downcasted != value) { - revert SafeCastOverflowedIntDowncast(${length}, value); - } -} -`; -/* 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}. - */ -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 - if (value > uint${length}(type(int${length}).max)) { - revert SafeCastOverflowedUintToInt(value); - } - 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. - */ -function toUint${length}(int${length} value) internal pure returns (uint${length}) { - if (value < 0) { - revert SafeCastOverflowedIntToUint(value); - } - return uint${length}(value); -} -`; - -const boolToUint = `\ -/** - * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump. - */ -function toUint(bool b) internal pure returns (uint256 u) { - /// @solidity memory-safe-assembly - assembly { - u := iszero(iszero(b)) - } -} -`; - -// GENERATE -module.exports = format( - header.trimEnd(), - 'library SafeCast {', - format( - [].concat(errors, LENGTHS.map(toUintDownCast), toUint(256), LENGTHS.map(toIntDownCast), toInt(256), boolToUint), - ).trimEnd(), - '}', -); diff --git a/lib/openzeppelin-contracts/scripts/generate/templates/Slot.opts.js b/lib/openzeppelin-contracts/scripts/generate/templates/Slot.opts.js deleted file mode 100644 index aed1f98..0000000 --- a/lib/openzeppelin-contracts/scripts/generate/templates/Slot.opts.js +++ /dev/null @@ -1,13 +0,0 @@ -const { capitalize } = require('../../helpers'); - -const TYPES = [ - { type: 'address', isValueType: true }, - { type: 'bool', isValueType: true, name: 'Boolean' }, - { type: 'bytes32', isValueType: true, variants: ['bytes4'] }, - { type: 'uint256', isValueType: true, variants: ['uint32'] }, - { type: 'int256', isValueType: true, variants: ['int32'] }, - { type: 'string', isValueType: false }, - { type: 'bytes', isValueType: false }, -].map(type => Object.assign(type, { name: type.name ?? capitalize(type.type) })); - -module.exports = { TYPES }; diff --git a/lib/openzeppelin-contracts/scripts/generate/templates/SlotDerivation.js b/lib/openzeppelin-contracts/scripts/generate/templates/SlotDerivation.js deleted file mode 100644 index d8ab35d..0000000 --- a/lib/openzeppelin-contracts/scripts/generate/templates/SlotDerivation.js +++ /dev/null @@ -1,120 +0,0 @@ -const format = require('../format-lines'); -const { TYPES } = require('./Slot.opts'); - -const header = `\ -pragma solidity ^0.8.20; - -/** - * @dev Library for computing storage (and transient storage) locations from namespaces and deriving slots - * corresponding to standard patterns. The derivation method for array and mapping matches the storage layout used by - * the solidity language / compiler. - * - * See https://docs.soliditylang.org/en/v0.8.20/internals/layout_in_storage.html#mappings-and-dynamic-arrays[Solidity docs for mappings and dynamic arrays.]. - * - * Example usage: - * \`\`\`solidity - * contract Example { - * // Add the library methods - * using StorageSlot for bytes32; - * using SlotDerivation for bytes32; - * - * // Declare a namespace - * string private constant _NAMESPACE = "" // eg. OpenZeppelin.Slot - * - * function setValueInNamespace(uint256 key, address newValue) internal { - * _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value = newValue; - * } - * - * function getValueInNamespace(uint256 key) internal view returns (address) { - * return _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value; - * } - * } - * \`\`\` - * - * TIP: Consider using this library along with {StorageSlot}. - * - * NOTE: This library provides a way to manipulate storage locations in a non-standard way. Tooling for checking - * upgrade safety will ignore the slots accessed through this library. - */ -`; - -const namespace = `\ -/** - * @dev Derive an ERC-7201 slot from a string (namespace). - */ -function erc7201Slot(string memory namespace) internal pure returns (bytes32 slot) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, sub(keccak256(add(namespace, 0x20), mload(namespace)), 1)) - slot := and(keccak256(0x00, 0x20), not(0xff)) - } -} -`; - -const array = `\ -/** - * @dev Add an offset to a slot to get the n-th element of a structure or an array. - */ -function offset(bytes32 slot, uint256 pos) internal pure returns (bytes32 result) { - unchecked { - return bytes32(uint256(slot) + pos); - } -} - -/** - * @dev Derive the location of the first element in an array from the slot where the length is stored. - */ -function deriveArray(bytes32 slot) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, slot) - result := keccak256(0x00, 0x20) - } -} -`; - -const mapping = ({ type }) => `\ -/** - * @dev Derive the location of a mapping element from the key. - */ -function deriveMapping(bytes32 slot, ${type} key) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, key) - mstore(0x20, slot) - result := keccak256(0x00, 0x40) - } -} -`; - -const mapping2 = ({ type }) => `\ -/** - * @dev Derive the location of a mapping element from the key. - */ -function deriveMapping(bytes32 slot, ${type} memory key) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let length := mload(key) - let begin := add(key, 0x20) - let end := add(begin, length) - let cache := mload(end) - mstore(end, slot) - result := keccak256(begin, add(length, 0x20)) - mstore(end, cache) - } -} -`; - -// GENERATE -module.exports = format( - header.trimEnd(), - 'library SlotDerivation {', - format( - [].concat( - namespace, - array, - TYPES.map(type => (type.isValueType ? mapping(type) : mapping2(type))), - ), - ).trimEnd(), - '}', -); diff --git a/lib/openzeppelin-contracts/scripts/generate/templates/SlotDerivation.t.js b/lib/openzeppelin-contracts/scripts/generate/templates/SlotDerivation.t.js deleted file mode 100644 index dc7b07f..0000000 --- a/lib/openzeppelin-contracts/scripts/generate/templates/SlotDerivation.t.js +++ /dev/null @@ -1,113 +0,0 @@ -const format = require('../format-lines'); -const { capitalize } = require('../../helpers'); -const { TYPES } = require('./Slot.opts'); - -const header = `\ -pragma solidity ^0.8.20; - -import {Test} from "forge-std/Test.sol"; -import {SymTest} from "halmos-cheatcodes/SymTest.sol"; -import {SlotDerivation} from "@openzeppelin/contracts/utils/SlotDerivation.sol"; -`; - -const array = `\ -bytes[] private _array; - -function symbolicDeriveArray(uint256 length, uint256 offset) public { - vm.assume(length > 0); - vm.assume(offset < length); - _assertDeriveArray(length, offset); -} - -function testDeriveArray(uint256 length, uint256 offset) public { - length = bound(length, 1, type(uint256).max); - offset = bound(offset, 0, length - 1); - _assertDeriveArray(length, offset); -} - -function _assertDeriveArray(uint256 length, uint256 offset) public { - bytes32 baseSlot; - assembly { - baseSlot := _array.slot - sstore(baseSlot, length) // store length so solidity access does not revert - } - - bytes storage derived = _array[offset]; - bytes32 derivedSlot; - assembly { - derivedSlot := derived.slot - } - - assertEq(baseSlot.deriveArray().offset(offset), derivedSlot); -} -`; - -const mapping = ({ type, name }) => `\ -mapping(${type} => bytes) private _${type}Mapping; - -function testSymbolicDeriveMapping${name}(${type} key) public { - bytes32 baseSlot; - assembly { - baseSlot := _${type}Mapping.slot - } - - bytes storage derived = _${type}Mapping[key]; - bytes32 derivedSlot; - assembly { - derivedSlot := derived.slot - } - - assertEq(baseSlot.deriveMapping(key), derivedSlot); -} -`; - -const boundedMapping = ({ type, name }) => `\ -mapping(${type} => bytes) private _${type}Mapping; - -function testDeriveMapping${name}(${type} memory key) public { - _assertDeriveMapping${name}(key); -} - -function symbolicDeriveMapping${name}() public { - _assertDeriveMapping${name}(svm.create${name}(256, "DeriveMapping${name}Input")); -} - -function _assertDeriveMapping${name}(${type} memory key) internal { - bytes32 baseSlot; - assembly { - baseSlot := _${type}Mapping.slot - } - - bytes storage derived = _${type}Mapping[key]; - bytes32 derivedSlot; - assembly { - derivedSlot := derived.slot - } - - assertEq(baseSlot.deriveMapping(key), derivedSlot); -} -`; - -// GENERATE -module.exports = format( - header, - 'contract SlotDerivationTest is Test, SymTest {', - format( - [].concat( - 'using SlotDerivation for bytes32;', - '', - array, - TYPES.flatMap(type => - [].concat( - type, - (type.variants ?? []).map(variant => ({ - type: variant, - name: capitalize(variant), - isValueType: type.isValueType, - })), - ), - ).map(type => (type.isValueType ? mapping(type) : boundedMapping(type))), - ), - ).trimEnd(), - '}', -); diff --git a/lib/openzeppelin-contracts/scripts/generate/templates/StorageSlot.js b/lib/openzeppelin-contracts/scripts/generate/templates/StorageSlot.js deleted file mode 100644 index aa0c325..0000000 --- a/lib/openzeppelin-contracts/scripts/generate/templates/StorageSlot.js +++ /dev/null @@ -1,133 +0,0 @@ -const format = require('../format-lines'); -const { TYPES } = require('./Slot.opts'); - -const header = `\ -pragma solidity ^0.8.24; - -/** - * @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 ERC-1967 implementation slot: - * \`\`\`solidity - * contract ERC1967 { - * // Define the slot. Alternatively, use the SlotDerivation library to derive the slot. - * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; - * - * function _getImplementation() internal view returns (address) { - * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; - * } - * - * function _setImplementation(address newImplementation) internal { - * require(newImplementation.code.length > 0); - * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; - * } - * } - * \`\`\` - * - * Since version 5.1, this library also support writing and reading value types to and from transient storage. - * - * * Example using transient storage: - * \`\`\`solidity - * contract Lock { - * // Define the slot. Alternatively, use the SlotDerivation library to derive the slot. - * bytes32 internal constant _LOCK_SLOT = 0xf4678858b2b588224636b8522b729e7722d32fc491da849ed75b3fdf3c84f542; - * - * modifier locked() { - * require(!_LOCK_SLOT.asBoolean().tload()); - * - * _LOCK_SLOT.asBoolean().tstore(true); - * _; - * _LOCK_SLOT.asBoolean().tstore(false); - * } - * } - * \`\`\` - * - * TIP: Consider using this library along with {SlotDerivation}. - */ -`; - -const struct = ({ type, name }) => `\ -struct ${name}Slot { - ${type} value; -} -`; - -const get = ({ name }) => `\ -/** - * @dev Returns an \`${name}Slot\` with member \`value\` located at \`slot\`. - */ -function get${name}Slot(bytes32 slot) internal pure returns (${name}Slot storage r) { - /// @solidity memory-safe-assembly - assembly { - r.slot := slot - } -} -`; - -const getStorage = ({ type, name }) => `\ -/** - * @dev Returns an \`${name}Slot\` representation of the ${type} storage pointer \`store\`. - */ -function get${name}Slot(${type} storage store) internal pure returns (${name}Slot storage r) { - /// @solidity memory-safe-assembly - assembly { - r.slot := store.slot - } -} -`; - -const udvt = ({ type, name }) => `\ -/** - * @dev UDVT that represent a slot holding a ${type}. - */ -type ${name}SlotType is bytes32; - -/** - * @dev Cast an arbitrary slot to a ${name}SlotType. - */ -function as${name}(bytes32 slot) internal pure returns (${name}SlotType) { - return ${name}SlotType.wrap(slot); -} -`; - -const transient = ({ type, name }) => `\ -/** - * @dev Load the value held at location \`slot\` in transient storage. - */ -function tload(${name}SlotType slot) internal view returns (${type} value) { - /// @solidity memory-safe-assembly - assembly { - value := tload(slot) - } -} - -/** - * @dev Store \`value\` at location \`slot\` in transient storage. - */ -function tstore(${name}SlotType slot, ${type} value) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(slot, value) - } -} -`; - -// GENERATE -module.exports = format( - header.trimEnd(), - 'library StorageSlot {', - format( - [].concat( - TYPES.map(type => struct(type)), - TYPES.flatMap(type => [get(type), !type.isValueType && getStorage(type)].filter(Boolean)), - TYPES.filter(type => type.isValueType).map(type => udvt(type)), - TYPES.filter(type => type.isValueType).map(type => transient(type)), - ), - ).trimEnd(), - '}', -); diff --git a/lib/openzeppelin-contracts/scripts/generate/templates/StorageSlotMock.js b/lib/openzeppelin-contracts/scripts/generate/templates/StorageSlotMock.js deleted file mode 100644 index 623a675..0000000 --- a/lib/openzeppelin-contracts/scripts/generate/templates/StorageSlotMock.js +++ /dev/null @@ -1,70 +0,0 @@ -const format = require('../format-lines'); -const { TYPES } = require('./Slot.opts'); - -const header = `\ -pragma solidity ^0.8.24; - -import {Multicall} from "../utils/Multicall.sol"; -import {StorageSlot} from "../utils/StorageSlot.sol"; -`; - -const storageSetValueType = ({ type, name }) => `\ -function set${name}Slot(bytes32 slot, ${type} value) public { - slot.get${name}Slot().value = value; -} -`; - -const storageGetValueType = ({ type, name }) => `\ -function get${name}Slot(bytes32 slot) public view returns (${type}) { - return slot.get${name}Slot().value; -} -`; - -const storageSetNonValueType = ({ type, name }) => `\ -mapping(uint256 key => ${type}) public ${type}Map; - -function set${name}Slot(bytes32 slot, ${type} calldata value) public { - slot.get${name}Slot().value = value; -} - -function set${name}Storage(uint256 key, ${type} calldata value) public { - ${type}Map[key].get${name}Slot().value = value; -} - -function get${name}Slot(bytes32 slot) public view returns (${type} memory) { - return slot.get${name}Slot().value; -} - -function get${name}Storage(uint256 key) public view returns (${type} memory) { - return ${type}Map[key].get${name}Slot().value; -} -`; - -const transient = ({ type, name }) => `\ -event ${name}Value(bytes32 slot, ${type} value); - -function tload${name}(bytes32 slot) public { - emit ${name}Value(slot, slot.as${name}().tload()); -} - -function tstore(bytes32 slot, ${type} value) public { - slot.as${name}().tstore(value); -} -`; - -// GENERATE -module.exports = format( - header, - 'contract StorageSlotMock is Multicall {', - format( - [].concat( - 'using StorageSlot for *;', - '', - TYPES.filter(type => type.isValueType).map(type => storageSetValueType(type)), - TYPES.filter(type => type.isValueType).map(type => storageGetValueType(type)), - TYPES.filter(type => !type.isValueType).map(type => storageSetNonValueType(type)), - TYPES.filter(type => type.isValueType).map(type => transient(type)), - ), - ).trimEnd(), - '}', -); diff --git a/lib/openzeppelin-contracts/scripts/generate/templates/conversion.js b/lib/openzeppelin-contracts/scripts/generate/templates/conversion.js deleted file mode 100644 index 9221f7c..0000000 --- a/lib/openzeppelin-contracts/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/openzeppelin-contracts/scripts/git-user-config.sh b/lib/openzeppelin-contracts/scripts/git-user-config.sh deleted file mode 100644 index e7b81c3..0000000 --- a/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/openzeppelin-contracts/scripts/helpers.js b/lib/openzeppelin-contracts/scripts/helpers.js deleted file mode 100644 index d28c086..0000000 --- a/lib/openzeppelin-contracts/scripts/helpers.js +++ /dev/null @@ -1,7 +0,0 @@ -const iterate = require('../test/helpers/iterate'); -const strings = require('../test/helpers/strings'); - -module.exports = { - ...iterate, - ...strings, -}; diff --git a/lib/openzeppelin-contracts/scripts/prepack.sh b/lib/openzeppelin-contracts/scripts/prepack.sh deleted file mode 100755 index 6af1032..0000000 --- a/lib/openzeppelin-contracts/scripts/prepack.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail -shopt -s globstar - -# cross platform `mkdir -p` -mkdirp() { - node -e "fs.mkdirSync('$1', { recursive: true })" -} - -# cd to the root of the repo -cd "$(git rev-parse --show-toplevel)" - -npm run clean - -env COMPILE_MODE=production npm run compile - -mkdirp contracts/build/contracts -cp artifacts/contracts/**/*.json contracts/build/contracts -rm contracts/build/contracts/*.dbg.json -node scripts/remove-ignored-artifacts.js - -cp README.md contracts/ diff --git a/lib/openzeppelin-contracts/scripts/prepare-docs.sh b/lib/openzeppelin-contracts/scripts/prepare-docs.sh deleted file mode 100755 index d1317b0..0000000 --- a/lib/openzeppelin-contracts/scripts/prepare-docs.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail -shopt -s globstar - -OUTDIR="$(node -p 'require("./docs/config.js").outputDir')" - -if [ ! -d node_modules ]; then - npm ci -fi - -rm -rf "$OUTDIR" - -hardhat docgen - -# copy examples and adjust imports -examples_source_dir="contracts/mocks/docs" -examples_target_dir="docs/modules/api/examples" - -for f in "$examples_source_dir"/**/*.sol; do - name="${f/#"$examples_source_dir/"/}" - mkdir -p "$examples_target_dir/$(dirname "$name")" - sed -Ee '/^import/s|"(\.\./)+|"@openzeppelin/contracts/|' "$f" > "$examples_target_dir/$name" -done - -node scripts/gen-nav.js "$OUTDIR" > "$OUTDIR/../nav.adoc" diff --git a/lib/openzeppelin-contracts/scripts/release/format-changelog.js b/lib/openzeppelin-contracts/scripts/release/format-changelog.js deleted file mode 100755 index b8bcc8c..0000000 --- a/lib/openzeppelin-contracts/scripts/release/format-changelog.js +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env node - -// Adjusts the format of the changelog that changesets generates. -// This is run automatically when npm version is run. - -const fs = require('fs'); -const changelog = fs.readFileSync('CHANGELOG.md', 'utf8'); - -// Groups: -// - 1: Pull Request Number and URL -// - 2: Changeset entry -const RELEASE_LINE_REGEX = /^- (\[#.*?\]\(.*?\))?.*?! - (.*)$/gm; - -// Captures vX.Y.Z or vX.Y.Z-rc.W -const VERSION_TITLE_REGEX = /^## (\d+\.\d+\.\d+(-rc\.\d+)?)$/gm; - -const isPrerelease = process.env.PRERELEASE === 'true'; - -const formatted = changelog - // Remove titles - .replace(/^### Major Changes\n\n/gm, '') - .replace(/^### Minor Changes\n\n/gm, '') - .replace(/^### Patch Changes\n\n/gm, '') - // Remove extra whitespace between items - .replace(/^(- \[.*\n)\n(?=-)/gm, '$1') - // Format each release line - .replace(RELEASE_LINE_REGEX, (_, pr, entry) => (pr ? `- ${entry} (${pr})` : `- ${entry}`)) - // Add date to new version - .replace(VERSION_TITLE_REGEX, `\n## $1 (${new Date().toISOString().split('T')[0]})`) - // Conditionally allow vX.Y.Z.rc-.W sections only in prerelease - .replace(/^## \d\.\d\.\d-rc\S+[^]+?(?=^#)/gm, section => (isPrerelease ? section : '')); - -fs.writeFileSync('CHANGELOG.md', formatted); diff --git a/lib/openzeppelin-contracts/scripts/release/synchronize-versions.js b/lib/openzeppelin-contracts/scripts/release/synchronize-versions.js deleted file mode 100755 index 15aa259..0000000 --- a/lib/openzeppelin-contracts/scripts/release/synchronize-versions.js +++ /dev/null @@ -1,15 +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'); - -setVersion('package.json', 'contracts/package.json'); - -function setVersion(from, to) { - const fromJson = JSON.parse(fs.readFileSync(from)); - const toJson = JSON.parse(fs.readFileSync(to)); - toJson.version = fromJson.version; - fs.writeFileSync(to, JSON.stringify(toJson, null, 2) + '\n'); -} diff --git a/lib/openzeppelin-contracts/scripts/release/update-comment.js b/lib/openzeppelin-contracts/scripts/release/update-comment.js deleted file mode 100755 index 9d6df26..0000000 --- a/lib/openzeppelin-contracts/scripts/release/update-comment.js +++ /dev/null @@ -1,34 +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.satisfies(v, `< ${version}`)) // ignores prereleases unless currently a prerelease - .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); -} diff --git a/lib/openzeppelin-contracts/scripts/release/version.sh b/lib/openzeppelin-contracts/scripts/release/version.sh deleted file mode 100755 index 7b0ddea..0000000 --- a/lib/openzeppelin-contracts/scripts/release/version.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -changeset version - -scripts/release/format-changelog.js -scripts/release/synchronize-versions.js -scripts/release/update-comment.js - -oz-docs update-version diff --git a/lib/openzeppelin-contracts/scripts/release/workflow/exit-prerelease.sh b/lib/openzeppelin-contracts/scripts/release/workflow/exit-prerelease.sh deleted file mode 100644 index bcf9b9a..0000000 --- a/lib/openzeppelin-contracts/scripts/release/workflow/exit-prerelease.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -npx changeset pre exit rc -git add . -git commit -m "Exit release candidate" -git push origin diff --git a/lib/openzeppelin-contracts/scripts/release/workflow/github-release.js b/lib/openzeppelin-contracts/scripts/release/workflow/github-release.js deleted file mode 100644 index f213106..0000000 --- a/lib/openzeppelin-contracts/scripts/release/workflow/github-release.js +++ /dev/null @@ -1,48 +0,0 @@ -const { readFileSync } = require('fs'); -const { join } = require('path'); -const { version } = require(join(__dirname, '../../../package.json')); - -module.exports = async ({ github, context }) => { - const changelog = readFileSync('CHANGELOG.md', 'utf8'); - - await github.rest.repos.createRelease({ - owner: context.repo.owner, - repo: context.repo.repo, - tag_name: `v${version}`, - target_commitish: github.ref_name, - body: extractSection(changelog, version), - prerelease: process.env.PRERELEASE === 'true', - }); -}; - -// From https://github.com/frangio/extract-changelog/blob/master/src/utils/word-regexp.ts -function makeWordRegExp(word) { - const start = word.length > 0 && /\b/.test(word[0]) ? '\\b' : ''; - const end = word.length > 0 && /\b/.test(word[word.length - 1]) ? '\\b' : ''; - return new RegExp(start + [...word].map(c => (/[a-z0-9]/i.test(c) ? c : '\\' + c)).join('') + end); -} - -// From https://github.com/frangio/extract-changelog/blob/master/src/core.ts -function extractSection(document, wantedHeading) { - // ATX Headings as defined in GitHub Flavored Markdown (https://github.github.com/gfm/#atx-headings) - const heading = /^ {0,3}(?#{1,6})(?: [ \t\v\f]*(?.*?)[ \t\v\f]*)?(?:[\n\r]+|$)/gm; - - const wantedHeadingRe = makeWordRegExp(wantedHeading); - - let start, end; - - for (const m of document.matchAll(heading)) { - if (!start) { - if (m.groups.text.search(wantedHeadingRe) === 0) { - start = m; - } - } else if (m.groups.lead.length <= start.groups.lead.length) { - end = m; - break; - } - } - - if (start) { - return document.slice(start.index + start[0].length, end?.index); - } -} diff --git a/lib/openzeppelin-contracts/scripts/release/workflow/integrity-check.sh b/lib/openzeppelin-contracts/scripts/release/workflow/integrity-check.sh deleted file mode 100644 index 86e99f9..0000000 --- a/lib/openzeppelin-contracts/scripts/release/workflow/integrity-check.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -CHECKSUMS="$RUNNER_TEMP/checksums.txt" - -# Extract tarball content into a tmp directory -tar xf "$TARBALL" -C "$RUNNER_TEMP" - -# Move to extracted directory -cd "$RUNNER_TEMP/package" - -# Checksum all Solidity files -find . -type f -name "*.sol" | xargs shasum > "$CHECKSUMS" - -# Back to directory with git contents -cd "$GITHUB_WORKSPACE/contracts" - -# Check against tarball contents -shasum -c "$CHECKSUMS" diff --git a/lib/openzeppelin-contracts/scripts/release/workflow/pack.sh b/lib/openzeppelin-contracts/scripts/release/workflow/pack.sh deleted file mode 100644 index ce30712..0000000 --- a/lib/openzeppelin-contracts/scripts/release/workflow/pack.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -dist_tag() { - PACKAGE_JSON_NAME="$(jq -r .name ./package.json)" - LATEST_NPM_VERSION="$(npm info "$PACKAGE_JSON_NAME" version)" - PACKAGE_JSON_VERSION="$(jq -r .version ./package.json)" - - if [ "$PRERELEASE" = "true" ]; then - echo "next" - elif npx semver -r ">$LATEST_NPM_VERSION" "$PACKAGE_JSON_VERSION" > /dev/null; then - echo "latest" - else - # This is a patch for an older version - # npm can't publish without a tag - echo "tmp" - fi -} - -cd contracts -TARBALL="$(npm pack | tee /dev/stderr | tail -1)" -echo "tarball_name=$TARBALL" >> $GITHUB_OUTPUT -echo "tarball=$(pwd)/$TARBALL" >> $GITHUB_OUTPUT -echo "tag=$(dist_tag)" >> $GITHUB_OUTPUT -cd .. diff --git a/lib/openzeppelin-contracts/scripts/release/workflow/publish.sh b/lib/openzeppelin-contracts/scripts/release/workflow/publish.sh deleted file mode 100644 index e490e5d..0000000 --- a/lib/openzeppelin-contracts/scripts/release/workflow/publish.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -PACKAGE_JSON_NAME="$(tar xfO "$TARBALL" package/package.json | jq -r .name)" -PACKAGE_JSON_VERSION="$(tar xfO "$TARBALL" package/package.json | jq -r .version)" - -# Intentionally escape $ to avoid interpolation and writing the token to disk -echo "//registry.npmjs.org/:_authToken=\${NPM_TOKEN}" > .npmrc - -# Actual publish -npm publish "$TARBALL" --tag "$TAG" - -# Clean up tags -delete_tag() { - npm dist-tag rm "$PACKAGE_JSON_NAME" "$1" -} - -if [ "$TAG" = tmp ]; then - delete_tag "$TAG" -elif [ "$TAG" = latest ]; then - # Delete the next tag if it exists and is a prerelease for what is currently being published - if npm dist-tag ls "$PACKAGE_JSON_NAME" | grep -q "next: $PACKAGE_JSON_VERSION"; then - delete_tag next - fi -fi diff --git a/lib/openzeppelin-contracts/scripts/release/workflow/rerun.js b/lib/openzeppelin-contracts/scripts/release/workflow/rerun.js deleted file mode 100644 index f48ce6e..0000000 --- a/lib/openzeppelin-contracts/scripts/release/workflow/rerun.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = ({ github, context }) => - github.rest.actions.createWorkflowDispatch({ - owner: context.repo.owner, - repo: context.repo.repo, - workflow_id: 'release-cycle.yml', - ref: process.env.REF || process.env.GITHUB_REF_NAME, - }); diff --git a/lib/openzeppelin-contracts/scripts/release/workflow/set-changesets-pr-title.js b/lib/openzeppelin-contracts/scripts/release/workflow/set-changesets-pr-title.js deleted file mode 100644 index 59b03b2..0000000 --- a/lib/openzeppelin-contracts/scripts/release/workflow/set-changesets-pr-title.js +++ /dev/null @@ -1,17 +0,0 @@ -const { coerce, inc, rsort } = require('semver'); -const { join } = require('path'); -const { version } = require(join(__dirname, '../../../package.json')); - -module.exports = async ({ core }) => { - // Variables not in the context - const refName = process.env.GITHUB_REF_NAME; - - // Compare package.json version's next patch vs. first version patch - // A recently opened branch will give the next patch for the previous minor - // So, we get the max against the patch 0 of the release branch's version - const branchPatch0 = coerce(refName.replace('release-v', '')).version; - const packageJsonNextPatch = inc(version, 'patch'); - const [nextVersion] = rsort([branchPatch0, packageJsonNextPatch], false); - - core.exportVariable('TITLE', `Release v${nextVersion}`); -}; diff --git a/lib/openzeppelin-contracts/scripts/release/workflow/start.sh b/lib/openzeppelin-contracts/scripts/release/workflow/start.sh deleted file mode 100644 index 7683ec5..0000000 --- a/lib/openzeppelin-contracts/scripts/release/workflow/start.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# Set changeset status location -# This is needed because `changeset status --output` only works with relative routes -CHANGESETS_STATUS_JSON="$(realpath --relative-to=. "$RUNNER_TEMP/status.json")" - -# Save changeset status to temp file -npx changeset status --output="$CHANGESETS_STATUS_JSON" - -# Defensive assertion. SHOULD NOT BE REACHED -if [ "$(jq '.releases | length' "$CHANGESETS_STATUS_JSON")" != 1 ]; then - echo "::error file=$CHANGESETS_STATUS_JSON::The status doesn't contain only 1 release" - exit 1; -fi; - -# Create branch -BRANCH_SUFFIX="$(jq -r '.releases[0].newVersion | gsub("\\.\\d+$"; "")' $CHANGESETS_STATUS_JSON)" -RELEASE_BRANCH="release-v$BRANCH_SUFFIX" -git checkout -b "$RELEASE_BRANCH" - -# Output branch -echo "branch=$RELEASE_BRANCH" >> $GITHUB_OUTPUT - -# Enter in prerelease state -npx changeset pre enter rc -git add . -git commit -m "Start release candidate" - -# Push branch -if ! git push origin "$RELEASE_BRANCH"; then - echo "::error file=scripts/release/start.sh::Can't push $RELEASE_BRANCH. Did you forget to run this workflow from $RELEASE_BRANCH?" - exit 1 -fi diff --git a/lib/openzeppelin-contracts/scripts/release/workflow/state.js b/lib/openzeppelin-contracts/scripts/release/workflow/state.js deleted file mode 100644 index 914e8de..0000000 --- a/lib/openzeppelin-contracts/scripts/release/workflow/state.js +++ /dev/null @@ -1,112 +0,0 @@ -const { readPreState } = require('@changesets/pre'); -const { default: readChangesets } = require('@changesets/read'); -const { join } = require('path'); -const { fetch } = require('undici'); -const { version, name: packageName } = require(join(__dirname, '../../../contracts/package.json')); - -module.exports = async ({ github, context, core }) => { - const state = await getState({ github, context, core }); - - function setOutput(key, value) { - core.info(`State ${key} = ${value}`); - core.setOutput(key, value); - } - - // Jobs to trigger - setOutput('start', shouldRunStart(state)); - setOutput('promote', shouldRunPromote(state)); - setOutput('changesets', shouldRunChangesets(state)); - setOutput('publish', shouldRunPublish(state)); - setOutput('merge', shouldRunMerge(state)); - - // Global Variables - setOutput('is_prerelease', state.prerelease); -}; - -function shouldRunStart({ isMaster, isWorkflowDispatch, botRun }) { - return isMaster && isWorkflowDispatch && !botRun; -} - -function shouldRunPromote({ isReleaseBranch, isWorkflowDispatch, botRun }) { - return isReleaseBranch && isWorkflowDispatch && !botRun; -} - -function shouldRunChangesets({ isReleaseBranch, isPush, isWorkflowDispatch, botRun }) { - return (isReleaseBranch && isPush) || (isReleaseBranch && isWorkflowDispatch && botRun); -} - -function shouldRunPublish({ isReleaseBranch, isPush, hasPendingChangesets, isPublishedOnNpm }) { - return isReleaseBranch && isPush && !hasPendingChangesets && !isPublishedOnNpm; -} - -function shouldRunMerge({ - isReleaseBranch, - isPush, - prerelease, - isCurrentFinalVersion, - hasPendingChangesets, - prBackExists, -}) { - return isReleaseBranch && isPush && !prerelease && isCurrentFinalVersion && !hasPendingChangesets && !prBackExists; -} - -async function getState({ github, context, core }) { - // Variables not in the context - const refName = process.env.GITHUB_REF_NAME; - const botRun = process.env.TRIGGERING_ACTOR === 'github-actions[bot]'; - - const { changesets, preState } = await readChangesetState(); - - // Static vars - const state = { - refName, - hasPendingChangesets: changesets.length > 0, - prerelease: preState?.mode === 'pre', - isMaster: refName === 'master', - isReleaseBranch: refName.startsWith('release-v'), - isWorkflowDispatch: context.eventName === 'workflow_dispatch', - isPush: context.eventName === 'push', - isCurrentFinalVersion: !version.includes('-rc.'), - botRun, - }; - - // Async vars - const { data: prs } = await github.rest.pulls.list({ - owner: context.repo.owner, - repo: context.repo.repo, - head: `${context.repo.owner}:merge/${state.refName}`, - base: 'master', - state: 'open', - }); - - state.prBackExists = prs.length !== 0; - - state.isPublishedOnNpm = await isPublishedOnNpm(packageName, version); - - // Log every state value in debug mode - if (core.isDebug()) for (const [key, value] of Object.entries(state)) core.debug(`${key}: ${value}`); - - return state; -} - -// From https://github.com/changesets/action/blob/v1.4.1/src/readChangesetState.ts -async function readChangesetState(cwd = process.cwd()) { - const preState = await readPreState(cwd); - const isInPreMode = preState !== undefined && preState.mode === 'pre'; - - let changesets = await readChangesets(cwd); - - if (isInPreMode) { - changesets = changesets.filter(x => !preState.changesets.includes(x.id)); - } - - return { - preState: isInPreMode ? preState : undefined, - changesets, - }; -} - -async function isPublishedOnNpm(package, version) { - const res = await fetch(`https://registry.npmjs.com/${package}/${version}`); - return res.ok; -} diff --git a/lib/openzeppelin-contracts/scripts/remove-ignored-artifacts.js b/lib/openzeppelin-contracts/scripts/remove-ignored-artifacts.js deleted file mode 100644 index e156032..0000000 --- a/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 = 'contracts/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/openzeppelin-contracts/scripts/solhint-custom/index.js b/lib/openzeppelin-contracts/scripts/solhint-custom/index.js deleted file mode 100644 index 9625027..0000000 --- a/lib/openzeppelin-contracts/scripts/solhint-custom/index.js +++ /dev/null @@ -1,84 +0,0 @@ -const path = require('path'); -const minimatch = require('minimatch'); - -// Files matching these patterns will be ignored unless a rule has `static global = true` -const ignore = ['contracts/mocks/**/*', 'test/**/*']; - -class Base { - constructor(reporter, config, source, fileName) { - this.reporter = reporter; - this.ignored = this.constructor.global || ignore.some(p => minimatch(path.normalize(fileName), p)); - this.ruleId = this.constructor.ruleId; - if (this.ruleId === undefined) { - throw Error('missing ruleId static property'); - } - } - - error(node, message) { - if (!this.ignored) { - this.reporter.error(node, this.ruleId, message); - } - } -} - -module.exports = [ - class extends Base { - static ruleId = 'interface-names'; - - ContractDefinition(node) { - if (node.kind === 'interface' && !/^I[A-Z]/.test(node.name)) { - this.error(node, 'Interface names should have a capital I prefix'); - } - } - }, - - class extends Base { - static ruleId = 'private-variables'; - - VariableDeclaration(node) { - const constantOrImmutable = node.isDeclaredConst || node.isImmutable; - if (node.isStateVar && !constantOrImmutable && node.visibility !== 'private') { - this.error(node, 'State variables must be private'); - } - } - }, - - class extends Base { - static ruleId = 'leading-underscore'; - - VariableDeclaration(node) { - if (node.isDeclaredConst) { - // TODO: expand visibility and fix - if (node.visibility === 'private' && /^_/.test(node.name)) { - this.error(node, 'Constant variables should not have leading underscore'); - } - } else if (node.visibility === 'private' && !/^_/.test(node.name)) { - this.error(node, 'Non-constant private variables must have leading underscore'); - } - } - - FunctionDefinition(node) { - if (node.visibility === 'private' || (node.visibility === 'internal' && node.parent.kind !== 'library')) { - if (!/^_/.test(node.name)) { - this.error(node, 'Private and internal functions must have leading underscore'); - } - } - if (node.visibility === 'internal' && node.parent.kind === 'library') { - if (/^_/.test(node.name)) { - this.error(node, 'Library internal functions should not have leading underscore'); - } - } - } - }, - - // TODO: re-enable and fix - // class extends Base { - // static ruleId = 'no-external-virtual'; - // - // FunctionDefinition(node) { - // if (node.visibility == 'external' && node.isVirtual) { - // this.error(node, 'Functions should not be external and virtual'); - // } - // } - // }, -]; diff --git a/lib/openzeppelin-contracts/scripts/solhint-custom/package.json b/lib/openzeppelin-contracts/scripts/solhint-custom/package.json deleted file mode 100644 index 075eb92..0000000 --- a/lib/openzeppelin-contracts/scripts/solhint-custom/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "solhint-plugin-openzeppelin", - "version": "0.0.0", - "private": true -} diff --git a/lib/openzeppelin-contracts/scripts/update-docs-branch.js b/lib/openzeppelin-contracts/scripts/update-docs-branch.js deleted file mode 100644 index 324ba0c..0000000 --- a/lib/openzeppelin-contracts/scripts/update-docs-branch.js +++ /dev/null @@ -1,65 +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); -} - -const pkgVersion = require('../package.json').version; - -if (pkgVersion.includes('-') && !pkgVersion.includes('.0.0-')) { - console.error('Refusing to update docs: non-major 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/openzeppelin-contracts/scripts/upgradeable/README.md b/lib/openzeppelin-contracts/scripts/upgradeable/README.md deleted file mode 100644 index 2309f9e..0000000 --- a/lib/openzeppelin-contracts/scripts/upgradeable/README.md +++ /dev/null @@ -1,21 +0,0 @@ -The upgradeable variant of OpenZeppelin Contracts is automatically generated from the original Solidity code. We call this process "transpilation" and it is implemented by our [Upgradeability Transpiler](https://github.com/OpenZeppelin/openzeppelin-transpiler/). - -When the `master` branch or `release-v*` branches are updated, the code is transpiled and pushed to [OpenZeppelin/openzeppelin-contracts-upgradeable](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable) by the `upgradeable.yml` workflow. - -## `transpile.sh` - -Applies patches and invokes the transpiler with the command line flags we need for our requirements (for example, excluding certain files). - -## `transpile-onto.sh` - -``` -bash scripts/upgradeable/transpile-onto.sh [] -``` - -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 `[]` (this is used in GitHub Actions, but is usually not necessary locally). - -## `patch-apply.sh` & `patch-save.sh` - -Some of the upgradeable contract variants require ad-hoc changes that are not implemented by the transpiler. These changes are implemented by patches stored in `upgradeable.patch` in this directory. `patch-apply.sh` applies these patches. - -If the patches fail to apply due to changes in the repo, the conflicts have to be resolved manually. Once fixed, `patch-save.sh` will take the changes staged in Git and update `upgradeable.patch` to match. diff --git a/lib/openzeppelin-contracts/scripts/upgradeable/patch-apply.sh b/lib/openzeppelin-contracts/scripts/upgradeable/patch-apply.sh deleted file mode 100755 index d9e1758..0000000 --- a/lib/openzeppelin-contracts/scripts/upgradeable/patch-apply.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -DIRNAME="$(dirname -- "${BASH_SOURCE[0]}")" -PATCH="$DIRNAME/upgradeable.patch" - -error() { - echo Error: "$*" >&2 - exit 1 -} - -if ! git diff-files --quiet ":!$PATCH" || ! git diff-index --quiet HEAD ":!$PATCH"; then - error "Repository must have no staged or unstaged changes" -fi - -if ! git apply -3 "$PATCH"; then - error "Fix conflicts and run $DIRNAME/patch-save.sh" -fi diff --git a/lib/openzeppelin-contracts/scripts/upgradeable/patch-save.sh b/lib/openzeppelin-contracts/scripts/upgradeable/patch-save.sh deleted file mode 100755 index 111e6f1..0000000 --- a/lib/openzeppelin-contracts/scripts/upgradeable/patch-save.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -DIRNAME="$(dirname -- "${BASH_SOURCE[0]}")" -PATCH="$DIRNAME/upgradeable.patch" - -error() { - echo Error: "$*" >&2 - exit 1 -} - -if ! git diff-files --quiet ":!$PATCH"; then - error "Unstaged changes. Stage to include in patch or temporarily stash." -fi - -git diff-index --cached --patch --output="$PATCH" HEAD -git restore --staged --worktree ":!$PATCH" diff --git a/lib/openzeppelin-contracts/scripts/upgradeable/transpile-onto.sh b/lib/openzeppelin-contracts/scripts/upgradeable/transpile-onto.sh deleted file mode 100644 index b8508f0..0000000 --- a/lib/openzeppelin-contracts/scripts/upgradeable/transpile-onto.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -if [ $# -lt 1 ]; then - echo "usage: bash $0 []" >&2 - exit 1 -fi - -set -x - -target="$1" -base="${2-}" - -bash scripts/upgradeable/transpile.sh - -commit="$(git rev-parse --short HEAD)" -start_branch="$(git rev-parse --abbrev-ref HEAD)" - -git add contracts - -# detach from the current branch to avoid making changes to it -git checkout --quiet --detach - -# switch to the target branch, creating it if necessary -if git rev-parse -q --verify "$target"; then - # if the branch exists, make it the current HEAD without checking out its contents - git reset --soft "$target" - git checkout "$target" -else - # if the branch doesn't exist, create it as an orphan and check it out - git checkout --orphan "$target" - if [ -n "$base" ] && git rev-parse -q --verify "$base"; then - # if base was specified and it exists, set it as the branch history - git reset --soft "$base" - fi -fi - -# abort if there are no changes to commit at this point -if git diff --quiet --cached; then - exit -fi - -if [[ -v SUBMODULE_REMOTE ]]; then - lib=lib/openzeppelin-contracts - git submodule add -b "${base#origin/}" "$SUBMODULE_REMOTE" "$lib" - git -C "$lib" checkout "$commit" - git add "$lib" -fi - -git commit -m "Transpile $commit" - -# return to original branch -git checkout "$start_branch" diff --git a/lib/openzeppelin-contracts/scripts/upgradeable/transpile.sh b/lib/openzeppelin-contracts/scripts/upgradeable/transpile.sh deleted file mode 100644 index f7c848c..0000000 --- a/lib/openzeppelin-contracts/scripts/upgradeable/transpile.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail -x - -VERSION="$(jq -r .version contracts/package.json)" -DIRNAME="$(dirname -- "${BASH_SOURCE[0]}")" - -bash "$DIRNAME/patch-apply.sh" -sed -i'' -e "s//$VERSION/g" "contracts/package.json" -git add contracts/package.json - -npm run clean -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 proxy-related contracts with a few exceptions -# -p: emit public initializer -# -n: use namespaces -# -N: exclude from namespaces transformation -# -q: partial transpilation using @openzeppelin/contracts as peer project -npx @openzeppelin/upgrade-safe-transpiler -D \ - -b "$build_info" \ - -i contracts/proxy/utils/Initializable.sol \ - -x 'contracts-exposed/**/*' \ - -x 'contracts/proxy/**/*' \ - -x '!contracts/proxy/Clones.sol' \ - -x '!contracts/proxy/ERC1967/ERC1967Storage.sol' \ - -x '!contracts/proxy/ERC1967/ERC1967Utils.sol' \ - -x '!contracts/proxy/utils/UUPSUpgradeable.sol' \ - -x '!contracts/proxy/beacon/IBeacon.sol' \ - -p 'contracts/access/manager/AccessManager.sol' \ - -p 'contracts/finance/VestingWallet.sol' \ - -p 'contracts/governance/TimelockController.sol' \ - -p 'contracts/metatx/ERC2771Forwarder.sol' \ - -n \ - -N 'contracts/mocks/**/*' \ - -q '@openzeppelin/' - -# delete compilation artifacts of vanilla code -npm run clean diff --git a/lib/openzeppelin-contracts/scripts/upgradeable/upgradeable.patch b/lib/openzeppelin-contracts/scripts/upgradeable/upgradeable.patch deleted file mode 100644 index 458ecd4..0000000 --- a/lib/openzeppelin-contracts/scripts/upgradeable/upgradeable.patch +++ /dev/null @@ -1,361 +0,0 @@ -diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md -deleted file mode 100644 -index 35ad097ff..000000000 ---- a/.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/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml -index 4018cef29..d343a53d8 100644 ---- a/.github/ISSUE_TEMPLATE/config.yml -+++ b/.github/ISSUE_TEMPLATE/config.yml -@@ -1,4 +1,8 @@ -+blank_issues_enabled: false - contact_links: -+ - name: Bug Reports & Feature Requests -+ url: https://github.com/OpenZeppelin/openzeppelin-contracts/issues/new/choose -+ about: Visit the OpenZeppelin Contracts repository - - name: Questions & Support Requests - url: https://forum.openzeppelin.com/c/support/contracts/18 - about: Ask in the OpenZeppelin Forum -diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md -deleted file mode 100644 -index ff596b0c3..000000000 ---- a/.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/README.md b/README.md -index fa7b4e31e..4799b6376 100644 ---- a/README.md -+++ b/README.md -@@ -19,6 +19,9 @@ - > [!IMPORTANT] - > OpenZeppelin Contracts uses semantic versioning to communicate backwards compatibility of its API and storage layout. For upgradeable contracts, the storage layout of different major versions should be assumed incompatible, for example, it is unsafe to upgrade from 4.9.3 to 5.0.0. Learn more at [Backwards Compatibility](https://docs.openzeppelin.com/contracts/backwards-compatibility). - -++> [!NOTE] -++> You are looking at the upgradeable variant of OpenZeppelin Contracts. Be sure to review the documentation on [Using OpenZeppelin Contracts with Upgrades](https://docs.openzeppelin.com/contracts/upgradeable). -++ - ## Overview - - ### Installation -@@ -26,7 +29,7 @@ - #### Hardhat (npm) - - ``` --$ npm install @openzeppelin/contracts -+$ npm install @openzeppelin/contracts-upgradeable - ``` - - #### Foundry (git) -@@ -38,10 +41,10 @@ $ npm install @openzeppelin/contracts - > Foundry installs the latest version initially, but subsequent `forge update` commands will use the `master` branch. - - ``` --$ forge install OpenZeppelin/openzeppelin-contracts -+$ forge install OpenZeppelin/openzeppelin-contracts-upgradeable - ``` - --Add `@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/` in `remappings.txt.` -+Add `@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/` in `remappings.txt.` - - ### Usage - -@@ -50,10 +53,11 @@ Once installed, you can use the contracts in the library by importing them: - ```solidity - pragma solidity ^0.8.20; - --import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; -+import {ERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol"; - --contract MyCollectible is ERC721 { -- constructor() ERC721("MyCollectible", "MCO") { -+contract MyCollectible is ERC721Upgradeable { -+ function initialize() initializer public { -+ __ERC721_init("MyCollectible", "MCO"); - } - } - ``` -diff --git a/contracts/package.json b/contracts/package.json -index 845e8c403..8dc181b91 100644 ---- a/contracts/package.json -+++ b/contracts/package.json -@@ -1,5 +1,5 @@ - { -- "name": "@openzeppelin/contracts", -+ "name": "@openzeppelin/contracts-upgradeable", - "description": "Secure Smart Contract library for Solidity", - "version": "5.0.2", - "files": [ -@@ -13,7 +13,7 @@ - }, - "repository": { - "type": "git", -- "url": "https://github.com/OpenZeppelin/openzeppelin-contracts.git" -+ "url": "https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable.git" - }, - "keywords": [ - "solidity", -@@ -28,5 +28,8 @@ - "bugs": { - "url": "https://github.com/OpenZeppelin/openzeppelin-contracts/issues" - }, -- "homepage": "https://openzeppelin.com/contracts/" -+ "homepage": "https://openzeppelin.com/contracts/", -+ "peerDependencies": { -+ "@openzeppelin/contracts": "" -+ } - } -diff --git a/contracts/utils/cryptography/EIP712.sol b/contracts/utils/cryptography/EIP712.sol -index 77c4c8990..602467f40 100644 ---- a/contracts/utils/cryptography/EIP712.sol -+++ b/contracts/utils/cryptography/EIP712.sol -@@ -4,7 +4,6 @@ - pragma solidity ^0.8.20; - - import {MessageHashUtils} from "./MessageHashUtils.sol"; --import {ShortStrings, ShortString} from "../ShortStrings.sol"; - import {IERC5267} from "../../interfaces/IERC5267.sol"; - - /** -@@ -28,28 +27,18 @@ import {IERC5267} from "../../interfaces/IERC5267.sol"; - * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain - * separator of the implementation contract. This will cause the {_domainSeparatorV4} function to always rebuild the - * separator from the immutable values, which is cheaper than accessing a cached version in cold storage. -- * -- * @custom:oz-upgrades-unsafe-allow state-variable-immutable - */ - abstract contract EIP712 is IERC5267 { -- using ShortStrings for *; -- - bytes32 private constant TYPE_HASH = - keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); - -- // 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 _cachedDomainSeparator; -- uint256 private immutable _cachedChainId; -- address private immutable _cachedThis; -- -+ /// @custom:oz-renamed-from _HASHED_NAME - bytes32 private immutable _hashedName; -+ /// @custom:oz-renamed-from _HASHED_VERSION - bytes32 private immutable _hashedVersion; - -- ShortString private immutable _name; -- ShortString private immutable _version; -- string private _nameFallback; -- string private _versionFallback; -+ string private _name; -+ string private _version; - - /** - * @dev Initializes the domain separator and parameter caches. -@@ -64,29 +53,23 @@ abstract contract EIP712 is IERC5267 { - * contract upgrade]. - */ - constructor(string memory name, string memory version) { -- _name = name.toShortStringWithFallback(_nameFallback); -- _version = version.toShortStringWithFallback(_versionFallback); -- _hashedName = keccak256(bytes(name)); -- _hashedVersion = keccak256(bytes(version)); -- -- _cachedChainId = block.chainid; -- _cachedDomainSeparator = _buildDomainSeparator(); -- _cachedThis = address(this); -+ _name = name; -+ _version = version; -+ -+ // Reset prior values in storage if upgrading -+ _hashedName = 0; -+ _hashedVersion = 0; - } - - /** - * @dev Returns the domain separator for the current chain. - */ - function _domainSeparatorV4() internal view returns (bytes32) { -- if (address(this) == _cachedThis && block.chainid == _cachedChainId) { -- return _cachedDomainSeparator; -- } else { -- return _buildDomainSeparator(); -- } -+ return _buildDomainSeparator(); - } - - function _buildDomainSeparator() private view returns (bytes32) { -- return keccak256(abi.encode(TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this))); -+ return keccak256(abi.encode(TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash(), block.chainid, address(this))); - } - - /** -@@ -125,6 +108,10 @@ abstract contract EIP712 is IERC5267 { - uint256[] memory extensions - ) - { -+ // If the hashed name and version in storage are non-zero, the contract hasn't been properly initialized -+ // and the EIP712 domain is not reliable, as it will be missing name and version. -+ require(_hashedName == 0 && _hashedVersion == 0, "EIP712: Uninitialized"); -+ - return ( - hex"0f", // 01111 - _EIP712Name(), -@@ -139,22 +126,62 @@ abstract contract EIP712 is IERC5267 { - /** - * @dev The name parameter for the EIP712 domain. - * -- * NOTE: By default this function reads _name which is an immutable value. -- * It only reads from storage if necessary (in case the value is too large to fit in a ShortString). -+ * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs -+ * are a concern. - */ -- // solhint-disable-next-line func-name-mixedcase -- function _EIP712Name() internal view returns (string memory) { -- return _name.toStringWithFallback(_nameFallback); -+ function _EIP712Name() internal view virtual returns (string memory) { -+ return _name; - } - - /** - * @dev The version parameter for the EIP712 domain. - * -- * NOTE: By default this function reads _version which is an immutable value. -- * It only reads from storage if necessary (in case the value is too large to fit in a ShortString). -+ * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs -+ * are a concern. - */ -- // solhint-disable-next-line func-name-mixedcase -- function _EIP712Version() internal view returns (string memory) { -- return _version.toStringWithFallback(_versionFallback); -+ function _EIP712Version() internal view virtual returns (string memory) { -+ return _version; -+ } -+ -+ /** -+ * @dev The hash of the name parameter for the EIP712 domain. -+ * -+ * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Name` instead. -+ */ -+ function _EIP712NameHash() internal view returns (bytes32) { -+ string memory name = _EIP712Name(); -+ if (bytes(name).length > 0) { -+ return keccak256(bytes(name)); -+ } else { -+ // If the name is empty, the contract may have been upgraded without initializing the new storage. -+ // We return the name hash in storage if non-zero, otherwise we assume the name is empty by design. -+ bytes32 hashedName = _hashedName; -+ if (hashedName != 0) { -+ return hashedName; -+ } else { -+ return keccak256(""); -+ } -+ } -+ } -+ -+ /** -+ * @dev The hash of the version parameter for the EIP712 domain. -+ * -+ * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Version` instead. -+ */ -+ function _EIP712VersionHash() internal view returns (bytes32) { -+ string memory version = _EIP712Version(); -+ if (bytes(version).length > 0) { -+ return keccak256(bytes(version)); -+ } else { -+ // If the version is empty, the contract may have been upgraded without initializing the new storage. -+ // We return the version hash in storage if non-zero, otherwise we assume the version is empty by design. -+ bytes32 hashedVersion = _hashedVersion; -+ if (hashedVersion != 0) { -+ return hashedVersion; -+ } else { -+ return keccak256(""); -+ } -+ } - } - } -diff --git a/package.json b/package.json -index c4b358e10..96ab2559c 100644 ---- a/package.json -+++ b/package.json -@@ -32,7 +32,7 @@ - }, - "repository": { - "type": "git", -- "url": "https://github.com/OpenZeppelin/openzeppelin-contracts.git" -+ "url": "https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable.git" - }, - "keywords": [ - "solidity", -diff --git a/remappings.txt b/remappings.txt -index 304d1386a..a1cd63bee 100644 ---- a/remappings.txt -+++ b/remappings.txt -@@ -1 +1,2 @@ --@openzeppelin/contracts/=contracts/ -+@openzeppelin/contracts-upgradeable/=contracts/ -+@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/ -diff --git a/test/utils/cryptography/EIP712.test.js b/test/utils/cryptography/EIP712.test.js -index 2b6e7fa97..268e0d29d 100644 ---- a/test/utils/cryptography/EIP712.test.js -+++ b/test/utils/cryptography/EIP712.test.js -@@ -47,27 +47,6 @@ describe('EIP712', function () { - const rebuildDomain = await getDomain(this.eip712); - expect(rebuildDomain).to.be.deep.equal(this.domain); - }); -- -- if (shortOrLong === 'short') { -- // Long strings are in storage, and the proxy will not be properly initialized unless -- // the upgradeable contract variant is used and the initializer is invoked. -- -- it('adjusts when behind proxy', async function () { -- const factory = await ethers.deployContract('$Clones'); -- -- const clone = await factory -- .$clone(this.eip712) -- .then(tx => tx.wait()) -- .then(receipt => receipt.logs.find(ev => ev.fragment.name == 'return$clone_address').args.instance) -- .then(address => ethers.getContractAt('$EIP712Verifier', address)); -- -- const expectedDomain = { ...this.domain, verifyingContract: clone.target }; -- expect(await getDomain(clone)).to.be.deep.equal(expectedDomain); -- -- const expectedSeparator = await domainSeparator(expectedDomain); -- expect(await clone.$_domainSeparatorV4()).to.equal(expectedSeparator); -- }); -- } - }); - - it('hash digest', async function () { diff --git a/lib/openzeppelin-contracts/slither.config.json b/lib/openzeppelin-contracts/slither.config.json deleted file mode 100644 index 069da1f..0000000 --- a/lib/openzeppelin-contracts/slither.config.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "detectors_to_run": "arbitrary-send-erc20,array-by-reference,incorrect-shift,name-reused,rtlo,suicidal,uninitialized-state,uninitialized-storage,arbitrary-send-erc20-permit,controlled-array-length,controlled-delegatecall,delegatecall-loop,msg-value-loop,reentrancy-eth,unchecked-transfer,weak-prng,domain-separator-collision,erc20-interface,erc721-interface,locked-ether,mapping-deletion,shadowing-abstract,tautology,write-after-write,boolean-cst,reentrancy-no-eth,reused-constructor,tx-origin,unchecked-lowlevel,unchecked-send,variable-scope,void-cst,events-access,events-maths,incorrect-unary,boolean-equal,cyclomatic-complexity,deprecated-standards,erc20-indexed,function-init-state,pragma,unused-state,reentrancy-unlimited-gas,constable-states,immutable-states,var-read-using-this", - "filter_paths": "contracts/mocks,contracts-exposed", - "compile_force_framework": "hardhat" -} diff --git a/lib/openzeppelin-contracts/solhint.config.js b/lib/openzeppelin-contracts/solhint.config.js deleted file mode 100644 index f0bd799..0000000 --- a/lib/openzeppelin-contracts/solhint.config.js +++ /dev/null @@ -1,26 +0,0 @@ -const customRules = require('./scripts/solhint-custom'); - -const rules = [ - 'avoid-tx-origin', - 'const-name-snakecase', - 'contract-name-camelcase', - 'event-name-camelcase', - 'explicit-types', - 'func-name-mixedcase', - 'func-param-name-mixedcase', - 'imports-on-top', - 'modifier-name-mixedcase', - 'no-console', - 'no-global-import', - 'no-unused-vars', - 'quotes', - 'use-forbidden-name', - 'var-name-mixedcase', - 'visibility-modifier-order', - ...customRules.map(r => `openzeppelin/${r.ruleId}`), -]; - -module.exports = { - plugins: ['openzeppelin'], - rules: Object.fromEntries(rules.map(r => [r, 'error'])), -}; diff --git a/lib/openzeppelin-contracts/test/TESTING.md b/lib/openzeppelin-contracts/test/TESTING.md deleted file mode 100644 index a5ee932..0000000 --- a/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/openzeppelin-contracts/test/access/AccessControl.behavior.js b/lib/openzeppelin-contracts/test/access/AccessControl.behavior.js deleted file mode 100644 index b7ae2a9..0000000 --- a/lib/openzeppelin-contracts/test/access/AccessControl.behavior.js +++ /dev/null @@ -1,874 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); - -const time = require('../helpers/time'); - -const { shouldSupportInterfaces } = require('../utils/introspection/SupportsInterface.behavior'); - -const DEFAULT_ADMIN_ROLE = ethers.ZeroHash; -const ROLE = ethers.id('ROLE'); -const OTHER_ROLE = ethers.id('OTHER_ROLE'); - -function shouldBehaveLikeAccessControl() { - beforeEach(async function () { - [this.authorized, this.other, this.otherAdmin] = this.accounts; - }); - - shouldSupportInterfaces(['AccessControl']); - - describe('default admin', function () { - it('deployer has default admin role', async function () { - expect(await this.mock.hasRole(DEFAULT_ADMIN_ROLE, this.defaultAdmin)).to.be.true; - }); - - it("other roles's admin is the default admin role", async function () { - expect(await this.mock.getRoleAdmin(ROLE)).to.equal(DEFAULT_ADMIN_ROLE); - }); - - it("default admin role's admin is itself", async function () { - expect(await this.mock.getRoleAdmin(DEFAULT_ADMIN_ROLE)).to.equal(DEFAULT_ADMIN_ROLE); - }); - }); - - describe('granting', function () { - beforeEach(async function () { - await this.mock.connect(this.defaultAdmin).grantRole(ROLE, this.authorized); - }); - - it('non-admin cannot grant role to other accounts', async function () { - await expect(this.mock.connect(this.other).grantRole(ROLE, this.authorized)) - .to.be.revertedWithCustomError(this.mock, 'AccessControlUnauthorizedAccount') - .withArgs(this.other, DEFAULT_ADMIN_ROLE); - }); - - it('accounts can be granted a role multiple times', async function () { - await this.mock.connect(this.defaultAdmin).grantRole(ROLE, this.authorized); - await expect(this.mock.connect(this.defaultAdmin).grantRole(ROLE, this.authorized)).to.not.emit( - this.mock, - 'RoleGranted', - ); - }); - }); - - describe('revoking', function () { - it('roles that are not had can be revoked', async function () { - expect(await this.mock.hasRole(ROLE, this.authorized)).to.be.false; - - await expect(this.mock.connect(this.defaultAdmin).revokeRole(ROLE, this.authorized)).to.not.emit( - this.mock, - 'RoleRevoked', - ); - }); - - describe('with granted role', function () { - beforeEach(async function () { - await this.mock.connect(this.defaultAdmin).grantRole(ROLE, this.authorized); - }); - - it('admin can revoke role', async function () { - await expect(this.mock.connect(this.defaultAdmin).revokeRole(ROLE, this.authorized)) - .to.emit(this.mock, 'RoleRevoked') - .withArgs(ROLE, this.authorized, this.defaultAdmin); - - expect(await this.mock.hasRole(ROLE, this.authorized)).to.be.false; - }); - - it('non-admin cannot revoke role', async function () { - await expect(this.mock.connect(this.other).revokeRole(ROLE, this.authorized)) - .to.be.revertedWithCustomError(this.mock, 'AccessControlUnauthorizedAccount') - .withArgs(this.other, DEFAULT_ADMIN_ROLE); - }); - - it('a role can be revoked multiple times', async function () { - await this.mock.connect(this.defaultAdmin).revokeRole(ROLE, this.authorized); - - await expect(this.mock.connect(this.defaultAdmin).revokeRole(ROLE, this.authorized)).to.not.emit( - this.mock, - 'RoleRevoked', - ); - }); - }); - }); - - describe('renouncing', function () { - it('roles that are not had can be renounced', async function () { - await expect(this.mock.connect(this.authorized).renounceRole(ROLE, this.authorized)).to.not.emit( - this.mock, - 'RoleRevoked', - ); - }); - - describe('with granted role', function () { - beforeEach(async function () { - await this.mock.connect(this.defaultAdmin).grantRole(ROLE, this.authorized); - }); - - it('bearer can renounce role', async function () { - await expect(this.mock.connect(this.authorized).renounceRole(ROLE, this.authorized)) - .to.emit(this.mock, 'RoleRevoked') - .withArgs(ROLE, this.authorized, this.authorized); - - expect(await this.mock.hasRole(ROLE, this.authorized)).to.be.false; - }); - - it('only the sender can renounce their roles', async function () { - await expect( - this.mock.connect(this.defaultAdmin).renounceRole(ROLE, this.authorized), - ).to.be.revertedWithCustomError(this.mock, 'AccessControlBadConfirmation'); - }); - - it('a role can be renounced multiple times', async function () { - await this.mock.connect(this.authorized).renounceRole(ROLE, this.authorized); - - await expect(this.mock.connect(this.authorized).renounceRole(ROLE, this.authorized)).not.to.emit( - this.mock, - 'RoleRevoked', - ); - }); - }); - }); - - describe('setting role admin', function () { - beforeEach(async function () { - await expect(this.mock.$_setRoleAdmin(ROLE, OTHER_ROLE)) - .to.emit(this.mock, 'RoleAdminChanged') - .withArgs(ROLE, DEFAULT_ADMIN_ROLE, OTHER_ROLE); - - await this.mock.connect(this.defaultAdmin).grantRole(OTHER_ROLE, this.otherAdmin); - }); - - it("a role's admin role can be changed", async function () { - expect(await this.mock.getRoleAdmin(ROLE)).to.equal(OTHER_ROLE); - }); - - it('the new admin can grant roles', async function () { - await expect(this.mock.connect(this.otherAdmin).grantRole(ROLE, this.authorized)) - .to.emit(this.mock, 'RoleGranted') - .withArgs(ROLE, this.authorized, this.otherAdmin); - }); - - it('the new admin can revoke roles', async function () { - await this.mock.connect(this.otherAdmin).grantRole(ROLE, this.authorized); - await expect(this.mock.connect(this.otherAdmin).revokeRole(ROLE, this.authorized)) - .to.emit(this.mock, 'RoleRevoked') - .withArgs(ROLE, this.authorized, this.otherAdmin); - }); - - it("a role's previous admins no longer grant roles", async function () { - await expect(this.mock.connect(this.defaultAdmin).grantRole(ROLE, this.authorized)) - .to.be.revertedWithCustomError(this.mock, 'AccessControlUnauthorizedAccount') - .withArgs(this.defaultAdmin, OTHER_ROLE); - }); - - it("a role's previous admins no longer revoke roles", async function () { - await expect(this.mock.connect(this.defaultAdmin).revokeRole(ROLE, this.authorized)) - .to.be.revertedWithCustomError(this.mock, 'AccessControlUnauthorizedAccount') - .withArgs(this.defaultAdmin, OTHER_ROLE); - }); - }); - - describe('onlyRole modifier', function () { - beforeEach(async function () { - await this.mock.connect(this.defaultAdmin).grantRole(ROLE, this.authorized); - }); - - it('do not revert if sender has role', async function () { - await this.mock.connect(this.authorized).$_checkRole(ROLE); - }); - - it("revert if sender doesn't have role #1", async function () { - await expect(this.mock.connect(this.other).$_checkRole(ROLE)) - .to.be.revertedWithCustomError(this.mock, 'AccessControlUnauthorizedAccount') - .withArgs(this.other, ROLE); - }); - - it("revert if sender doesn't have role #2", async function () { - await expect(this.mock.connect(this.authorized).$_checkRole(OTHER_ROLE)) - .to.be.revertedWithCustomError(this.mock, 'AccessControlUnauthorizedAccount') - .withArgs(this.authorized, OTHER_ROLE); - }); - }); - - describe('internal functions', function () { - describe('_grantRole', function () { - it('return true if the account does not have the role', async function () { - await expect(this.mock.$_grantRole(ROLE, this.authorized)) - .to.emit(this.mock, 'return$_grantRole') - .withArgs(true); - }); - - it('return false if the account has the role', async function () { - await this.mock.$_grantRole(ROLE, this.authorized); - - await expect(this.mock.$_grantRole(ROLE, this.authorized)) - .to.emit(this.mock, 'return$_grantRole') - .withArgs(false); - }); - }); - - describe('_revokeRole', function () { - it('return true if the account has the role', async function () { - await this.mock.$_grantRole(ROLE, this.authorized); - - await expect(this.mock.$_revokeRole(ROLE, this.authorized)) - .to.emit(this.mock, 'return$_revokeRole') - .withArgs(true); - }); - - it('return false if the account does not have the role', async function () { - await expect(this.mock.$_revokeRole(ROLE, this.authorized)) - .to.emit(this.mock, 'return$_revokeRole') - .withArgs(false); - }); - }); - }); -} - -function shouldBehaveLikeAccessControlEnumerable() { - beforeEach(async function () { - [this.authorized, this.other, this.otherAdmin, this.otherAuthorized] = this.accounts; - }); - - shouldSupportInterfaces(['AccessControlEnumerable']); - - describe('enumerating', function () { - it('role bearers can be enumerated', async function () { - await this.mock.connect(this.defaultAdmin).grantRole(ROLE, this.authorized); - await this.mock.connect(this.defaultAdmin).grantRole(ROLE, this.other); - await this.mock.connect(this.defaultAdmin).grantRole(ROLE, this.otherAuthorized); - await this.mock.connect(this.defaultAdmin).revokeRole(ROLE, this.other); - - const expectedMembers = [this.authorized.address, this.otherAuthorized.address]; - - const memberCount = await this.mock.getRoleMemberCount(ROLE); - const members = []; - for (let i = 0; i < memberCount; ++i) { - members.push(await this.mock.getRoleMember(ROLE, i)); - } - - expect(memberCount).to.equal(expectedMembers.length); - expect(members).to.deep.equal(expectedMembers); - expect(await this.mock.getRoleMembers(ROLE)).to.deep.equal(expectedMembers); - }); - - it('role enumeration should be in sync after renounceRole call', async function () { - expect(await this.mock.getRoleMemberCount(ROLE)).to.equal(0); - await this.mock.connect(this.defaultAdmin).grantRole(ROLE, this.defaultAdmin); - expect(await this.mock.getRoleMemberCount(ROLE)).to.equal(1); - await this.mock.connect(this.defaultAdmin).renounceRole(ROLE, this.defaultAdmin); - expect(await this.mock.getRoleMemberCount(ROLE)).to.equal(0); - }); - }); -} - -function shouldBehaveLikeAccessControlDefaultAdminRules() { - shouldSupportInterfaces(['AccessControlDefaultAdminRules']); - - beforeEach(async function () { - [this.newDefaultAdmin, this.other] = this.accounts; - }); - - for (const getter of ['owner', 'defaultAdmin']) { - describe(`${getter}()`, function () { - it('has a default set to the initial default admin', async function () { - const value = await this.mock[getter](); - expect(value).to.equal(this.defaultAdmin); - expect(await this.mock.hasRole(DEFAULT_ADMIN_ROLE, value)).to.be.true; - }); - - it('changes if the default admin changes', async function () { - // Starts an admin transfer - await this.mock.connect(this.defaultAdmin).beginDefaultAdminTransfer(this.newDefaultAdmin); - - // Wait for acceptance - await time.increaseBy.timestamp(this.delay + 1n, false); - await this.mock.connect(this.newDefaultAdmin).acceptDefaultAdminTransfer(); - - const value = await this.mock[getter](); - expect(value).to.equal(this.newDefaultAdmin); - }); - }); - } - - describe('pendingDefaultAdmin()', function () { - it('returns 0 if no pending default admin transfer', async function () { - const { newAdmin, schedule } = await this.mock.pendingDefaultAdmin(); - expect(newAdmin).to.equal(ethers.ZeroAddress); - expect(schedule).to.equal(0); - }); - - describe('when there is a scheduled default admin transfer', function () { - beforeEach('begins admin transfer', async function () { - await this.mock.connect(this.defaultAdmin).beginDefaultAdminTransfer(this.newDefaultAdmin); - }); - - for (const [fromSchedule, tag] of [ - [-1n, 'before'], - [0n, 'exactly when'], - [1n, 'after'], - ]) { - it(`returns pending admin and schedule ${tag} it passes if not accepted`, async function () { - // Wait until schedule + fromSchedule - const { schedule: firstSchedule } = await this.mock.pendingDefaultAdmin(); - await time.increaseTo.timestamp(firstSchedule + fromSchedule); - - const { newAdmin, schedule } = await this.mock.pendingDefaultAdmin(); - expect(newAdmin).to.equal(this.newDefaultAdmin); - expect(schedule).to.equal(firstSchedule); - }); - } - - it('returns 0 after schedule passes and the transfer was accepted', async function () { - // Wait after schedule - const { schedule: firstSchedule } = await this.mock.pendingDefaultAdmin(); - await time.increaseTo.timestamp(firstSchedule + 1n, false); - - // Accepts - await this.mock.connect(this.newDefaultAdmin).acceptDefaultAdminTransfer(); - - const { newAdmin, schedule } = await this.mock.pendingDefaultAdmin(); - expect(newAdmin).to.equal(ethers.ZeroAddress); - expect(schedule).to.equal(0); - }); - }); - }); - - describe('defaultAdminDelay()', function () { - it('returns the current delay', async function () { - expect(await this.mock.defaultAdminDelay()).to.equal(this.delay); - }); - - describe('when there is a scheduled delay change', function () { - const newDelay = 0x1337n; // Any change - - beforeEach('begins delay change', async function () { - await this.mock.connect(this.defaultAdmin).changeDefaultAdminDelay(newDelay); - }); - - for (const [fromSchedule, tag, expectNew, delayTag] of [ - [-1n, 'before', false, 'old'], - [0n, 'exactly when', false, 'old'], - [1n, 'after', true, 'new'], - ]) { - it(`returns ${delayTag} delay ${tag} delay schedule passes`, async function () { - // Wait until schedule + fromSchedule - const { schedule } = await this.mock.pendingDefaultAdminDelay(); - await time.increaseTo.timestamp(schedule + fromSchedule); - - const currentDelay = await this.mock.defaultAdminDelay(); - expect(currentDelay).to.equal(expectNew ? newDelay : this.delay); - }); - } - }); - }); - - describe('pendingDefaultAdminDelay()', function () { - it('returns 0 if not set', async function () { - const { newDelay, schedule } = await this.mock.pendingDefaultAdminDelay(); - expect(newDelay).to.equal(0); - expect(schedule).to.equal(0); - }); - - describe('when there is a scheduled delay change', function () { - const newDelay = 0x1337n; // Any change - - beforeEach('begins admin transfer', async function () { - await this.mock.connect(this.defaultAdmin).changeDefaultAdminDelay(newDelay); - }); - - for (const [fromSchedule, tag, expectedDelay, delayTag, expectZeroSchedule] of [ - [-1n, 'before', newDelay, 'new'], - [0n, 'exactly when', newDelay, 'new'], - [1n, 'after', 0, 'zero', true], - ]) { - it(`returns ${delayTag} delay ${tag} delay schedule passes`, async function () { - // Wait until schedule + fromSchedule - const { schedule: firstSchedule } = await this.mock.pendingDefaultAdminDelay(); - await time.increaseTo.timestamp(firstSchedule + fromSchedule); - - const { newDelay, schedule } = await this.mock.pendingDefaultAdminDelay(); - expect(newDelay).to.equal(expectedDelay); - expect(schedule).to.equal(expectZeroSchedule ? 0 : firstSchedule); - }); - } - }); - }); - - describe('defaultAdminDelayIncreaseWait()', function () { - it('should return 5 days (default)', async function () { - expect(await this.mock.defaultAdminDelayIncreaseWait()).to.equal(time.duration.days(5)); - }); - }); - - it('should revert if granting default admin role', async function () { - await expect( - this.mock.connect(this.defaultAdmin).grantRole(DEFAULT_ADMIN_ROLE, this.defaultAdmin), - ).to.be.revertedWithCustomError(this.mock, 'AccessControlEnforcedDefaultAdminRules'); - }); - - it('should revert if revoking default admin role', async function () { - await expect( - this.mock.connect(this.defaultAdmin).revokeRole(DEFAULT_ADMIN_ROLE, this.defaultAdmin), - ).to.be.revertedWithCustomError(this.mock, 'AccessControlEnforcedDefaultAdminRules'); - }); - - it("should revert if defaultAdmin's admin is changed", async function () { - await expect(this.mock.$_setRoleAdmin(DEFAULT_ADMIN_ROLE, OTHER_ROLE)).to.be.revertedWithCustomError( - this.mock, - 'AccessControlEnforcedDefaultAdminRules', - ); - }); - - it('should not grant the default admin role twice', async function () { - await expect(this.mock.$_grantRole(DEFAULT_ADMIN_ROLE, this.defaultAdmin)).to.be.revertedWithCustomError( - this.mock, - 'AccessControlEnforcedDefaultAdminRules', - ); - }); - - describe('begins a default admin transfer', function () { - it('reverts if called by non default admin accounts', async function () { - await expect(this.mock.connect(this.other).beginDefaultAdminTransfer(this.newDefaultAdmin)) - .to.be.revertedWithCustomError(this.mock, 'AccessControlUnauthorizedAccount') - .withArgs(this.other, DEFAULT_ADMIN_ROLE); - }); - - describe('when there is no pending delay nor pending admin transfer', function () { - it('should set pending default admin and schedule', async function () { - const nextBlockTimestamp = (await time.clock.timestamp()) + 1n; - const acceptSchedule = nextBlockTimestamp + this.delay; - - await time.increaseTo.timestamp(nextBlockTimestamp, false); // set timestamp but don't mine the block yet - await expect(this.mock.connect(this.defaultAdmin).beginDefaultAdminTransfer(this.newDefaultAdmin)) - .to.emit(this.mock, 'DefaultAdminTransferScheduled') - .withArgs(this.newDefaultAdmin, acceptSchedule); - - const { newAdmin, schedule } = await this.mock.pendingDefaultAdmin(); - expect(newAdmin).to.equal(this.newDefaultAdmin); - expect(schedule).to.equal(acceptSchedule); - }); - }); - - describe('when there is a pending admin transfer', function () { - beforeEach('sets a pending default admin transfer', async function () { - await this.mock.connect(this.defaultAdmin).beginDefaultAdminTransfer(this.newDefaultAdmin); - this.acceptSchedule = (await time.clock.timestamp()) + this.delay; - }); - - for (const [fromSchedule, tag] of [ - [-1n, 'before'], - [0n, 'exactly when'], - [1n, 'after'], - ]) { - it(`should be able to begin a transfer again ${tag} acceptSchedule passes`, async function () { - // Wait until schedule + fromSchedule - await time.increaseTo.timestamp(this.acceptSchedule + fromSchedule, false); - - // defaultAdmin changes its mind and begin again to another address - await expect(this.mock.connect(this.defaultAdmin).beginDefaultAdminTransfer(this.other)).to.emit( - this.mock, - 'DefaultAdminTransferCanceled', // Cancellation is always emitted since it was never accepted - ); - const newSchedule = (await time.clock.timestamp()) + this.delay; - const { newAdmin, schedule } = await this.mock.pendingDefaultAdmin(); - expect(newAdmin).to.equal(this.other); - expect(schedule).to.equal(newSchedule); - }); - } - - it('should not emit a cancellation event if the new default admin accepted', async function () { - // Wait until the acceptSchedule has passed - await time.increaseTo.timestamp(this.acceptSchedule + 1n, false); - - // Accept and restart - await this.mock.connect(this.newDefaultAdmin).acceptDefaultAdminTransfer(); - await expect(this.mock.connect(this.newDefaultAdmin).beginDefaultAdminTransfer(this.other)).to.not.emit( - this.mock, - 'DefaultAdminTransferCanceled', - ); - }); - }); - - describe('when there is a pending delay', function () { - const newDelay = time.duration.hours(3); - - beforeEach('schedule a delay change', async function () { - await this.mock.connect(this.defaultAdmin).changeDefaultAdminDelay(newDelay); - ({ schedule: this.effectSchedule } = await this.mock.pendingDefaultAdminDelay()); - }); - - for (const [fromSchedule, schedulePassed, expectNewDelay] of [ - [-1n, 'before', false], - [0n, 'exactly when', false], - [1n, 'after', true], - ]) { - it(`should set the ${ - expectNewDelay ? 'new' : 'old' - } delay and apply it to next default admin transfer schedule ${schedulePassed} effectSchedule passed`, async function () { - // Wait until the expected fromSchedule time - const nextBlockTimestamp = this.effectSchedule + fromSchedule; - await time.increaseTo.timestamp(nextBlockTimestamp, false); - - // Start the new default admin transfer and get its schedule - const expectedDelay = expectNewDelay ? newDelay : this.delay; - const expectedAcceptSchedule = nextBlockTimestamp + expectedDelay; - await expect(this.mock.connect(this.defaultAdmin).beginDefaultAdminTransfer(this.newDefaultAdmin)) - .to.emit(this.mock, 'DefaultAdminTransferScheduled') - .withArgs(this.newDefaultAdmin, expectedAcceptSchedule); - - // Check that the schedule corresponds with the new delay - const { newAdmin, schedule: transferSchedule } = await this.mock.pendingDefaultAdmin(); - expect(newAdmin).to.equal(this.newDefaultAdmin); - expect(transferSchedule).to.equal(expectedAcceptSchedule); - }); - } - }); - }); - - describe('accepts transfer admin', function () { - beforeEach(async function () { - await this.mock.connect(this.defaultAdmin).beginDefaultAdminTransfer(this.newDefaultAdmin); - this.acceptSchedule = (await time.clock.timestamp()) + this.delay; - }); - - it('should revert if caller is not pending default admin', async function () { - await time.increaseTo.timestamp(this.acceptSchedule + 1n, false); - await expect(this.mock.connect(this.other).acceptDefaultAdminTransfer()) - .to.be.revertedWithCustomError(this.mock, 'AccessControlInvalidDefaultAdmin') - .withArgs(this.other); - }); - - describe('when caller is pending default admin and delay has passed', function () { - beforeEach(async function () { - await time.increaseTo.timestamp(this.acceptSchedule + 1n, false); - }); - - it('accepts a transfer and changes default admin', async function () { - // Emit events - await expect(this.mock.connect(this.newDefaultAdmin).acceptDefaultAdminTransfer()) - .to.emit(this.mock, 'RoleRevoked') - .withArgs(DEFAULT_ADMIN_ROLE, this.defaultAdmin, this.newDefaultAdmin) - .to.emit(this.mock, 'RoleGranted') - .withArgs(DEFAULT_ADMIN_ROLE, this.newDefaultAdmin, this.newDefaultAdmin); - - // Storage changes - expect(await this.mock.hasRole(DEFAULT_ADMIN_ROLE, this.defaultAdmin)).to.be.false; - expect(await this.mock.hasRole(DEFAULT_ADMIN_ROLE, this.newDefaultAdmin)).to.be.true; - expect(await this.mock.owner()).to.equal(this.newDefaultAdmin); - - // Resets pending default admin and schedule - const { newAdmin, schedule } = await this.mock.pendingDefaultAdmin(); - expect(newAdmin).to.equal(ethers.ZeroAddress); - expect(schedule).to.equal(0); - }); - }); - - describe('schedule not passed', function () { - for (const [fromSchedule, tag] of [ - [-1n, 'less'], - [0n, 'equal'], - ]) { - it(`should revert if block.timestamp is ${tag} to schedule`, async function () { - await time.increaseTo.timestamp(this.acceptSchedule + fromSchedule, false); - await expect(this.mock.connect(this.newDefaultAdmin).acceptDefaultAdminTransfer()) - .to.be.revertedWithCustomError(this.mock, 'AccessControlEnforcedDefaultAdminDelay') - .withArgs(this.acceptSchedule); - }); - } - }); - }); - - describe('cancels a default admin transfer', function () { - it('reverts if called by non default admin accounts', async function () { - await expect(this.mock.connect(this.other).cancelDefaultAdminTransfer()) - .to.be.revertedWithCustomError(this.mock, 'AccessControlUnauthorizedAccount') - .withArgs(this.other, DEFAULT_ADMIN_ROLE); - }); - - describe('when there is a pending default admin transfer', function () { - beforeEach(async function () { - await this.mock.connect(this.defaultAdmin).beginDefaultAdminTransfer(this.newDefaultAdmin); - this.acceptSchedule = (await time.clock.timestamp()) + this.delay; - }); - - for (const [fromSchedule, tag] of [ - [-1n, 'before'], - [0n, 'exactly when'], - [1n, 'after'], - ]) { - it(`resets pending default admin and schedule ${tag} transfer schedule passes`, async function () { - // Advance until passed delay - await time.increaseTo.timestamp(this.acceptSchedule + fromSchedule, false); - - await expect(this.mock.connect(this.defaultAdmin).cancelDefaultAdminTransfer()).to.emit( - this.mock, - 'DefaultAdminTransferCanceled', - ); - - const { newAdmin, schedule } = await this.mock.pendingDefaultAdmin(); - expect(newAdmin).to.equal(ethers.ZeroAddress); - expect(schedule).to.equal(0); - }); - } - - it('should revert if the previous default admin tries to accept', async function () { - await this.mock.connect(this.defaultAdmin).cancelDefaultAdminTransfer(); - - // Advance until passed delay - await time.increaseTo.timestamp(this.acceptSchedule + 1n, false); - - // Previous pending default admin should not be able to accept after cancellation. - await expect(this.mock.connect(this.newDefaultAdmin).acceptDefaultAdminTransfer()) - .to.be.revertedWithCustomError(this.mock, 'AccessControlInvalidDefaultAdmin') - .withArgs(this.newDefaultAdmin); - }); - }); - - describe('when there is no pending default admin transfer', function () { - it('should succeed without changes', async function () { - await expect(this.mock.connect(this.defaultAdmin).cancelDefaultAdminTransfer()).to.not.emit( - this.mock, - 'DefaultAdminTransferCanceled', - ); - - const { newAdmin, schedule } = await this.mock.pendingDefaultAdmin(); - expect(newAdmin).to.equal(ethers.ZeroAddress); - expect(schedule).to.equal(0); - }); - }); - }); - - describe('renounces admin', function () { - beforeEach(async function () { - await this.mock.connect(this.defaultAdmin).beginDefaultAdminTransfer(ethers.ZeroAddress); - this.expectedSchedule = (await time.clock.timestamp()) + this.delay; - }); - - it('reverts if caller is not default admin', async function () { - await time.increaseBy.timestamp(this.delay + 1n, false); - await expect( - this.mock.connect(this.defaultAdmin).renounceRole(DEFAULT_ADMIN_ROLE, this.other), - ).to.be.revertedWithCustomError(this.mock, 'AccessControlBadConfirmation'); - }); - - it("renouncing the admin role when not an admin doesn't affect the schedule", async function () { - await time.increaseBy.timestamp(this.delay + 1n, false); - await this.mock.connect(this.other).renounceRole(DEFAULT_ADMIN_ROLE, this.other); - - const { newAdmin, schedule } = await this.mock.pendingDefaultAdmin(); - expect(newAdmin).to.equal(ethers.ZeroAddress); - expect(schedule).to.equal(this.expectedSchedule); - }); - - it('keeps defaultAdmin consistent with hasRole if another non-defaultAdmin user renounces the DEFAULT_ADMIN_ROLE', async function () { - await time.increaseBy.timestamp(this.delay + 1n, false); - - // This passes because it's a noop - await this.mock.connect(this.other).renounceRole(DEFAULT_ADMIN_ROLE, this.other); - - expect(await this.mock.hasRole(DEFAULT_ADMIN_ROLE, this.defaultAdmin)).to.be.true; - expect(await this.mock.defaultAdmin()).to.equal(this.defaultAdmin); - }); - - it('renounces role', async function () { - await time.increaseBy.timestamp(this.delay + 1n, false); - await expect(this.mock.connect(this.defaultAdmin).renounceRole(DEFAULT_ADMIN_ROLE, this.defaultAdmin)) - .to.emit(this.mock, 'RoleRevoked') - .withArgs(DEFAULT_ADMIN_ROLE, this.defaultAdmin, this.defaultAdmin); - - expect(await this.mock.hasRole(DEFAULT_ADMIN_ROLE, this.defaultAdmin)).to.be.false; - expect(await this.mock.defaultAdmin()).to.equal(ethers.ZeroAddress); - expect(await this.mock.owner()).to.equal(ethers.ZeroAddress); - - const { newAdmin, schedule } = await this.mock.pendingDefaultAdmin(); - expect(newAdmin).to.equal(ethers.ZeroAddress); - expect(schedule).to.equal(0); - }); - - it('allows to recover access using the internal _grantRole', async function () { - await time.increaseBy.timestamp(this.delay + 1n, false); - await this.mock.connect(this.defaultAdmin).renounceRole(DEFAULT_ADMIN_ROLE, this.defaultAdmin); - - await expect(this.mock.connect(this.defaultAdmin).$_grantRole(DEFAULT_ADMIN_ROLE, this.other)) - .to.emit(this.mock, 'RoleGranted') - .withArgs(DEFAULT_ADMIN_ROLE, this.other, this.defaultAdmin); - }); - - describe('schedule not passed', function () { - for (const [fromSchedule, tag] of [ - [-1n, 'less'], - [0n, 'equal'], - ]) { - it(`reverts if block.timestamp is ${tag} to schedule`, async function () { - await time.increaseBy.timestamp(this.delay + fromSchedule, false); - await expect(this.mock.connect(this.defaultAdmin).renounceRole(DEFAULT_ADMIN_ROLE, this.defaultAdmin)) - .to.be.revertedWithCustomError(this.mock, 'AccessControlEnforcedDefaultAdminDelay') - .withArgs(this.expectedSchedule); - }); - } - }); - }); - - describe('changes delay', function () { - it('reverts if called by non default admin accounts', async function () { - await expect(this.mock.connect(this.other).changeDefaultAdminDelay(time.duration.hours(4))) - .to.be.revertedWithCustomError(this.mock, 'AccessControlUnauthorizedAccount') - .withArgs(this.other, DEFAULT_ADMIN_ROLE); - }); - - for (const [delayDifference, delayChangeType] of [ - [time.duration.hours(-1), 'decreased'], - [time.duration.hours(1), 'increased'], - [time.duration.days(5), 'increased to more than 5 days'], - ]) { - describe(`when the delay is ${delayChangeType}`, function () { - beforeEach(function () { - this.newDefaultAdminDelay = this.delay + delayDifference; - }); - - it('begins the delay change to the new delay', async function () { - // Calculate expected values - const capWait = await this.mock.defaultAdminDelayIncreaseWait(); - const minWait = capWait < this.newDefaultAdminDelay ? capWait : this.newDefaultAdminDelay; - const changeDelay = - this.newDefaultAdminDelay <= this.delay ? this.delay - this.newDefaultAdminDelay : minWait; - const nextBlockTimestamp = (await time.clock.timestamp()) + 1n; - const effectSchedule = nextBlockTimestamp + changeDelay; - - await time.increaseTo.timestamp(nextBlockTimestamp, false); - - // Begins the change - await expect(this.mock.connect(this.defaultAdmin).changeDefaultAdminDelay(this.newDefaultAdminDelay)) - .to.emit(this.mock, 'DefaultAdminDelayChangeScheduled') - .withArgs(this.newDefaultAdminDelay, effectSchedule); - - // Assert - const { newDelay, schedule } = await this.mock.pendingDefaultAdminDelay(); - expect(newDelay).to.equal(this.newDefaultAdminDelay); - expect(schedule).to.equal(effectSchedule); - }); - - describe('scheduling again', function () { - beforeEach('schedule once', async function () { - await this.mock.connect(this.defaultAdmin).changeDefaultAdminDelay(this.newDefaultAdminDelay); - }); - - for (const [fromSchedule, tag] of [ - [-1n, 'before'], - [0n, 'exactly when'], - [1n, 'after'], - ]) { - const passed = fromSchedule > 0; - - it(`succeeds ${tag} the delay schedule passes`, async function () { - // Wait until schedule + fromSchedule - const { schedule: firstSchedule } = await this.mock.pendingDefaultAdminDelay(); - const nextBlockTimestamp = firstSchedule + fromSchedule; - await time.increaseTo.timestamp(nextBlockTimestamp, false); - - // Calculate expected values - const anotherNewDefaultAdminDelay = this.newDefaultAdminDelay + time.duration.hours(2); - const capWait = await this.mock.defaultAdminDelayIncreaseWait(); - const minWait = capWait < anotherNewDefaultAdminDelay ? capWait : anotherNewDefaultAdminDelay; - const effectSchedule = nextBlockTimestamp + minWait; - - // Default admin changes its mind and begins another delay change - await expect(this.mock.connect(this.defaultAdmin).changeDefaultAdminDelay(anotherNewDefaultAdminDelay)) - .to.emit(this.mock, 'DefaultAdminDelayChangeScheduled') - .withArgs(anotherNewDefaultAdminDelay, effectSchedule); - - // Assert - const { newDelay, schedule } = await this.mock.pendingDefaultAdminDelay(); - expect(newDelay).to.equal(anotherNewDefaultAdminDelay); - expect(schedule).to.equal(effectSchedule); - }); - - const emit = passed ? 'not emit' : 'emit'; - it(`should ${emit} a cancellation event ${tag} the delay schedule passes`, async function () { - // Wait until schedule + fromSchedule - const { schedule: firstSchedule } = await this.mock.pendingDefaultAdminDelay(); - await time.increaseTo.timestamp(firstSchedule + fromSchedule, false); - - // Default admin changes its mind and begins another delay change - const anotherNewDefaultAdminDelay = this.newDefaultAdminDelay + time.duration.hours(2); - - const expected = expect( - this.mock.connect(this.defaultAdmin).changeDefaultAdminDelay(anotherNewDefaultAdminDelay), - ); - if (passed) { - await expected.to.not.emit(this.mock, 'DefaultAdminDelayChangeCanceled'); - } else { - await expected.to.emit(this.mock, 'DefaultAdminDelayChangeCanceled'); - } - }); - } - }); - }); - } - }); - - describe('rollbacks a delay change', function () { - it('reverts if called by non default admin accounts', async function () { - await expect(this.mock.connect(this.other).rollbackDefaultAdminDelay()) - .to.be.revertedWithCustomError(this.mock, 'AccessControlUnauthorizedAccount') - .withArgs(this.other, DEFAULT_ADMIN_ROLE); - }); - - describe('when there is a pending delay', function () { - beforeEach('set pending delay', async function () { - await this.mock.connect(this.defaultAdmin).changeDefaultAdminDelay(time.duration.hours(12)); - }); - - for (const [fromSchedule, tag] of [ - [-1n, 'before'], - [0n, 'exactly when'], - [1n, 'after'], - ]) { - const passed = fromSchedule > 0; - - it(`resets pending delay and schedule ${tag} delay change schedule passes`, async function () { - // Wait until schedule + fromSchedule - const { schedule: firstSchedule } = await this.mock.pendingDefaultAdminDelay(); - await time.increaseTo.timestamp(firstSchedule + fromSchedule, false); - - await this.mock.connect(this.defaultAdmin).rollbackDefaultAdminDelay(); - - const { newDelay, schedule } = await this.mock.pendingDefaultAdminDelay(); - expect(newDelay).to.equal(0); - expect(schedule).to.equal(0); - }); - - const emit = passed ? 'not emit' : 'emit'; - it(`should ${emit} a cancellation event ${tag} the delay schedule passes`, async function () { - // Wait until schedule + fromSchedule - const { schedule: firstSchedule } = await this.mock.pendingDefaultAdminDelay(); - await time.increaseTo.timestamp(firstSchedule + fromSchedule, false); - - const expected = expect(this.mock.connect(this.defaultAdmin).rollbackDefaultAdminDelay()); - if (passed) { - await expected.to.not.emit(this.mock, 'DefaultAdminDelayChangeCanceled'); - } else { - await expected.to.emit(this.mock, 'DefaultAdminDelayChangeCanceled'); - } - }); - } - }); - - describe('when there is no pending delay', function () { - it('succeeds without changes', async function () { - await this.mock.connect(this.defaultAdmin).rollbackDefaultAdminDelay(); - - const { newDelay, schedule } = await this.mock.pendingDefaultAdminDelay(); - expect(newDelay).to.equal(0); - expect(schedule).to.equal(0); - }); - }); - }); -} - -module.exports = { - DEFAULT_ADMIN_ROLE, - shouldBehaveLikeAccessControl, - shouldBehaveLikeAccessControlEnumerable, - shouldBehaveLikeAccessControlDefaultAdminRules, -}; diff --git a/lib/openzeppelin-contracts/test/access/AccessControl.test.js b/lib/openzeppelin-contracts/test/access/AccessControl.test.js deleted file mode 100644 index 5c70cdc..0000000 --- a/lib/openzeppelin-contracts/test/access/AccessControl.test.js +++ /dev/null @@ -1,19 +0,0 @@ -const { ethers } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { DEFAULT_ADMIN_ROLE, shouldBehaveLikeAccessControl } = require('./AccessControl.behavior'); - -async function fixture() { - const [defaultAdmin, ...accounts] = await ethers.getSigners(); - const mock = await ethers.deployContract('$AccessControl'); - await mock.$_grantRole(DEFAULT_ADMIN_ROLE, defaultAdmin); - return { mock, defaultAdmin, accounts }; -} - -describe('AccessControl', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - shouldBehaveLikeAccessControl(); -}); diff --git a/lib/openzeppelin-contracts/test/access/Ownable.test.js b/lib/openzeppelin-contracts/test/access/Ownable.test.js deleted file mode 100644 index 2d9b561..0000000 --- a/lib/openzeppelin-contracts/test/access/Ownable.test.js +++ /dev/null @@ -1,79 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -async function fixture() { - const [owner, other] = await ethers.getSigners(); - const ownable = await ethers.deployContract('$Ownable', [owner]); - return { owner, other, ownable }; -} - -describe('Ownable', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - it('emits ownership transfer events during construction', async function () { - await expect(this.ownable.deploymentTransaction()) - .to.emit(this.ownable, 'OwnershipTransferred') - .withArgs(ethers.ZeroAddress, this.owner); - }); - - it('rejects zero address for initialOwner', async function () { - await expect(ethers.deployContract('$Ownable', [ethers.ZeroAddress])) - .to.be.revertedWithCustomError({ interface: this.ownable.interface }, 'OwnableInvalidOwner') - .withArgs(ethers.ZeroAddress); - }); - - it('has an owner', async function () { - expect(await this.ownable.owner()).to.equal(this.owner); - }); - - describe('transfer ownership', function () { - it('changes owner after transfer', async function () { - await expect(this.ownable.connect(this.owner).transferOwnership(this.other)) - .to.emit(this.ownable, 'OwnershipTransferred') - .withArgs(this.owner, this.other); - - expect(await this.ownable.owner()).to.equal(this.other); - }); - - it('prevents non-owners from transferring', async function () { - await expect(this.ownable.connect(this.other).transferOwnership(this.other)) - .to.be.revertedWithCustomError(this.ownable, 'OwnableUnauthorizedAccount') - .withArgs(this.other); - }); - - it('guards ownership against stuck state', async function () { - await expect(this.ownable.connect(this.owner).transferOwnership(ethers.ZeroAddress)) - .to.be.revertedWithCustomError(this.ownable, 'OwnableInvalidOwner') - .withArgs(ethers.ZeroAddress); - }); - }); - - describe('renounce ownership', function () { - it('loses ownership after renouncement', async function () { - await expect(this.ownable.connect(this.owner).renounceOwnership()) - .to.emit(this.ownable, 'OwnershipTransferred') - .withArgs(this.owner, ethers.ZeroAddress); - - expect(await this.ownable.owner()).to.equal(ethers.ZeroAddress); - }); - - it('prevents non-owners from renouncement', async function () { - await expect(this.ownable.connect(this.other).renounceOwnership()) - .to.be.revertedWithCustomError(this.ownable, 'OwnableUnauthorizedAccount') - .withArgs(this.other); - }); - - it('allows to recover access using the internal _transferOwnership', async function () { - await this.ownable.connect(this.owner).renounceOwnership(); - - await expect(this.ownable.$_transferOwnership(this.other)) - .to.emit(this.ownable, 'OwnershipTransferred') - .withArgs(ethers.ZeroAddress, this.other); - - expect(await this.ownable.owner()).to.equal(this.other); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/access/Ownable2Step.test.js b/lib/openzeppelin-contracts/test/access/Ownable2Step.test.js deleted file mode 100644 index 4c49e21..0000000 --- a/lib/openzeppelin-contracts/test/access/Ownable2Step.test.js +++ /dev/null @@ -1,85 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -async function fixture() { - const [owner, accountA, accountB] = await ethers.getSigners(); - const ownable2Step = await ethers.deployContract('$Ownable2Step', [owner]); - return { - ownable2Step, - owner, - accountA, - accountB, - }; -} - -describe('Ownable2Step', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('transfer ownership', function () { - it('starting a transfer does not change owner', async function () { - await expect(this.ownable2Step.connect(this.owner).transferOwnership(this.accountA)) - .to.emit(this.ownable2Step, 'OwnershipTransferStarted') - .withArgs(this.owner, this.accountA); - - expect(await this.ownable2Step.owner()).to.equal(this.owner); - expect(await this.ownable2Step.pendingOwner()).to.equal(this.accountA); - }); - - it('changes owner after transfer', async function () { - await this.ownable2Step.connect(this.owner).transferOwnership(this.accountA); - - await expect(this.ownable2Step.connect(this.accountA).acceptOwnership()) - .to.emit(this.ownable2Step, 'OwnershipTransferred') - .withArgs(this.owner, this.accountA); - - expect(await this.ownable2Step.owner()).to.equal(this.accountA); - expect(await this.ownable2Step.pendingOwner()).to.equal(ethers.ZeroAddress); - }); - - it('guards transfer against invalid user', async function () { - await this.ownable2Step.connect(this.owner).transferOwnership(this.accountA); - - await expect(this.ownable2Step.connect(this.accountB).acceptOwnership()) - .to.be.revertedWithCustomError(this.ownable2Step, 'OwnableUnauthorizedAccount') - .withArgs(this.accountB); - }); - }); - - describe('renouncing ownership', function () { - it('changes owner after renouncing ownership', async function () { - await expect(this.ownable2Step.connect(this.owner).renounceOwnership()) - .to.emit(this.ownable2Step, 'OwnershipTransferred') - .withArgs(this.owner, ethers.ZeroAddress); - - // 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(ethers.ZeroAddress); - }); - - it('pending owner resets after renouncing ownership', async function () { - await this.ownable2Step.connect(this.owner).transferOwnership(this.accountA); - expect(await this.ownable2Step.pendingOwner()).to.equal(this.accountA); - - await this.ownable2Step.connect(this.owner).renounceOwnership(); - expect(await this.ownable2Step.pendingOwner()).to.equal(ethers.ZeroAddress); - - await expect(this.ownable2Step.connect(this.accountA).acceptOwnership()) - .to.be.revertedWithCustomError(this.ownable2Step, 'OwnableUnauthorizedAccount') - .withArgs(this.accountA); - }); - - it('allows to recover access using the internal _transferOwnership', async function () { - await this.ownable2Step.connect(this.owner).renounceOwnership(); - - await expect(this.ownable2Step.$_transferOwnership(this.accountA)) - .to.emit(this.ownable2Step, 'OwnershipTransferred') - .withArgs(ethers.ZeroAddress, this.accountA); - - expect(await this.ownable2Step.owner()).to.equal(this.accountA); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/access/extensions/AccessControlDefaultAdminRules.test.js b/lib/openzeppelin-contracts/test/access/extensions/AccessControlDefaultAdminRules.test.js deleted file mode 100644 index 48036fd..0000000 --- a/lib/openzeppelin-contracts/test/access/extensions/AccessControlDefaultAdminRules.test.js +++ /dev/null @@ -1,32 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const time = require('../../helpers/time'); - -const { - shouldBehaveLikeAccessControl, - shouldBehaveLikeAccessControlDefaultAdminRules, -} = require('../AccessControl.behavior'); - -async function fixture() { - const delay = time.duration.hours(10); - const [defaultAdmin, ...accounts] = await ethers.getSigners(); - const mock = await ethers.deployContract('$AccessControlDefaultAdminRules', [delay, defaultAdmin]); - return { mock, defaultAdmin, delay, accounts }; -} - -describe('AccessControlDefaultAdminRules', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - it('initial admin not zero', async function () { - await expect(ethers.deployContract('$AccessControlDefaultAdminRules', [this.delay, ethers.ZeroAddress])) - .to.be.revertedWithCustomError(this.mock, 'AccessControlInvalidDefaultAdmin') - .withArgs(ethers.ZeroAddress); - }); - - shouldBehaveLikeAccessControl(); - shouldBehaveLikeAccessControlDefaultAdminRules(); -}); diff --git a/lib/openzeppelin-contracts/test/access/extensions/AccessControlEnumerable.test.js b/lib/openzeppelin-contracts/test/access/extensions/AccessControlEnumerable.test.js deleted file mode 100644 index ea1a8c4..0000000 --- a/lib/openzeppelin-contracts/test/access/extensions/AccessControlEnumerable.test.js +++ /dev/null @@ -1,24 +0,0 @@ -const { ethers } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { - DEFAULT_ADMIN_ROLE, - shouldBehaveLikeAccessControl, - shouldBehaveLikeAccessControlEnumerable, -} = require('../AccessControl.behavior'); - -async function fixture() { - const [defaultAdmin, ...accounts] = await ethers.getSigners(); - const mock = await ethers.deployContract('$AccessControlEnumerable'); - await mock.$_grantRole(DEFAULT_ADMIN_ROLE, defaultAdmin); - return { mock, defaultAdmin, accounts }; -} - -describe('AccessControlEnumerable', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - shouldBehaveLikeAccessControl(); - shouldBehaveLikeAccessControlEnumerable(); -}); diff --git a/lib/openzeppelin-contracts/test/access/manager/AccessManaged.test.js b/lib/openzeppelin-contracts/test/access/manager/AccessManaged.test.js deleted file mode 100644 index d666b5e..0000000 --- a/lib/openzeppelin-contracts/test/access/manager/AccessManaged.test.js +++ /dev/null @@ -1,146 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { impersonate } = require('../../helpers/account'); -const time = require('../../helpers/time'); - -async function fixture() { - const [admin, roleMember, other] = await ethers.getSigners(); - - const authority = await ethers.deployContract('$AccessManager', [admin]); - const managed = await ethers.deployContract('$AccessManagedTarget', [authority]); - - const anotherAuthority = await ethers.deployContract('$AccessManager', [admin]); - const authorityObserveIsConsuming = await ethers.deployContract('$AuthorityObserveIsConsuming'); - - await impersonate(authority.target); - const authorityAsSigner = await ethers.getSigner(authority.target); - - return { - roleMember, - other, - authorityAsSigner, - authority, - managed, - authorityObserveIsConsuming, - anotherAuthority, - }; -} - -describe('AccessManaged', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - it('sets authority and emits AuthorityUpdated event during construction', async function () { - await expect(this.managed.deploymentTransaction()) - .to.emit(this.managed, 'AuthorityUpdated') - .withArgs(this.authority); - }); - - describe('restricted modifier', function () { - beforeEach(async function () { - this.selector = this.managed.fnRestricted.getFragment().selector; - this.role = 42n; - await this.authority.$_setTargetFunctionRole(this.managed, this.selector, this.role); - await this.authority.$_grantRole(this.role, this.roleMember, 0, 0); - }); - - it('succeeds when role is granted without execution delay', async function () { - await this.managed.connect(this.roleMember)[this.selector](); - }); - - it('reverts when role is not granted', async function () { - await expect(this.managed.connect(this.other)[this.selector]()) - .to.be.revertedWithCustomError(this.managed, 'AccessManagedUnauthorized') - .withArgs(this.other); - }); - - it('panics in short calldata', async function () { - // We avoid adding the `restricted` modifier to the fallback function because other tests may depend on it - // being accessible without restrictions. We check for the internal `_checkCanCall` instead. - await expect(this.managed.$_checkCanCall(this.roleMember, '0x1234')).to.be.reverted; - }); - - describe('when role is granted with execution delay', function () { - beforeEach(async function () { - const executionDelay = 911n; - await this.authority.$_grantRole(this.role, this.roleMember, 0, executionDelay); - }); - - it('reverts if the operation is not scheduled', async function () { - const fn = this.managed.interface.getFunction(this.selector); - const calldata = this.managed.interface.encodeFunctionData(fn, []); - const opId = await this.authority.hashOperation(this.roleMember, this.managed, calldata); - - await expect(this.managed.connect(this.roleMember)[this.selector]()) - .to.be.revertedWithCustomError(this.authority, 'AccessManagerNotScheduled') - .withArgs(opId); - }); - - it('succeeds if the operation is scheduled', async function () { - // Arguments - const delay = time.duration.hours(12); - const fn = this.managed.interface.getFunction(this.selector); - const calldata = this.managed.interface.encodeFunctionData(fn, []); - - // Schedule - const scheduledAt = (await time.clock.timestamp()) + 1n; - const when = scheduledAt + delay; - await time.increaseTo.timestamp(scheduledAt, false); - await this.authority.connect(this.roleMember).schedule(this.managed, calldata, when); - - // Set execution date - await time.increaseTo.timestamp(when, false); - - // Shouldn't revert - await this.managed.connect(this.roleMember)[this.selector](); - }); - }); - }); - - describe('setAuthority', function () { - it('reverts if the caller is not the authority', async function () { - await expect(this.managed.connect(this.other).setAuthority(this.other)) - .to.be.revertedWithCustomError(this.managed, 'AccessManagedUnauthorized') - .withArgs(this.other); - }); - - it('reverts if the new authority is not a valid authority', async function () { - await expect(this.managed.connect(this.authorityAsSigner).setAuthority(this.other)) - .to.be.revertedWithCustomError(this.managed, 'AccessManagedInvalidAuthority') - .withArgs(this.other); - }); - - it('sets authority and emits AuthorityUpdated event', async function () { - await expect(this.managed.connect(this.authorityAsSigner).setAuthority(this.anotherAuthority)) - .to.emit(this.managed, 'AuthorityUpdated') - .withArgs(this.anotherAuthority); - - expect(await this.managed.authority()).to.equal(this.anotherAuthority); - }); - }); - - describe('isConsumingScheduledOp', function () { - beforeEach(async function () { - await this.managed.connect(this.authorityAsSigner).setAuthority(this.authorityObserveIsConsuming); - }); - - it('returns bytes4(0) when not consuming operation', async function () { - expect(await this.managed.isConsumingScheduledOp()).to.equal('0x00000000'); - }); - - it('returns isConsumingScheduledOp selector when consuming operation', async function () { - const isConsumingScheduledOp = this.managed.interface.getFunction('isConsumingScheduledOp()'); - const fnRestricted = this.managed.fnRestricted.getFragment(); - await expect(this.managed.connect(this.other).fnRestricted()) - .to.emit(this.authorityObserveIsConsuming, 'ConsumeScheduledOpCalled') - .withArgs( - this.other, - this.managed.interface.encodeFunctionData(fnRestricted, []), - isConsumingScheduledOp.selector, - ); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/access/manager/AccessManager.behavior.js b/lib/openzeppelin-contracts/test/access/manager/AccessManager.behavior.js deleted file mode 100644 index 385da57..0000000 --- a/lib/openzeppelin-contracts/test/access/manager/AccessManager.behavior.js +++ /dev/null @@ -1,257 +0,0 @@ -const { expect } = require('chai'); - -const { - LIKE_COMMON_IS_EXECUTING, - LIKE_COMMON_GET_ACCESS, - LIKE_COMMON_SCHEDULABLE, - testAsSchedulableOperation, - testAsRestrictedOperation, - testAsDelayedOperation, - testAsCanCall, - testAsHasRole, -} = require('./AccessManager.predicate'); - -// ============ ADMIN OPERATION ============ - -/** - * @requires this.{manager,roles,calldata,role} - */ -function shouldBehaveLikeDelayedAdminOperation() { - const getAccessPath = LIKE_COMMON_GET_ACCESS; - testAsDelayedOperation.mineDelay = true; - getAccessPath.requiredRoleIsGranted.roleGrantingIsDelayed.callerHasAnExecutionDelay.afterGrantDelay = - testAsDelayedOperation; - getAccessPath.requiredRoleIsGranted.roleGrantingIsNotDelayed.callerHasAnExecutionDelay = function () { - beforeEach('set execution delay', async function () { - this.scheduleIn = this.executionDelay; // For testAsDelayedOperation - }); - testAsSchedulableOperation(LIKE_COMMON_SCHEDULABLE); - }; - - beforeEach('set target as manager', function () { - this.target = this.manager; - }); - - testAsRestrictedOperation({ - callerIsTheManager: LIKE_COMMON_IS_EXECUTING, - callerIsNotTheManager() { - testAsHasRole({ - publicRoleIsRequired() { - it('reverts as AccessManagerUnauthorizedAccount', async function () { - await expect(this.caller.sendTransaction({ to: this.target, data: this.calldata })) - .to.be.revertedWithCustomError(this.target, 'AccessManagerUnauthorizedAccount') - .withArgs( - this.caller, - this.roles.ADMIN.id, // Although PUBLIC is required, target function role doesn't apply to admin ops - ); - }); - }, - specificRoleIsRequired: getAccessPath, - }); - }, - }); -} - -/** - * @requires this.{manager,roles,calldata,role} - */ -function shouldBehaveLikeNotDelayedAdminOperation() { - const getAccessPath = LIKE_COMMON_GET_ACCESS; - - function testScheduleOperation(mineDelay) { - return function self() { - self.mineDelay = mineDelay; - beforeEach('set execution delay', async function () { - this.scheduleIn = this.executionDelay; // For testAsSchedulableOperation - }); - testAsSchedulableOperation(LIKE_COMMON_SCHEDULABLE); - }; - } - - getAccessPath.requiredRoleIsGranted.roleGrantingIsDelayed.callerHasAnExecutionDelay.afterGrantDelay = - testScheduleOperation(true); - getAccessPath.requiredRoleIsGranted.roleGrantingIsNotDelayed.callerHasAnExecutionDelay = testScheduleOperation(false); - - beforeEach('set target as manager', function () { - this.target = this.manager; - }); - - testAsRestrictedOperation({ - callerIsTheManager: LIKE_COMMON_IS_EXECUTING, - callerIsNotTheManager() { - testAsHasRole({ - publicRoleIsRequired() { - it('reverts as AccessManagerUnauthorizedAccount', async function () { - await expect(this.caller.sendTransaction({ to: this.target, data: this.calldata })) - .to.be.revertedWithCustomError(this.target, 'AccessManagerUnauthorizedAccount') - .withArgs( - this.caller, - this.roles.ADMIN.id, // Although PUBLIC_ROLE is required, admin ops are not subject to target function roles - ); - }); - }, - specificRoleIsRequired: getAccessPath, - }); - }, - }); -} - -/** - * @requires this.{manager,roles,calldata,role} - */ -function shouldBehaveLikeRoleAdminOperation(roleAdmin) { - const getAccessPath = LIKE_COMMON_GET_ACCESS; - - function afterGrantDelay() { - afterGrantDelay.mineDelay = true; - beforeEach('set execution delay', async function () { - this.scheduleIn = this.executionDelay; // For testAsSchedulableOperation - }); - testAsSchedulableOperation(LIKE_COMMON_SCHEDULABLE); - } - - getAccessPath.requiredRoleIsGranted.roleGrantingIsDelayed.callerHasAnExecutionDelay.afterGrantDelay = afterGrantDelay; - getAccessPath.requiredRoleIsGranted.roleGrantingIsNotDelayed.callerHasAnExecutionDelay = afterGrantDelay; - - beforeEach('set target as manager', function () { - this.target = this.manager; - }); - - testAsRestrictedOperation({ - callerIsTheManager: LIKE_COMMON_IS_EXECUTING, - callerIsNotTheManager() { - testAsHasRole({ - publicRoleIsRequired() { - it('reverts as AccessManagerUnauthorizedAccount', async function () { - await expect(this.caller.sendTransaction({ to: this.target, data: this.calldata })) - .to.be.revertedWithCustomError(this.target, 'AccessManagerUnauthorizedAccount') - .withArgs(this.caller, roleAdmin); - }); - }, - specificRoleIsRequired: getAccessPath, - }); - }, - }); -} - -// ============ RESTRICTED OPERATION ============ - -/** - * @requires this.{manager,roles,calldata,role} - */ -function shouldBehaveLikeAManagedRestrictedOperation() { - function revertUnauthorized() { - it('reverts as AccessManagedUnauthorized', async function () { - await expect(this.caller.sendTransaction({ to: this.target, data: this.calldata })) - .to.be.revertedWithCustomError(this.target, 'AccessManagedUnauthorized') - .withArgs(this.caller); - }); - } - - const getAccessPath = LIKE_COMMON_GET_ACCESS; - - getAccessPath.requiredRoleIsGranted.roleGrantingIsDelayed.callerHasAnExecutionDelay.beforeGrantDelay = - revertUnauthorized; - getAccessPath.requiredRoleIsGranted.roleGrantingIsDelayed.callerHasNoExecutionDelay.beforeGrantDelay = - revertUnauthorized; - getAccessPath.requiredRoleIsNotGranted = revertUnauthorized; - - function testScheduleOperation(mineDelay) { - return function self() { - self.mineDelay = mineDelay; - beforeEach('sets execution delay', async function () { - this.scheduleIn = this.executionDelay; // For testAsSchedulableOperation - }); - testAsSchedulableOperation(LIKE_COMMON_SCHEDULABLE); - }; - } - - getAccessPath.requiredRoleIsGranted.roleGrantingIsDelayed.callerHasAnExecutionDelay.afterGrantDelay = - testScheduleOperation(true); - getAccessPath.requiredRoleIsGranted.roleGrantingIsNotDelayed.callerHasAnExecutionDelay = testScheduleOperation(false); - - const isExecutingPath = LIKE_COMMON_IS_EXECUTING; - isExecutingPath.notExecuting = revertUnauthorized; - - testAsCanCall({ - closed: revertUnauthorized, - open: { - callerIsTheManager: isExecutingPath, - callerIsNotTheManager: { - publicRoleIsRequired() { - it('succeeds called directly', async function () { - await this.caller.sendTransaction({ to: this.target, data: this.calldata }); - }); - - it('succeeds via execute', async function () { - await this.manager.connect(this.caller).execute(this.target, this.calldata); - }); - }, - specificRoleIsRequired: getAccessPath, - }, - }, - }); -} - -/** - * @requires this.{target,manager,roles,calldata,role} - */ -function shouldBehaveLikeASelfRestrictedOperation() { - function revertUnauthorized() { - it('reverts as AccessManagerUnauthorizedAccount', async function () { - await expect(this.caller.sendTransaction({ to: this.target, data: this.calldata })) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerUnauthorizedAccount') - .withArgs(this.caller, this.role?.id ?? 0n); - }); - } - - const getAccessPath = LIKE_COMMON_GET_ACCESS; - - function testScheduleOperation(mineDelay) { - return function self() { - self.mineDelay = mineDelay; - beforeEach('sets execution delay', async function () { - this.scheduleIn = this.executionDelay; // For testAsSchedulableOperation - }); - testAsSchedulableOperation(LIKE_COMMON_SCHEDULABLE); - }; - } - - getAccessPath.requiredRoleIsGranted.roleGrantingIsDelayed.callerHasAnExecutionDelay.afterGrantDelay = - testScheduleOperation(true); - getAccessPath.requiredRoleIsGranted.roleGrantingIsNotDelayed.callerHasAnExecutionDelay = testScheduleOperation(false); - - beforeEach('set target as manager', function () { - this.target = this.manager; - }); - - const isExecutingPath = LIKE_COMMON_IS_EXECUTING; - isExecutingPath.notExecuting = revertUnauthorized; - - testAsCanCall({ - closed: revertUnauthorized, - open: { - callerIsTheManager: isExecutingPath, - callerIsNotTheManager: { - publicRoleIsRequired() { - it('succeeds called directly', async function () { - await this.caller.sendTransaction({ to: this.target, data: this.calldata }); - }); - - it('succeeds via execute', async function () { - await this.manager.connect(this.caller).execute(this.target, this.calldata); - }); - }, - specificRoleIsRequired: getAccessPath, - }, - }, - }); -} - -module.exports = { - shouldBehaveLikeDelayedAdminOperation, - shouldBehaveLikeNotDelayedAdminOperation, - shouldBehaveLikeRoleAdminOperation, - shouldBehaveLikeAManagedRestrictedOperation, - shouldBehaveLikeASelfRestrictedOperation, -}; diff --git a/lib/openzeppelin-contracts/test/access/manager/AccessManager.predicate.js b/lib/openzeppelin-contracts/test/access/manager/AccessManager.predicate.js deleted file mode 100644 index 8b4c5f4..0000000 --- a/lib/openzeppelin-contracts/test/access/manager/AccessManager.predicate.js +++ /dev/null @@ -1,456 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { setStorageAt } = require('@nomicfoundation/hardhat-network-helpers'); - -const { EXECUTION_ID_STORAGE_SLOT, EXPIRATION, prepareOperation } = require('../../helpers/access-manager'); -const { impersonate } = require('../../helpers/account'); -const time = require('../../helpers/time'); - -// ============ COMMON PREDICATES ============ - -const LIKE_COMMON_IS_EXECUTING = { - executing() { - it('succeeds', async function () { - await this.caller.sendTransaction({ to: this.target, data: this.calldata }); - }); - }, - notExecuting() { - it('reverts as AccessManagerUnauthorizedAccount', async function () { - await expect(this.caller.sendTransaction({ to: this.target, data: this.calldata })) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerUnauthorizedAccount') - .withArgs(this.caller, this.role.id); - }); - }, -}; - -const LIKE_COMMON_GET_ACCESS = { - requiredRoleIsGranted: { - roleGrantingIsDelayed: { - callerHasAnExecutionDelay: { - beforeGrantDelay() { - it('reverts as AccessManagerUnauthorizedAccount', async function () { - await expect(this.caller.sendTransaction({ to: this.target, data: this.calldata })) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerUnauthorizedAccount') - .withArgs(this.caller, this.role.id); - }); - }, - afterGrantDelay: undefined, // Diverges if there's an operation delay or not - }, - callerHasNoExecutionDelay: { - beforeGrantDelay() { - it('reverts as AccessManagerUnauthorizedAccount', async function () { - await expect(this.caller.sendTransaction({ to: this.target, data: this.calldata })) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerUnauthorizedAccount') - .withArgs(this.caller, this.role.id); - }); - }, - afterGrantDelay() { - it('succeeds called directly', async function () { - await this.caller.sendTransaction({ to: this.target, data: this.calldata }); - }); - - it('succeeds via execute', async function () { - await this.manager.connect(this.caller).execute(this.target, this.calldata); - }); - }, - }, - }, - roleGrantingIsNotDelayed: { - callerHasAnExecutionDelay: undefined, // Diverges if there's an operation to schedule or not - callerHasNoExecutionDelay() { - it('succeeds called directly', async function () { - await this.caller.sendTransaction({ to: this.target, data: this.calldata }); - }); - - it('succeeds via execute', async function () { - await this.manager.connect(this.caller).execute(this.target, this.calldata); - }); - }, - }, - }, - requiredRoleIsNotGranted() { - it('reverts as AccessManagerUnauthorizedAccount', async function () { - await expect(this.caller.sendTransaction({ to: this.target, data: this.calldata })) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerUnauthorizedAccount') - .withArgs(this.caller, this.role.id); - }); - }, -}; - -const LIKE_COMMON_SCHEDULABLE = { - scheduled: { - before() { - it('reverts as AccessManagerNotReady', async function () { - await expect(this.caller.sendTransaction({ to: this.target, data: this.calldata })) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerNotReady') - .withArgs(this.operationId); - }); - }, - after() { - it('succeeds called directly', async function () { - await this.caller.sendTransaction({ to: this.target, data: this.calldata }); - }); - - it('succeeds via execute', async function () { - await this.manager.connect(this.caller).execute(this.target, this.calldata); - }); - }, - expired() { - it('reverts as AccessManagerExpired', async function () { - await expect(this.caller.sendTransaction({ to: this.target, data: this.calldata })) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerExpired') - .withArgs(this.operationId); - }); - }, - }, - notScheduled() { - it('reverts as AccessManagerNotScheduled', async function () { - await expect(this.caller.sendTransaction({ to: this.target, data: this.calldata })) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerNotScheduled') - .withArgs(this.operationId); - }); - }, -}; - -// ============ MODE ============ - -/** - * @requires this.{manager,target} - */ -function testAsClosable({ closed, open }) { - describe('when the manager is closed', function () { - beforeEach('close', async function () { - await this.manager.$_setTargetClosed(this.target, true); - }); - - closed(); - }); - - describe('when the manager is open', function () { - beforeEach('open', async function () { - await this.manager.$_setTargetClosed(this.target, false); - }); - - open(); - }); -} - -// ============ DELAY ============ - -/** - * @requires this.{delay} - */ -function testAsDelay(type, { before, after }) { - beforeEach('define timestamp when delay takes effect', async function () { - const timestamp = await time.clock.timestamp(); - this.delayEffect = timestamp + this.delay; - }); - - describe(`when ${type} delay has not taken effect yet`, function () { - beforeEach(`set next block timestamp before ${type} takes effect`, async function () { - await time.increaseTo.timestamp(this.delayEffect - 1n, !!before.mineDelay); - }); - - before(); - }); - - describe(`when ${type} delay has taken effect`, function () { - beforeEach(`set next block timestamp when ${type} takes effect`, async function () { - await time.increaseTo.timestamp(this.delayEffect, !!after.mineDelay); - }); - - after(); - }); -} - -// ============ OPERATION ============ - -/** - * @requires this.{manager,scheduleIn,caller,target,calldata} - */ -function testAsSchedulableOperation({ scheduled: { before, after, expired }, notScheduled }) { - describe('when operation is scheduled', function () { - beforeEach('schedule operation', async function () { - if (this.caller.target) { - await impersonate(this.caller.target); - this.caller = await ethers.getSigner(this.caller.target); - } - const { operationId, schedule } = await prepareOperation(this.manager, { - caller: this.caller, - target: this.target, - calldata: this.calldata, - delay: this.scheduleIn, - }); - await schedule(); - this.operationId = operationId; - }); - - describe('when operation is not ready for execution', function () { - beforeEach('set next block time before operation is ready', async function () { - this.scheduledAt = await time.clock.timestamp(); - const schedule = await this.manager.getSchedule(this.operationId); - await time.increaseTo.timestamp(schedule - 1n, !!before.mineDelay); - }); - - before(); - }); - - describe('when operation is ready for execution', function () { - beforeEach('set next block time when operation is ready for execution', async function () { - this.scheduledAt = await time.clock.timestamp(); - const schedule = await this.manager.getSchedule(this.operationId); - await time.increaseTo.timestamp(schedule, !!after.mineDelay); - }); - - after(); - }); - - describe('when operation has expired', function () { - beforeEach('set next block time when operation expired', async function () { - this.scheduledAt = await time.clock.timestamp(); - const schedule = await this.manager.getSchedule(this.operationId); - await time.increaseTo.timestamp(schedule + EXPIRATION, !!expired.mineDelay); - }); - - expired(); - }); - }); - - describe('when operation is not scheduled', function () { - beforeEach('set expected operationId', async function () { - this.operationId = await this.manager.hashOperation(this.caller, this.target, this.calldata); - - // Assert operation is not scheduled - expect(await this.manager.getSchedule(this.operationId)).to.equal(0n); - }); - - notScheduled(); - }); -} - -/** - * @requires this.{manager,roles,target,calldata} - */ -function testAsRestrictedOperation({ callerIsTheManager: { executing, notExecuting }, callerIsNotTheManager }) { - describe('when the call comes from the manager (msg.sender == manager)', function () { - beforeEach('define caller as manager', async function () { - this.caller = this.manager; - if (this.caller.target) { - await impersonate(this.caller.target); - this.caller = await ethers.getSigner(this.caller.target); - } - }); - - describe('when _executionId is in storage for target and selector', function () { - beforeEach('set _executionId flag from calldata and target', async function () { - const executionId = ethers.keccak256( - ethers.AbiCoder.defaultAbiCoder().encode( - ['address', 'bytes4'], - [this.target.target, this.calldata.substring(0, 10)], - ), - ); - await setStorageAt(this.manager.target, EXECUTION_ID_STORAGE_SLOT, executionId); - }); - - executing(); - }); - - describe('when _executionId does not match target and selector', notExecuting); - }); - - describe('when the call does not come from the manager (msg.sender != manager)', function () { - beforeEach('define non manager caller', function () { - this.caller = this.roles.SOME.members[0]; - }); - - callerIsNotTheManager(); - }); -} - -/** - * @requires this.{manager,scheduleIn,caller,target,calldata,executionDelay} - */ -function testAsDelayedOperation() { - describe('with operation delay', function () { - describe('when operation delay is greater than execution delay', function () { - beforeEach('set operation delay', async function () { - this.operationDelay = this.executionDelay + time.duration.hours(1); - await this.manager.$_setTargetAdminDelay(this.target, this.operationDelay); - this.scheduleIn = this.operationDelay; // For testAsSchedulableOperation - }); - - testAsSchedulableOperation(LIKE_COMMON_SCHEDULABLE); - }); - - describe('when operation delay is shorter than execution delay', function () { - beforeEach('set operation delay', async function () { - this.operationDelay = this.executionDelay - time.duration.hours(1); - await this.manager.$_setTargetAdminDelay(this.target, this.operationDelay); - this.scheduleIn = this.executionDelay; // For testAsSchedulableOperation - }); - - testAsSchedulableOperation(LIKE_COMMON_SCHEDULABLE); - }); - }); - - describe('without operation delay', function () { - beforeEach('set operation delay', async function () { - this.operationDelay = 0n; - await this.manager.$_setTargetAdminDelay(this.target, this.operationDelay); - this.scheduleIn = this.executionDelay; // For testAsSchedulableOperation - }); - - testAsSchedulableOperation(LIKE_COMMON_SCHEDULABLE); - }); -} - -// ============ METHOD ============ - -/** - * @requires this.{manager,roles,role,target,calldata} - */ -function testAsCanCall({ - closed, - open: { - callerIsTheManager, - callerIsNotTheManager: { publicRoleIsRequired, specificRoleIsRequired }, - }, -}) { - testAsClosable({ - closed, - open() { - testAsRestrictedOperation({ - callerIsTheManager, - callerIsNotTheManager() { - testAsHasRole({ - publicRoleIsRequired, - specificRoleIsRequired, - }); - }, - }); - }, - }); -} - -/** - * @requires this.{target,calldata,roles,role} - */ -function testAsHasRole({ publicRoleIsRequired, specificRoleIsRequired }) { - describe('when the function requires the caller to be granted with the PUBLIC_ROLE', function () { - beforeEach('set target function role as PUBLIC_ROLE', async function () { - this.role = this.roles.PUBLIC; - await this.manager - .connect(this.roles.ADMIN.members[0]) - .$_setTargetFunctionRole(this.target, this.calldata.substring(0, 10), this.role.id); - }); - - publicRoleIsRequired(); - }); - - describe('when the function requires the caller to be granted with a role other than PUBLIC_ROLE', function () { - beforeEach('set target function role as PUBLIC_ROLE', async function () { - await this.manager - .connect(this.roles.ADMIN.members[0]) - .$_setTargetFunctionRole(this.target, this.calldata.substring(0, 10), this.role.id); - }); - - testAsGetAccess(specificRoleIsRequired); - }); -} - -/** - * @requires this.{manager,role,caller} - */ -function testAsGetAccess({ - requiredRoleIsGranted: { - roleGrantingIsDelayed: { - // Because both grant and execution delay are set within the same $_grantRole call - // it's not possible to create a set of tests that diverge between grant and execution delay. - // Therefore, the testAsDelay arguments are renamed for clarity: - // before => beforeGrantDelay - // after => afterGrantDelay - callerHasAnExecutionDelay: { beforeGrantDelay: case1, afterGrantDelay: case2 }, - callerHasNoExecutionDelay: { beforeGrantDelay: case3, afterGrantDelay: case4 }, - }, - roleGrantingIsNotDelayed: { callerHasAnExecutionDelay: case5, callerHasNoExecutionDelay: case6 }, - }, - requiredRoleIsNotGranted, -}) { - describe('when the required role is granted to the caller', function () { - describe('when role granting is delayed', function () { - beforeEach('define delay', function () { - this.grantDelay = time.duration.minutes(3); - this.delay = this.grantDelay; // For testAsDelay - }); - - describe('when caller has an execution delay', function () { - beforeEach('set role and delay', async function () { - this.executionDelay = time.duration.hours(10); - this.delay = this.grantDelay; - await this.manager.$_grantRole(this.role.id, this.caller, this.grantDelay, this.executionDelay); - }); - - testAsDelay('grant', { before: case1, after: case2 }); - }); - - describe('when caller has no execution delay', function () { - beforeEach('set role and delay', async function () { - this.executionDelay = 0n; - await this.manager.$_grantRole(this.role.id, this.caller, this.grantDelay, this.executionDelay); - }); - - testAsDelay('grant', { before: case3, after: case4 }); - }); - }); - - describe('when role granting is not delayed', function () { - beforeEach('define delay', function () { - this.grantDelay = 0n; - }); - - describe('when caller has an execution delay', function () { - beforeEach('set role and delay', async function () { - this.executionDelay = time.duration.hours(10); - await this.manager.$_grantRole(this.role.id, this.caller, this.grantDelay, this.executionDelay); - }); - - case5(); - }); - - describe('when caller has no execution delay', function () { - beforeEach('set role and delay', async function () { - this.executionDelay = 0n; - await this.manager.$_grantRole(this.role.id, this.caller, this.grantDelay, this.executionDelay); - }); - - case6(); - }); - }); - }); - - describe('when role is not granted', function () { - // Because this helper can be composed with other helpers, it's possible - // that role has been set already by another helper. - // Although this is highly unlikely, we check for it here to avoid false positives. - beforeEach('assert role is unset', async function () { - const { since } = await this.manager.getAccess(this.role.id, this.caller); - expect(since).to.equal(0n); - }); - - requiredRoleIsNotGranted(); - }); -} - -module.exports = { - LIKE_COMMON_IS_EXECUTING, - LIKE_COMMON_GET_ACCESS, - LIKE_COMMON_SCHEDULABLE, - testAsClosable, - testAsDelay, - testAsSchedulableOperation, - testAsRestrictedOperation, - testAsDelayedOperation, - testAsCanCall, - testAsHasRole, - testAsGetAccess, -}; diff --git a/lib/openzeppelin-contracts/test/access/manager/AccessManager.test.js b/lib/openzeppelin-contracts/test/access/manager/AccessManager.test.js deleted file mode 100644 index 7726831..0000000 --- a/lib/openzeppelin-contracts/test/access/manager/AccessManager.test.js +++ /dev/null @@ -1,2489 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { impersonate } = require('../../helpers/account'); -const { MAX_UINT48 } = require('../../helpers/constants'); -const { selector } = require('../../helpers/methods'); -const time = require('../../helpers/time'); - -const { - buildBaseRoles, - formatAccess, - EXPIRATION, - MINSETBACK, - EXECUTION_ID_STORAGE_SLOT, - CONSUMING_SCHEDULE_STORAGE_SLOT, - prepareOperation, - hashOperation, -} = require('../../helpers/access-manager'); - -const { - shouldBehaveLikeDelayedAdminOperation, - shouldBehaveLikeNotDelayedAdminOperation, - shouldBehaveLikeRoleAdminOperation, - shouldBehaveLikeAManagedRestrictedOperation, - shouldBehaveLikeASelfRestrictedOperation, -} = require('./AccessManager.behavior'); - -const { - LIKE_COMMON_SCHEDULABLE, - testAsClosable, - testAsDelay, - testAsSchedulableOperation, - testAsCanCall, - testAsHasRole, - testAsGetAccess, -} = require('./AccessManager.predicate'); - -async function fixture() { - const [admin, roleAdmin, roleGuardian, member, user, other] = await ethers.getSigners(); - - // Build roles - const roles = buildBaseRoles(); - - // Add members - roles.ADMIN.members = [admin]; - roles.SOME_ADMIN.members = [roleAdmin]; - roles.SOME_GUARDIAN.members = [roleGuardian]; - roles.SOME.members = [member]; - roles.PUBLIC.members = [admin, roleAdmin, roleGuardian, member, user, other]; - - const manager = await ethers.deployContract('$AccessManagerMock', [admin]); - const target = await ethers.deployContract('$AccessManagedTarget', [manager]); - - for (const { id: roleId, admin, guardian, members } of Object.values(roles)) { - if (roleId === roles.PUBLIC.id) continue; // Every address belong to public and is locked - if (roleId === roles.ADMIN.id) continue; // Admin set during construction and is locked - - // Set admin role avoiding default - if (admin.id !== roles.ADMIN.id) { - await manager.$_setRoleAdmin(roleId, admin.id); - } - - // Set guardian role avoiding default - if (guardian.id !== roles.ADMIN.id) { - await manager.$_setRoleGuardian(roleId, guardian.id); - } - - // Grant role to members - for (const member of members) { - await manager.$_grantRole(roleId, member, 0, 0); - } - } - - return { - admin, - roleAdmin, - user, - other, - roles, - manager, - target, - }; -} - -// This test suite is made using the following tools: -// -// * Predicates: Functions with common conditional setups without assertions. -// * Behaviors: Functions with common assertions. -// -// The behavioral tests are built by composing predicates and are used as templates -// for testing access to restricted functions. -// -// Similarly, unit tests in this suite will use predicates to test subsets of these -// behaviors and are helped by common assertions provided for some of the predicates. -// -// The predicates can be identified by the `testAs*` prefix while the behaviors -// are prefixed with `shouldBehave*`. The common assertions for predicates are -// defined as constants. -describe('AccessManager', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('during construction', function () { - it('grants admin role to initialAdmin', async function () { - const manager = await ethers.deployContract('$AccessManager', [this.other]); - expect(await manager.hasRole(this.roles.ADMIN.id, this.other).then(formatAccess)).to.be.deep.equal([true, '0']); - }); - - it('rejects zero address for initialAdmin', async function () { - await expect(ethers.deployContract('$AccessManager', [ethers.ZeroAddress])) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerInvalidInitialAdmin') - .withArgs(ethers.ZeroAddress); - }); - - it('initializes setup roles correctly', async function () { - for (const { id: roleId, admin, guardian, members } of Object.values(this.roles)) { - expect(await this.manager.getRoleAdmin(roleId)).to.equal(admin.id); - expect(await this.manager.getRoleGuardian(roleId)).to.equal(guardian.id); - - for (const user of this.roles.PUBLIC.members) { - expect(await this.manager.hasRole(roleId, user).then(formatAccess)).to.be.deep.equal([ - members.includes(user), - '0', - ]); - } - } - }); - }); - - describe('getters', function () { - describe('#canCall', function () { - beforeEach('set calldata', function () { - this.calldata = '0x12345678'; - this.role = { id: 379204n }; - }); - - testAsCanCall({ - closed() { - it('should return false and no delay', async function () { - const { immediate, delay } = await this.manager.canCall( - this.other, - this.target, - this.calldata.substring(0, 10), - ); - expect(immediate).to.be.false; - expect(delay).to.equal(0n); - }); - }, - open: { - callerIsTheManager: { - executing() { - it('should return true and no delay', async function () { - const { immediate, delay } = await this.manager.canCall( - this.caller, - this.target, - this.calldata.substring(0, 10), - ); - expect(immediate).to.be.true; - expect(delay).to.equal(0n); - }); - }, - notExecuting() { - it('should return false and no delay', async function () { - const { immediate, delay } = await this.manager.canCall( - this.caller, - this.target, - this.calldata.substring(0, 10), - ); - expect(immediate).to.be.false; - expect(delay).to.equal(0n); - }); - }, - }, - callerIsNotTheManager: { - publicRoleIsRequired() { - it('should return true and no delay', async function () { - const { immediate, delay } = await this.manager.canCall( - this.caller, - this.target, - this.calldata.substring(0, 10), - ); - expect(immediate).to.be.true; - expect(delay).to.equal(0n); - }); - }, - specificRoleIsRequired: { - requiredRoleIsGranted: { - roleGrantingIsDelayed: { - callerHasAnExecutionDelay: { - beforeGrantDelay: function self() { - self.mineDelay = true; - - it('should return false and no execution delay', async function () { - const { immediate, delay } = await this.manager.canCall( - this.caller, - this.target, - this.calldata.substring(0, 10), - ); - expect(immediate).to.be.false; - expect(delay).to.equal(0n); - }); - }, - afterGrantDelay: function self() { - self.mineDelay = true; - - beforeEach('sets execution delay', function () { - this.scheduleIn = this.executionDelay; // For testAsSchedulableOperation - }); - - testAsSchedulableOperation({ - scheduled: { - before: function self() { - self.mineDelay = true; - - it('should return false and execution delay', async function () { - const { immediate, delay } = await this.manager.canCall( - this.caller, - this.target, - this.calldata.substring(0, 10), - ); - expect(immediate).to.be.false; - expect(delay).to.equal(this.executionDelay); - }); - }, - after: function self() { - self.mineDelay = true; - - it('should return false and execution delay', async function () { - const { immediate, delay } = await this.manager.canCall( - this.caller, - this.target, - this.calldata.substring(0, 10), - ); - expect(immediate).to.be.false; - expect(delay).to.equal(this.executionDelay); - }); - }, - expired: function self() { - self.mineDelay = true; - - it('should return false and execution delay', async function () { - const { immediate, delay } = await this.manager.canCall( - this.caller, - this.target, - this.calldata.substring(0, 10), - ); - expect(immediate).to.be.false; - expect(delay).to.equal(this.executionDelay); - }); - }, - }, - notScheduled() { - it('should return false and execution delay', async function () { - const { immediate, delay } = await this.manager.canCall( - this.caller, - this.target, - this.calldata.substring(0, 10), - ); - expect(immediate).to.be.false; - expect(delay).to.equal(this.executionDelay); - }); - }, - }); - }, - }, - callerHasNoExecutionDelay: { - beforeGrantDelay: function self() { - self.mineDelay = true; - - it('should return false and no execution delay', async function () { - const { immediate, delay } = await this.manager.canCall( - this.caller, - this.target, - this.calldata.substring(0, 10), - ); - expect(immediate).to.be.false; - expect(delay).to.equal(0n); - }); - }, - afterGrantDelay: function self() { - self.mineDelay = true; - - it('should return true and no execution delay', async function () { - const { immediate, delay } = await this.manager.canCall( - this.caller, - this.target, - this.calldata.substring(0, 10), - ); - expect(immediate).to.be.true; - expect(delay).to.equal(0n); - }); - }, - }, - }, - roleGrantingIsNotDelayed: { - callerHasAnExecutionDelay() { - it('should return false and execution delay', async function () { - const { immediate, delay } = await this.manager.canCall( - this.caller, - this.target, - this.calldata.substring(0, 10), - ); - expect(immediate).to.be.false; - expect(delay).to.equal(this.executionDelay); - }); - }, - callerHasNoExecutionDelay() { - it('should return true and no execution delay', async function () { - const { immediate, delay } = await this.manager.canCall( - this.caller, - this.target, - this.calldata.substring(0, 10), - ); - expect(immediate).to.be.true; - expect(delay).to.equal(0n); - }); - }, - }, - }, - requiredRoleIsNotGranted() { - it('should return false and no execution delay', async function () { - const { immediate, delay } = await this.manager.canCall( - this.caller, - this.target, - this.calldata.substring(0, 10), - ); - expect(immediate).to.be.false; - expect(delay).to.equal(0n); - }); - }, - }, - }, - }, - }); - }); - - describe('#expiration', function () { - it('has a 7 days default expiration', async function () { - expect(await this.manager.expiration()).to.equal(EXPIRATION); - }); - }); - - describe('#minSetback', function () { - it('has a 5 days default minimum setback', async function () { - expect(await this.manager.minSetback()).to.equal(MINSETBACK); - }); - }); - - describe('#isTargetClosed', function () { - testAsClosable({ - closed() { - it('returns true', async function () { - expect(await this.manager.isTargetClosed(this.target)).to.be.true; - }); - }, - open() { - it('returns false', async function () { - expect(await this.manager.isTargetClosed(this.target)).to.be.false; - }); - }, - }); - }); - - describe('#getTargetFunctionRole', function () { - const methodSelector = selector('something(address,bytes)'); - - it('returns the target function role', async function () { - const roleId = 21498n; - await this.manager.$_setTargetFunctionRole(this.target, methodSelector, roleId); - - expect(await this.manager.getTargetFunctionRole(this.target, methodSelector)).to.equal(roleId); - }); - - it('returns the ADMIN role if not set', async function () { - expect(await this.manager.getTargetFunctionRole(this.target, methodSelector)).to.equal(this.roles.ADMIN.id); - }); - }); - - describe('#getTargetAdminDelay', function () { - describe('when the target admin delay is setup', function () { - beforeEach('set target admin delay', async function () { - this.oldDelay = await this.manager.getTargetAdminDelay(this.target); - this.newDelay = time.duration.days(10); - - await this.manager.$_setTargetAdminDelay(this.target, this.newDelay); - this.delay = MINSETBACK; // For testAsDelay - }); - - testAsDelay('effect', { - before: function self() { - self.mineDelay = true; - - it('returns the old target admin delay', async function () { - expect(await this.manager.getTargetAdminDelay(this.target)).to.equal(this.oldDelay); - }); - }, - after: function self() { - self.mineDelay = true; - - it('returns the new target admin delay', async function () { - expect(await this.manager.getTargetAdminDelay(this.target)).to.equal(this.newDelay); - }); - }, - }); - }); - - it('returns the 0 if not set', async function () { - expect(await this.manager.getTargetAdminDelay(this.target)).to.equal(0n); - }); - }); - - describe('#getRoleAdmin', function () { - const roleId = 5234907n; - - it('returns the role admin', async function () { - const adminId = 789433n; - - await this.manager.$_setRoleAdmin(roleId, adminId); - - expect(await this.manager.getRoleAdmin(roleId)).to.equal(adminId); - }); - - it('returns the ADMIN role if not set', async function () { - expect(await this.manager.getRoleAdmin(roleId)).to.equal(this.roles.ADMIN.id); - }); - }); - - describe('#getRoleGuardian', function () { - const roleId = 5234907n; - - it('returns the role guardian', async function () { - const guardianId = 789433n; - - await this.manager.$_setRoleGuardian(roleId, guardianId); - - expect(await this.manager.getRoleGuardian(roleId)).to.equal(guardianId); - }); - - it('returns the ADMIN role if not set', async function () { - expect(await this.manager.getRoleGuardian(roleId)).to.equal(this.roles.ADMIN.id); - }); - }); - - describe('#getRoleGrantDelay', function () { - const roleId = 9248439n; - - describe('when the grant admin delay is setup', function () { - beforeEach('set grant admin delay', async function () { - this.oldDelay = await this.manager.getRoleGrantDelay(roleId); - this.newDelay = time.duration.days(11); - - await this.manager.$_setGrantDelay(roleId, this.newDelay); - this.delay = MINSETBACK; // For testAsDelay - }); - - testAsDelay('grant', { - before: function self() { - self.mineDelay = true; - - it('returns the old role grant delay', async function () { - expect(await this.manager.getRoleGrantDelay(roleId)).to.equal(this.oldDelay); - }); - }, - after: function self() { - self.mineDelay = true; - - it('returns the new role grant delay', async function () { - expect(await this.manager.getRoleGrantDelay(roleId)).to.equal(this.newDelay); - }); - }, - }); - }); - - it('returns 0 if delay is not set', async function () { - expect(await this.manager.getTargetAdminDelay(this.target)).to.equal(0n); - }); - }); - - describe('#getAccess', function () { - beforeEach('set role', function () { - this.role = { id: 9452n }; - this.caller = this.user; - }); - - testAsGetAccess({ - requiredRoleIsGranted: { - roleGrantingIsDelayed: { - callerHasAnExecutionDelay: { - beforeGrantDelay: function self() { - self.mineDelay = true; - - it('role is not in effect and execution delay is set', async function () { - const access = await this.manager.getAccess(this.role.id, this.caller); - expect(access[0]).to.equal(this.delayEffect); // inEffectSince - expect(access[1]).to.equal(this.executionDelay); // currentDelay - expect(access[2]).to.equal(0n); // pendingDelay - expect(access[3]).to.equal(0n); // pendingDelayEffect - - // Not in effect yet - expect(await time.clock.timestamp()).to.lt(access[0]); - }); - }, - afterGrantDelay: function self() { - self.mineDelay = true; - - it('access has role in effect and execution delay is set', async function () { - const access = await this.manager.getAccess(this.role.id, this.caller); - - expect(access[0]).to.equal(this.delayEffect); // inEffectSince - expect(access[1]).to.equal(this.executionDelay); // currentDelay - expect(access[2]).to.equal(0n); // pendingDelay - expect(access[3]).to.equal(0n); // pendingDelayEffect - - // Already in effect - expect(await time.clock.timestamp()).to.equal(access[0]); - }); - }, - }, - callerHasNoExecutionDelay: { - beforeGrantDelay: function self() { - self.mineDelay = true; - - it('access has role not in effect without execution delay', async function () { - const access = await this.manager.getAccess(this.role.id, this.caller); - expect(access[0]).to.equal(this.delayEffect); // inEffectSince - expect(access[1]).to.equal(0n); // currentDelay - expect(access[2]).to.equal(0n); // pendingDelay - expect(access[3]).to.equal(0n); // pendingDelayEffect - - // Not in effect yet - expect(await time.clock.timestamp()).to.lt(access[0]); - }); - }, - afterGrantDelay: function self() { - self.mineDelay = true; - - it('role is in effect without execution delay', async function () { - const access = await this.manager.getAccess(this.role.id, this.caller); - expect(access[0]).to.equal(this.delayEffect); // inEffectSince - expect(access[1]).to.equal(0n); // currentDelay - expect(access[2]).to.equal(0n); // pendingDelay - expect(access[3]).to.equal(0n); // pendingDelayEffect - - // Already in effect - expect(await time.clock.timestamp()).to.equal(access[0]); - }); - }, - }, - }, - roleGrantingIsNotDelayed: { - callerHasAnExecutionDelay() { - it('access has role in effect and execution delay is set', async function () { - const access = await this.manager.getAccess(this.role.id, this.caller); - expect(access[0]).to.equal(await time.clock.timestamp()); // inEffectSince - expect(access[1]).to.equal(this.executionDelay); // currentDelay - expect(access[2]).to.equal(0n); // pendingDelay - expect(access[3]).to.equal(0n); // pendingDelayEffect - - // Already in effect - expect(await time.clock.timestamp()).to.equal(access[0]); - }); - }, - callerHasNoExecutionDelay() { - it('access has role in effect without execution delay', async function () { - const access = await this.manager.getAccess(this.role.id, this.caller); - expect(access[0]).to.equal(await time.clock.timestamp()); // inEffectSince - expect(access[1]).to.equal(0n); // currentDelay - expect(access[2]).to.equal(0n); // pendingDelay - expect(access[3]).to.equal(0n); // pendingDelayEffect - - // Already in effect - expect(await time.clock.timestamp()).to.equal(access[0]); - }); - }, - }, - }, - requiredRoleIsNotGranted() { - it('has empty access', async function () { - const access = await this.manager.getAccess(this.role.id, this.caller); - expect(access[0]).to.equal(0n); // inEffectSince - expect(access[1]).to.equal(0n); // currentDelay - expect(access[2]).to.equal(0n); // pendingDelay - expect(access[3]).to.equal(0n); // pendingDelayEffect - }); - }, - }); - }); - - describe('#hasRole', function () { - beforeEach('setup testAsHasRole', function () { - this.role = { id: 49832n }; - this.calldata = '0x12345678'; - this.caller = this.user; - }); - - testAsHasRole({ - publicRoleIsRequired() { - it('has PUBLIC role', async function () { - const { isMember, executionDelay } = await this.manager.hasRole(this.role.id, this.caller); - expect(isMember).to.be.true; - expect(executionDelay).to.equal('0'); - }); - }, - specificRoleIsRequired: { - requiredRoleIsGranted: { - roleGrantingIsDelayed: { - callerHasAnExecutionDelay: { - beforeGrantDelay: function self() { - self.mineDelay = true; - - it('does not have role but execution delay', async function () { - const { isMember, executionDelay } = await this.manager.hasRole(this.role.id, this.caller); - expect(isMember).to.be.false; - expect(executionDelay).to.equal(this.executionDelay); - }); - }, - afterGrantDelay: function self() { - self.mineDelay = true; - - it('has role and execution delay', async function () { - const { isMember, executionDelay } = await this.manager.hasRole(this.role.id, this.caller); - expect(isMember).to.be.true; - expect(executionDelay).to.equal(this.executionDelay); - }); - }, - }, - callerHasNoExecutionDelay: { - beforeGrantDelay: function self() { - self.mineDelay = true; - - it('does not have role nor execution delay', async function () { - const { isMember, executionDelay } = await this.manager.hasRole(this.role.id, this.caller); - expect(isMember).to.be.false; - expect(executionDelay).to.equal('0'); - }); - }, - afterGrantDelay: function self() { - self.mineDelay = true; - - it('has role and no execution delay', async function () { - const { isMember, executionDelay } = await this.manager.hasRole(this.role.id, this.caller); - expect(isMember).to.be.true; - expect(executionDelay).to.equal('0'); - }); - }, - }, - }, - roleGrantingIsNotDelayed: { - callerHasAnExecutionDelay() { - it('has role and execution delay', async function () { - const { isMember, executionDelay } = await this.manager.hasRole(this.role.id, this.caller); - expect(isMember).to.be.true; - expect(executionDelay).to.equal(this.executionDelay); - }); - }, - callerHasNoExecutionDelay() { - it('has role and no execution delay', async function () { - const { isMember, executionDelay } = await this.manager.hasRole(this.role.id, this.caller); - expect(isMember).to.be.true; - expect(executionDelay).to.equal('0'); - }); - }, - }, - }, - requiredRoleIsNotGranted() { - it('has no role and no execution delay', async function () { - const { isMember, executionDelay } = await this.manager.hasRole(this.role.id, this.caller); - expect(isMember).to.be.false; - expect(executionDelay).to.equal('0'); - }); - }, - }, - }); - }); - - describe('#getSchedule', function () { - beforeEach('set role and calldata', async function () { - const fnRestricted = this.target.fnRestricted.getFragment().selector; - this.caller = this.user; - this.role = { id: 493590n }; - await this.manager.$_setTargetFunctionRole(this.target, fnRestricted, this.role.id); - await this.manager.$_grantRole(this.role.id, this.caller, 0, 1); // nonzero execution delay - - this.calldata = this.target.interface.encodeFunctionData(fnRestricted, []); - this.scheduleIn = time.duration.days(10); // For testAsSchedulableOperation - }); - - testAsSchedulableOperation({ - scheduled: { - before: function self() { - self.mineDelay = true; - - it('returns schedule in the future', async function () { - const schedule = await this.manager.getSchedule(this.operationId); - expect(schedule).to.equal(this.scheduledAt + this.scheduleIn); - expect(schedule).to.gt(await time.clock.timestamp()); - }); - }, - after: function self() { - self.mineDelay = true; - - it('returns schedule', async function () { - const schedule = await this.manager.getSchedule(this.operationId); - expect(schedule).to.equal(this.scheduledAt + this.scheduleIn); - expect(schedule).to.equal(await time.clock.timestamp()); - }); - }, - expired: function self() { - self.mineDelay = true; - - it('returns 0', async function () { - expect(await this.manager.getSchedule(this.operationId)).to.equal(0n); - }); - }, - }, - notScheduled() { - it('defaults to 0', async function () { - expect(await this.manager.getSchedule(this.operationId)).to.equal(0n); - }); - }, - }); - }); - - describe('#getNonce', function () { - describe('when operation is scheduled', function () { - beforeEach('schedule operation', async function () { - const fnRestricted = this.target.fnRestricted.getFragment().selector; - this.caller = this.user; - this.role = { id: 4209043n }; - await this.manager.$_setTargetFunctionRole(this.target, fnRestricted, this.role.id); - await this.manager.$_grantRole(this.role.id, this.caller, 0, 1); // nonzero execution delay - - this.calldata = this.target.interface.encodeFunctionData(fnRestricted, []); - this.delay = time.duration.days(10); - - const { operationId, schedule } = await prepareOperation(this.manager, { - caller: this.caller, - target: this.target, - calldata: this.calldata, - delay: this.delay, - }); - await schedule(); - this.operationId = operationId; - }); - - it('returns nonce', async function () { - expect(await this.manager.getNonce(this.operationId)).to.equal(1n); - }); - }); - - describe('when is not scheduled', function () { - it('returns default 0', async function () { - expect(await this.manager.getNonce(ethers.id('operation'))).to.equal(0n); - }); - }); - }); - - describe('#hashOperation', function () { - it('returns an operationId', async function () { - const args = [this.user, this.other, '0x123543']; - expect(await this.manager.hashOperation(...args)).to.equal(hashOperation(...args)); - }); - }); - }); - - describe('admin operations', function () { - beforeEach('set required role', function () { - this.role = this.roles.ADMIN; - }); - - describe('subject to a delay', function () { - describe('#labelRole', function () { - describe('restrictions', function () { - beforeEach('set method and args', function () { - const args = [123443, 'TEST']; - const method = this.manager.interface.getFunction('labelRole(uint64,string)'); - this.calldata = this.manager.interface.encodeFunctionData(method, args); - }); - - shouldBehaveLikeDelayedAdminOperation(); - }); - - it('emits an event with the label', async function () { - await expect(this.manager.connect(this.admin).labelRole(this.roles.SOME.id, 'Some label')) - .to.emit(this.manager, 'RoleLabel') - .withArgs(this.roles.SOME.id, 'Some label'); - }); - - it('updates label on a second call', async function () { - await this.manager.connect(this.admin).labelRole(this.roles.SOME.id, 'Some label'); - - await expect(this.manager.connect(this.admin).labelRole(this.roles.SOME.id, 'Updated label')) - .to.emit(this.manager, 'RoleLabel') - .withArgs(this.roles.SOME.id, 'Updated label'); - }); - - it('reverts labeling PUBLIC_ROLE', async function () { - await expect(this.manager.connect(this.admin).labelRole(this.roles.PUBLIC.id, 'Some label')) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerLockedRole') - .withArgs(this.roles.PUBLIC.id); - }); - - it('reverts labeling ADMIN_ROLE', async function () { - await expect(this.manager.connect(this.admin).labelRole(this.roles.ADMIN.id, 'Some label')) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerLockedRole') - .withArgs(this.roles.ADMIN.id); - }); - }); - - describe('#setRoleAdmin', function () { - describe('restrictions', function () { - beforeEach('set method and args', function () { - const args = [93445, 84532]; - const method = this.manager.interface.getFunction('setRoleAdmin(uint64,uint64)'); - this.calldata = this.manager.interface.encodeFunctionData(method, args); - }); - - shouldBehaveLikeDelayedAdminOperation(); - }); - - it("sets any role's admin if called by an admin", async function () { - expect(await this.manager.getRoleAdmin(this.roles.SOME.id)).to.equal(this.roles.SOME_ADMIN.id); - - await expect(this.manager.connect(this.admin).setRoleAdmin(this.roles.SOME.id, this.roles.ADMIN.id)) - .to.emit(this.manager, 'RoleAdminChanged') - .withArgs(this.roles.SOME.id, this.roles.ADMIN.id); - - expect(await this.manager.getRoleAdmin(this.roles.SOME.id)).to.equal(this.roles.ADMIN.id); - }); - - it('reverts setting PUBLIC_ROLE admin', async function () { - await expect(this.manager.connect(this.admin).setRoleAdmin(this.roles.PUBLIC.id, this.roles.ADMIN.id)) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerLockedRole') - .withArgs(this.roles.PUBLIC.id); - }); - - it('reverts setting ADMIN_ROLE admin', async function () { - await expect(this.manager.connect(this.admin).setRoleAdmin(this.roles.ADMIN.id, this.roles.ADMIN.id)) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerLockedRole') - .withArgs(this.roles.ADMIN.id); - }); - }); - - describe('#setRoleGuardian', function () { - describe('restrictions', function () { - beforeEach('set method and args', function () { - const args = [93445, 84532]; - const method = this.manager.interface.getFunction('setRoleGuardian(uint64,uint64)'); - this.calldata = this.manager.interface.encodeFunctionData(method, args); - }); - - shouldBehaveLikeDelayedAdminOperation(); - }); - - it("sets any role's guardian if called by an admin", async function () { - expect(await this.manager.getRoleGuardian(this.roles.SOME.id)).to.equal(this.roles.SOME_GUARDIAN.id); - - await expect(this.manager.connect(this.admin).setRoleGuardian(this.roles.SOME.id, this.roles.ADMIN.id)) - .to.emit(this.manager, 'RoleGuardianChanged') - .withArgs(this.roles.SOME.id, this.roles.ADMIN.id); - - expect(await this.manager.getRoleGuardian(this.roles.SOME.id)).to.equal(this.roles.ADMIN.id); - }); - - it('reverts setting PUBLIC_ROLE admin', async function () { - await expect(this.manager.connect(this.admin).setRoleGuardian(this.roles.PUBLIC.id, this.roles.ADMIN.id)) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerLockedRole') - .withArgs(this.roles.PUBLIC.id); - }); - - it('reverts setting ADMIN_ROLE admin', async function () { - await expect(this.manager.connect(this.admin).setRoleGuardian(this.roles.ADMIN.id, this.roles.ADMIN.id)) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerLockedRole') - .withArgs(this.roles.ADMIN.id); - }); - }); - - describe('#setGrantDelay', function () { - describe('restrictions', function () { - beforeEach('set method and args', function () { - const args = [984910, time.duration.days(2)]; - const method = this.manager.interface.getFunction('setGrantDelay(uint64,uint32)'); - this.calldata = this.manager.interface.encodeFunctionData(method, args); - }); - - shouldBehaveLikeDelayedAdminOperation(); - }); - - it('reverts setting grant delay for the PUBLIC_ROLE', async function () { - await expect(this.manager.connect(this.admin).setGrantDelay(this.roles.PUBLIC.id, 69n)) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerLockedRole') - .withArgs(this.roles.PUBLIC.id); - }); - - describe('when increasing the delay', function () { - const oldDelay = 10n; - const newDelay = 100n; - - beforeEach('sets old delay', async function () { - this.role = this.roles.SOME; - await this.manager.$_setGrantDelay(this.role.id, oldDelay); - await time.increaseBy.timestamp(MINSETBACK); - expect(await this.manager.getRoleGrantDelay(this.role.id)).to.equal(oldDelay); - }); - - it('increases the delay after minsetback', async function () { - const txResponse = await this.manager.connect(this.admin).setGrantDelay(this.role.id, newDelay); - const setGrantDelayAt = await time.clockFromReceipt.timestamp(txResponse); - await expect(txResponse) - .to.emit(this.manager, 'RoleGrantDelayChanged') - .withArgs(this.role.id, newDelay, setGrantDelayAt + MINSETBACK); - - expect(await this.manager.getRoleGrantDelay(this.role.id)).to.equal(oldDelay); - await time.increaseBy.timestamp(MINSETBACK); - expect(await this.manager.getRoleGrantDelay(this.role.id)).to.equal(newDelay); - }); - }); - - describe('when reducing the delay', function () { - const oldDelay = time.duration.days(10); - - beforeEach('sets old delay', async function () { - this.role = this.roles.SOME; - await this.manager.$_setGrantDelay(this.role.id, oldDelay); - await time.increaseBy.timestamp(MINSETBACK); - expect(await this.manager.getRoleGrantDelay(this.role.id)).to.equal(oldDelay); - }); - - describe('when the delay difference is shorter than minimum setback', function () { - const newDelay = oldDelay - 1n; - - it('increases the delay after minsetback', async function () { - const txResponse = await this.manager.connect(this.admin).setGrantDelay(this.role.id, newDelay); - const setGrantDelayAt = await time.clockFromReceipt.timestamp(txResponse); - await expect(txResponse) - .to.emit(this.manager, 'RoleGrantDelayChanged') - .withArgs(this.role.id, newDelay, setGrantDelayAt + MINSETBACK); - - expect(await this.manager.getRoleGrantDelay(this.role.id)).to.equal(oldDelay); - await time.increaseBy.timestamp(MINSETBACK); - expect(await this.manager.getRoleGrantDelay(this.role.id)).to.equal(newDelay); - }); - }); - - describe('when the delay difference is longer than minimum setback', function () { - const newDelay = 1n; - - beforeEach('assert delay difference is higher than minsetback', function () { - expect(oldDelay - newDelay).to.gt(MINSETBACK); - }); - - it('increases the delay after delay difference', async function () { - const setback = oldDelay - newDelay; - - const txResponse = await this.manager.connect(this.admin).setGrantDelay(this.role.id, newDelay); - const setGrantDelayAt = await time.clockFromReceipt.timestamp(txResponse); - - await expect(txResponse) - .to.emit(this.manager, 'RoleGrantDelayChanged') - .withArgs(this.role.id, newDelay, setGrantDelayAt + setback); - - expect(await this.manager.getRoleGrantDelay(this.role.id)).to.equal(oldDelay); - await time.increaseBy.timestamp(setback); - expect(await this.manager.getRoleGrantDelay(this.role.id)).to.equal(newDelay); - }); - }); - }); - }); - - describe('#setTargetAdminDelay', function () { - describe('restrictions', function () { - beforeEach('set method and args', function () { - const args = [this.other.address, time.duration.days(3)]; - const method = this.manager.interface.getFunction('setTargetAdminDelay(address,uint32)'); - this.calldata = this.manager.interface.encodeFunctionData(method, args); - }); - - shouldBehaveLikeDelayedAdminOperation(); - }); - - describe('when increasing the delay', function () { - const oldDelay = time.duration.days(10); - const newDelay = time.duration.days(11); - - beforeEach('sets old delay', async function () { - await this.manager.$_setTargetAdminDelay(this.other, oldDelay); - await time.increaseBy.timestamp(MINSETBACK); - expect(await this.manager.getTargetAdminDelay(this.other)).to.equal(oldDelay); - }); - - it('increases the delay after minsetback', async function () { - const txResponse = await this.manager.connect(this.admin).setTargetAdminDelay(this.other, newDelay); - const setTargetAdminDelayAt = await time.clockFromReceipt.timestamp(txResponse); - await expect(txResponse) - .to.emit(this.manager, 'TargetAdminDelayUpdated') - .withArgs(this.other, newDelay, setTargetAdminDelayAt + MINSETBACK); - - expect(await this.manager.getTargetAdminDelay(this.other)).to.equal(oldDelay); - await time.increaseBy.timestamp(MINSETBACK); - expect(await this.manager.getTargetAdminDelay(this.other)).to.equal(newDelay); - }); - }); - - describe('when reducing the delay', function () { - const oldDelay = time.duration.days(10); - - beforeEach('sets old delay', async function () { - await this.manager.$_setTargetAdminDelay(this.other, oldDelay); - await time.increaseBy.timestamp(MINSETBACK); - expect(await this.manager.getTargetAdminDelay(this.other)).to.equal(oldDelay); - }); - - describe('when the delay difference is shorter than minimum setback', function () { - const newDelay = oldDelay - 1n; - - it('increases the delay after minsetback', async function () { - const txResponse = await this.manager.connect(this.admin).setTargetAdminDelay(this.other, newDelay); - const setTargetAdminDelayAt = await time.clockFromReceipt.timestamp(txResponse); - await expect(txResponse) - .to.emit(this.manager, 'TargetAdminDelayUpdated') - .withArgs(this.other, newDelay, setTargetAdminDelayAt + MINSETBACK); - - expect(await this.manager.getTargetAdminDelay(this.other)).to.equal(oldDelay); - await time.increaseBy.timestamp(MINSETBACK); - expect(await this.manager.getTargetAdminDelay(this.other)).to.equal(newDelay); - }); - }); - - describe('when the delay difference is longer than minimum setback', function () { - const newDelay = 1n; - - beforeEach('assert delay difference is higher than minsetback', function () { - expect(oldDelay - newDelay).to.gt(MINSETBACK); - }); - - it('increases the delay after delay difference', async function () { - const setback = oldDelay - newDelay; - - const txResponse = await this.manager.connect(this.admin).setTargetAdminDelay(this.other, newDelay); - const setTargetAdminDelayAt = await time.clockFromReceipt.timestamp(txResponse); - - await expect(txResponse) - .to.emit(this.manager, 'TargetAdminDelayUpdated') - .withArgs(this.other, newDelay, setTargetAdminDelayAt + setback); - - expect(await this.manager.getTargetAdminDelay(this.other)).to.equal(oldDelay); - await time.increaseBy.timestamp(setback); - expect(await this.manager.getTargetAdminDelay(this.other)).to.equal(newDelay); - }); - }); - }); - }); - }); - - describe('not subject to a delay', function () { - describe('#updateAuthority', function () { - beforeEach('create a target and a new authority', async function () { - this.newAuthority = await ethers.deployContract('$AccessManager', [this.admin]); - this.newManagedTarget = await ethers.deployContract('$AccessManagedTarget', [this.manager]); - }); - - describe('restrictions', function () { - beforeEach('set method and args', function () { - this.calldata = this.manager.interface.encodeFunctionData('updateAuthority(address,address)', [ - this.newManagedTarget.target, - this.newAuthority.target, - ]); - }); - - shouldBehaveLikeNotDelayedAdminOperation(); - }); - - it('changes the authority', async function () { - expect(await this.newManagedTarget.authority()).to.equal(this.manager); - - await expect(this.manager.connect(this.admin).updateAuthority(this.newManagedTarget, this.newAuthority)) - .to.emit(this.newManagedTarget, 'AuthorityUpdated') // Managed contract is responsible of notifying the change through an event - .withArgs(this.newAuthority); - - expect(await this.newManagedTarget.authority()).to.equal(this.newAuthority); - }); - }); - - describe('#setTargetClosed', function () { - describe('restrictions', function () { - beforeEach('set method and args', function () { - const args = [this.other.address, true]; - const method = this.manager.interface.getFunction('setTargetClosed(address,bool)'); - this.calldata = this.manager.interface.encodeFunctionData(method, args); - }); - - shouldBehaveLikeNotDelayedAdminOperation(); - }); - - it('closes and opens a target', async function () { - await expect(this.manager.connect(this.admin).setTargetClosed(this.target, true)) - .to.emit(this.manager, 'TargetClosed') - .withArgs(this.target, true); - expect(await this.manager.isTargetClosed(this.target)).to.be.true; - - await expect(this.manager.connect(this.admin).setTargetClosed(this.target, false)) - .to.emit(this.manager, 'TargetClosed') - .withArgs(this.target, false); - expect(await this.manager.isTargetClosed(this.target)).to.be.false; - }); - - describe('when the target is the manager', async function () { - it('closes and opens the manager', async function () { - await expect(this.manager.connect(this.admin).setTargetClosed(this.manager, true)) - .to.emit(this.manager, 'TargetClosed') - .withArgs(this.manager, true); - expect(await this.manager.isTargetClosed(this.manager)).to.be.true; - - await expect(this.manager.connect(this.admin).setTargetClosed(this.manager, false)) - .to.emit(this.manager, 'TargetClosed') - .withArgs(this.manager, false); - expect(await this.manager.isTargetClosed(this.manager)).to.be.false; - }); - }); - }); - - describe('#setTargetFunctionRole', function () { - describe('restrictions', function () { - beforeEach('set method and args', function () { - const args = [this.other.address, ['0x12345678'], 443342]; - const method = this.manager.interface.getFunction('setTargetFunctionRole(address,bytes4[],uint64)'); - this.calldata = this.manager.interface.encodeFunctionData(method, args); - }); - - shouldBehaveLikeNotDelayedAdminOperation(); - }); - - const sigs = ['someFunction()', 'someOtherFunction(uint256)', 'oneMoreFunction(address,uint8)'].map(selector); - - it('sets function roles', async function () { - for (const sig of sigs) { - expect(await this.manager.getTargetFunctionRole(this.target, sig)).to.equal(this.roles.ADMIN.id); - } - - const allowRole = await this.manager - .connect(this.admin) - .setTargetFunctionRole(this.target, sigs, this.roles.SOME.id); - - for (const sig of sigs) { - await expect(allowRole) - .to.emit(this.manager, 'TargetFunctionRoleUpdated') - .withArgs(this.target, sig, this.roles.SOME.id); - expect(await this.manager.getTargetFunctionRole(this.target, sig)).to.equal(this.roles.SOME.id); - } - - await expect( - this.manager.connect(this.admin).setTargetFunctionRole(this.target, [sigs[1]], this.roles.SOME_ADMIN.id), - ) - .to.emit(this.manager, 'TargetFunctionRoleUpdated') - .withArgs(this.target, sigs[1], this.roles.SOME_ADMIN.id); - - for (const sig of sigs) { - expect(await this.manager.getTargetFunctionRole(this.target, sig)).to.equal( - sig == sigs[1] ? this.roles.SOME_ADMIN.id : this.roles.SOME.id, - ); - } - }); - }); - - describe('role admin operations', function () { - const ANOTHER_ADMIN = 0xdeadc0de1n; - const ANOTHER_ROLE = 0xdeadc0de2n; - - beforeEach('set required role', async function () { - // Make admin a member of ANOTHER_ADMIN - await this.manager.$_grantRole(ANOTHER_ADMIN, this.admin, 0, 0); - await this.manager.$_setRoleAdmin(ANOTHER_ROLE, ANOTHER_ADMIN); - - this.role = { id: ANOTHER_ADMIN }; - await this.manager.$_grantRole(this.role.id, this.user, 0, 0); - }); - - describe('#grantRole', function () { - describe('restrictions', function () { - beforeEach('set method and args', function () { - const args = [ANOTHER_ROLE, this.other.address, 0]; - const method = this.manager.interface.getFunction('grantRole(uint64,address,uint32)'); - this.calldata = this.manager.interface.encodeFunctionData(method, args); - }); - - shouldBehaveLikeRoleAdminOperation(ANOTHER_ADMIN); - }); - - it('reverts when granting PUBLIC_ROLE', async function () { - await expect(this.manager.connect(this.admin).grantRole(this.roles.PUBLIC.id, this.user, 0)) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerLockedRole') - .withArgs(this.roles.PUBLIC.id); - }); - - describe('when the user is not a role member', function () { - describe('with grant delay', function () { - beforeEach('set grant delay and grant role', async function () { - // Delay granting - this.grantDelay = time.duration.weeks(2); - await this.manager.$_setGrantDelay(ANOTHER_ROLE, this.grantDelay); - await time.increaseBy.timestamp(MINSETBACK); - - // Grant role - this.executionDelay = time.duration.days(3); - expect(await this.manager.hasRole(ANOTHER_ROLE, this.user).then(formatAccess)).to.be.deep.equal([ - false, - '0', - ]); - - this.txResponse = await this.manager - .connect(this.admin) - .grantRole(ANOTHER_ROLE, this.user, this.executionDelay); - this.delay = this.grantDelay; // For testAsDelay - }); - - testAsDelay('grant', { - before: function self() { - self.mineDelay = true; - - it('does not grant role to the user yet', async function () { - const timestamp = await time.clockFromReceipt.timestamp(this.txResponse); - await expect(this.txResponse) - .to.emit(this.manager, 'RoleGranted') - .withArgs(ANOTHER_ROLE, this.user, this.executionDelay, timestamp + this.grantDelay, true); - - // Access is correctly stored - const access = await this.manager.getAccess(ANOTHER_ROLE, this.user); - expect(access[0]).to.equal(timestamp + this.grantDelay); // inEffectSince - expect(access[1]).to.equal(this.executionDelay); // currentDelay - expect(access[2]).to.equal(0n); // pendingDelay - expect(access[3]).to.equal(0n); // pendingDelayEffect - - // Not in effect yet - const currentTimestamp = await time.clock.timestamp(); - expect(currentTimestamp).to.be.lt(access[0]); - expect(await this.manager.hasRole(ANOTHER_ROLE, this.user).then(formatAccess)).to.be.deep.equal([ - false, - this.executionDelay.toString(), - ]); - }); - }, - after: function self() { - self.mineDelay = true; - - it('grants role to the user', async function () { - const timestamp = await time.clockFromReceipt.timestamp(this.txResponse); - await expect(this.txResponse) - .to.emit(this.manager, 'RoleGranted') - .withArgs(ANOTHER_ROLE, this.user, this.executionDelay, timestamp + this.grantDelay, true); - - // Access is correctly stored - const access = await this.manager.getAccess(ANOTHER_ROLE, this.user); - expect(access[0]).to.equal(timestamp + this.grantDelay); // inEffectSince - expect(access[1]).to.equal(this.executionDelay); // currentDelay - expect(access[2]).to.equal(0n); // pendingDelay - expect(access[3]).to.equal(0n); // pendingDelayEffect - - // Already in effect - const currentTimestamp = await time.clock.timestamp(); - expect(currentTimestamp).to.equal(access[0]); - expect(await this.manager.hasRole(ANOTHER_ROLE, this.user).then(formatAccess)).to.be.deep.equal([ - true, - this.executionDelay.toString(), - ]); - }); - }, - }); - }); - - describe('without grant delay', function () { - beforeEach('set granting delay', async function () { - // Delay granting - this.grantDelay = 0; - await this.manager.$_setGrantDelay(ANOTHER_ROLE, this.grantDelay); - await time.increaseBy.timestamp(MINSETBACK); - }); - - it('immediately grants the role to the user', async function () { - const executionDelay = time.duration.days(6); - expect(await this.manager.hasRole(ANOTHER_ROLE, this.user).then(formatAccess)).to.be.deep.equal([ - false, - '0', - ]); - const txResponse = await this.manager - .connect(this.admin) - .grantRole(ANOTHER_ROLE, this.user, executionDelay); - const grantedAt = await time.clockFromReceipt.timestamp(txResponse); - await expect(txResponse) - .to.emit(this.manager, 'RoleGranted') - .withArgs(ANOTHER_ROLE, this.user, executionDelay, grantedAt, true); - - // Access is correctly stored - const access = await this.manager.getAccess(ANOTHER_ROLE, this.user); - expect(access[0]).to.equal(grantedAt); // inEffectSince - expect(access[1]).to.equal(executionDelay); // currentDelay - expect(access[2]).to.equal(0n); // pendingDelay - expect(access[3]).to.equal(0n); // pendingDelayEffect - - // Already in effect - const currentTimestamp = await time.clock.timestamp(); - expect(currentTimestamp).to.equal(access[0]); - expect(await this.manager.hasRole(ANOTHER_ROLE, this.user).then(formatAccess)).to.be.deep.equal([ - true, - executionDelay.toString(), - ]); - }); - }); - }); - - describe('when the user is already a role member', function () { - beforeEach('make user role member', async function () { - this.previousExecutionDelay = time.duration.days(6); - await this.manager.$_grantRole(ANOTHER_ROLE, this.user, 0, this.previousExecutionDelay); - this.oldAccess = await this.manager.getAccess(ANOTHER_ROLE, this.user); - }); - - describe('with grant delay', function () { - beforeEach('set granting delay', async function () { - // Delay granting - const grantDelay = time.duration.weeks(2); - await this.manager.$_setGrantDelay(ANOTHER_ROLE, grantDelay); - await time.increaseBy.timestamp(MINSETBACK); - }); - - describe('when increasing the execution delay', function () { - beforeEach('set increased new execution delay', async function () { - expect(await this.manager.hasRole(ANOTHER_ROLE, this.user).then(formatAccess)).to.be.deep.equal([ - true, - this.previousExecutionDelay.toString(), - ]); - - this.newExecutionDelay = this.previousExecutionDelay + time.duration.days(4); - }); - - it('emits event and immediately changes the execution delay', async function () { - expect(await this.manager.hasRole(ANOTHER_ROLE, this.user).then(formatAccess)).to.be.deep.equal([ - true, - this.previousExecutionDelay.toString(), - ]); - const txResponse = await this.manager - .connect(this.admin) - .grantRole(ANOTHER_ROLE, this.user, this.newExecutionDelay); - const timestamp = await time.clockFromReceipt.timestamp(txResponse); - - await expect(txResponse) - .to.emit(this.manager, 'RoleGranted') - .withArgs(ANOTHER_ROLE, this.user, this.newExecutionDelay, timestamp, false); - - // Access is correctly stored - const access = await this.manager.getAccess(ANOTHER_ROLE, this.user); - expect(access[0]).to.equal(this.oldAccess[0]); // inEffectSince - expect(access[1]).to.equal(this.newExecutionDelay); // currentDelay - expect(access[2]).to.equal(0n); // pendingDelay - expect(access[3]).to.equal(0n); // pendingDelayEffect - - // Already in effect - expect(await this.manager.hasRole(ANOTHER_ROLE, this.user).then(formatAccess)).to.be.deep.equal([ - true, - this.newExecutionDelay.toString(), - ]); - }); - }); - - describe('when decreasing the execution delay', function () { - beforeEach('decrease execution delay', async function () { - expect(await this.manager.hasRole(ANOTHER_ROLE, this.user).then(formatAccess)).to.be.deep.equal([ - true, - this.previousExecutionDelay.toString(), - ]); - - this.newExecutionDelay = this.previousExecutionDelay - time.duration.days(4); - this.txResponse = await this.manager - .connect(this.admin) - .grantRole(ANOTHER_ROLE, this.user, this.newExecutionDelay); - this.grantTimestamp = await time.clockFromReceipt.timestamp(this.txResponse); - - this.delay = this.previousExecutionDelay - this.newExecutionDelay; // For testAsDelay - }); - - it('emits event', async function () { - await expect(this.txResponse) - .to.emit(this.manager, 'RoleGranted') - .withArgs(ANOTHER_ROLE, this.user, this.newExecutionDelay, this.grantTimestamp + this.delay, false); - }); - - testAsDelay('execution delay effect', { - before: function self() { - self.mineDelay = true; - - it('does not change the execution delay yet', async function () { - // Access is correctly stored - const access = await this.manager.getAccess(ANOTHER_ROLE, this.user); - expect(access[0]).to.equal(this.oldAccess[0]); // inEffectSince - expect(access[1]).to.equal(this.previousExecutionDelay); // currentDelay - expect(access[2]).to.equal(this.newExecutionDelay); // pendingDelay - expect(access[3]).to.equal(this.grantTimestamp + this.delay); // pendingDelayEffect - - // Not in effect yet - expect(await this.manager.hasRole(ANOTHER_ROLE, this.user).then(formatAccess)).to.be.deep.equal([ - true, - this.previousExecutionDelay.toString(), - ]); - }); - }, - after: function self() { - self.mineDelay = true; - - it('changes the execution delay', async function () { - // Access is correctly stored - const access = await this.manager.getAccess(ANOTHER_ROLE, this.user); - - expect(access[0]).to.equal(this.oldAccess[0]); // inEffectSince - expect(access[1]).to.equal(this.newExecutionDelay); // currentDelay - expect(access[2]).to.equal(0n); // pendingDelay - expect(access[3]).to.equal(0n); // pendingDelayEffect - - // Already in effect - expect(await this.manager.hasRole(ANOTHER_ROLE, this.user).then(formatAccess)).to.be.deep.equal([ - true, - this.newExecutionDelay.toString(), - ]); - }); - }, - }); - }); - }); - - describe('without grant delay', function () { - beforeEach('set granting delay', async function () { - // Delay granting - const grantDelay = 0; - await this.manager.$_setGrantDelay(ANOTHER_ROLE, grantDelay); - await time.increaseBy.timestamp(MINSETBACK); - }); - - describe('when increasing the execution delay', function () { - beforeEach('set increased new execution delay', async function () { - expect(await this.manager.hasRole(ANOTHER_ROLE, this.user).then(formatAccess)).to.be.deep.equal([ - true, - this.previousExecutionDelay.toString(), - ]); - - this.newExecutionDelay = this.previousExecutionDelay + time.duration.days(4); - }); - - it('emits event and immediately changes the execution delay', async function () { - expect(await this.manager.hasRole(ANOTHER_ROLE, this.user).then(formatAccess)).to.be.deep.equal([ - true, - this.previousExecutionDelay.toString(), - ]); - const txResponse = await this.manager - .connect(this.admin) - .grantRole(ANOTHER_ROLE, this.user, this.newExecutionDelay); - const timestamp = await time.clockFromReceipt.timestamp(txResponse); - - await expect(txResponse) - .to.emit(this.manager, 'RoleGranted') - .withArgs(ANOTHER_ROLE, this.user, this.newExecutionDelay, timestamp, false); - - // Access is correctly stored - const access = await this.manager.getAccess(ANOTHER_ROLE, this.user); - expect(access[0]).to.equal(this.oldAccess[0]); // inEffectSince - expect(access[1]).to.equal(this.newExecutionDelay); // currentDelay - expect(access[2]).to.equal(0n); // pendingDelay - expect(access[3]).to.equal(0n); // pendingDelayEffect - - // Already in effect - expect(await this.manager.hasRole(ANOTHER_ROLE, this.user).then(formatAccess)).to.be.deep.equal([ - true, - this.newExecutionDelay.toString(), - ]); - }); - }); - - describe('when decreasing the execution delay', function () { - beforeEach('decrease execution delay', async function () { - expect(await this.manager.hasRole(ANOTHER_ROLE, this.user).then(formatAccess)).to.be.deep.equal([ - true, - this.previousExecutionDelay.toString(), - ]); - - this.newExecutionDelay = this.previousExecutionDelay - time.duration.days(4); - this.txResponse = await this.manager - .connect(this.admin) - .grantRole(ANOTHER_ROLE, this.user, this.newExecutionDelay); - this.grantTimestamp = await time.clockFromReceipt.timestamp(this.txResponse); - - this.delay = this.previousExecutionDelay - this.newExecutionDelay; // For testAsDelay - }); - - it('emits event', async function () { - await expect(this.txResponse) - .to.emit(this.manager, 'RoleGranted') - .withArgs(ANOTHER_ROLE, this.user, this.newExecutionDelay, this.grantTimestamp + this.delay, false); - }); - - testAsDelay('execution delay effect', { - before: function self() { - self.mineDelay = true; - - it('does not change the execution delay yet', async function () { - // Access is correctly stored - const access = await this.manager.getAccess(ANOTHER_ROLE, this.user); - expect(access[0]).to.equal(this.oldAccess[0]); // inEffectSince - expect(access[1]).to.equal(this.previousExecutionDelay); // currentDelay - expect(access[2]).to.equal(this.newExecutionDelay); // pendingDelay - expect(access[3]).to.equal(this.grantTimestamp + this.delay); // pendingDelayEffect - - // Not in effect yet - expect(await this.manager.hasRole(ANOTHER_ROLE, this.user).then(formatAccess)).to.be.deep.equal([ - true, - this.previousExecutionDelay.toString(), - ]); - }); - }, - after: function self() { - self.mineDelay = true; - - it('changes the execution delay', async function () { - // Access is correctly stored - const access = await this.manager.getAccess(ANOTHER_ROLE, this.user); - - expect(access[0]).to.equal(this.oldAccess[0]); // inEffectSince - expect(access[1]).to.equal(this.newExecutionDelay); // currentDelay - expect(access[2]).to.equal(0n); // pendingDelay - expect(access[3]).to.equal(0n); // pendingDelayEffect - - // Already in effect - expect(await this.manager.hasRole(ANOTHER_ROLE, this.user).then(formatAccess)).to.be.deep.equal([ - true, - this.newExecutionDelay.toString(), - ]); - }); - }, - }); - }); - }); - }); - }); - - describe('#revokeRole', function () { - describe('restrictions', function () { - beforeEach('set method and args', async function () { - const args = [ANOTHER_ROLE, this.other.address]; - const method = this.manager.interface.getFunction('revokeRole(uint64,address)'); - this.calldata = this.manager.interface.encodeFunctionData(method, args); - - // Need to be set before revoking - await this.manager.$_grantRole(...args, 0, 0); - }); - - shouldBehaveLikeRoleAdminOperation(ANOTHER_ADMIN); - }); - - describe('when role has been granted', function () { - beforeEach('grant role with grant delay', async function () { - this.grantDelay = time.duration.weeks(1); - await this.manager.$_grantRole(ANOTHER_ROLE, this.user, this.grantDelay, 0); - - this.delay = this.grantDelay; // For testAsDelay - }); - - testAsDelay('grant', { - before: function self() { - self.mineDelay = true; - - it('revokes a granted role that will take effect in the future', async function () { - expect(await this.manager.hasRole(ANOTHER_ROLE, this.user).then(formatAccess)).to.be.deep.equal([ - false, - '0', - ]); - - await expect(this.manager.connect(this.admin).revokeRole(ANOTHER_ROLE, this.user)) - .to.emit(this.manager, 'RoleRevoked') - .withArgs(ANOTHER_ROLE, this.user); - - expect(await this.manager.hasRole(ANOTHER_ROLE, this.user).then(formatAccess)).to.be.deep.equal([ - false, - '0', - ]); - - const access = await this.manager.getAccess(ANOTHER_ROLE, this.user); - expect(access[0]).to.equal(0n); // inRoleSince - expect(access[1]).to.equal(0n); // currentDelay - expect(access[2]).to.equal(0n); // pendingDelay - expect(access[3]).to.equal(0n); // effect - }); - }, - after: function self() { - self.mineDelay = true; - - it('revokes a granted role that already took effect', async function () { - expect(await this.manager.hasRole(ANOTHER_ROLE, this.user).then(formatAccess)).to.be.deep.equal([ - true, - '0', - ]); - - await expect(this.manager.connect(this.admin).revokeRole(ANOTHER_ROLE, this.user)) - .to.emit(this.manager, 'RoleRevoked') - .withArgs(ANOTHER_ROLE, this.user); - - expect(await this.manager.hasRole(ANOTHER_ROLE, this.user).then(formatAccess)).to.be.deep.equal([ - false, - '0', - ]); - - const access = await this.manager.getAccess(ANOTHER_ROLE, this.user); - expect(access[0]).to.equal(0n); // inRoleSince - expect(access[1]).to.equal(0n); // currentDelay - expect(access[2]).to.equal(0n); // pendingDelay - expect(access[3]).to.equal(0n); // effect - }); - }, - }); - }); - - describe('when role has not been granted', function () { - it('has no effect', async function () { - expect(await this.manager.hasRole(this.roles.SOME.id, this.user).then(formatAccess)).to.be.deep.equal([ - false, - '0', - ]); - await expect(this.manager.connect(this.roleAdmin).revokeRole(this.roles.SOME.id, this.user)).to.not.emit( - this.manager, - 'RoleRevoked', - ); - expect(await this.manager.hasRole(this.roles.SOME.id, this.user).then(formatAccess)).to.be.deep.equal([ - false, - '0', - ]); - }); - }); - - it('reverts revoking PUBLIC_ROLE', async function () { - await expect(this.manager.connect(this.admin).revokeRole(this.roles.PUBLIC.id, this.user)) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerLockedRole') - .withArgs(this.roles.PUBLIC.id); - }); - }); - }); - - describe('self role operations', function () { - describe('#renounceRole', function () { - beforeEach('grant role', async function () { - this.role = { id: 783164n }; - this.caller = this.user; - await this.manager.$_grantRole(this.role.id, this.caller, 0, 0); - }); - - it('renounces a role', async function () { - expect(await this.manager.hasRole(this.role.id, this.caller).then(formatAccess)).to.be.deep.equal([ - true, - '0', - ]); - await expect(this.manager.connect(this.caller).renounceRole(this.role.id, this.caller)) - .to.emit(this.manager, 'RoleRevoked') - .withArgs(this.role.id, this.caller); - expect(await this.manager.hasRole(this.role.id, this.caller).then(formatAccess)).to.be.deep.equal([ - false, - '0', - ]); - }); - - it('reverts if renouncing the PUBLIC_ROLE', async function () { - await expect(this.manager.connect(this.caller).renounceRole(this.roles.PUBLIC.id, this.caller)) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerLockedRole') - .withArgs(this.roles.PUBLIC.id); - }); - - it('reverts if renouncing with bad caller confirmation', async function () { - await expect( - this.manager.connect(this.caller).renounceRole(this.role.id, this.other), - ).to.be.revertedWithCustomError(this.manager, 'AccessManagerBadConfirmation'); - }); - }); - }); - }); - }); - - describe('access managed self operations', function () { - describe('when calling a restricted target function', function () { - const method = 'fnRestricted()'; - - beforeEach('set required role', async function () { - this.role = { id: 785913n }; - await this.manager.$_setTargetFunctionRole( - this.manager, - this.manager[method].getFragment().selector, - this.role.id, - ); - }); - - describe('restrictions', function () { - beforeEach('set method and args', function () { - this.caller = this.user; - this.calldata = this.manager.interface.encodeFunctionData(method, []); - }); - - shouldBehaveLikeASelfRestrictedOperation(); - }); - - it('succeeds called by a role member', async function () { - await this.manager.$_grantRole(this.role.id, this.user, 0, 0); - - await expect(this.manager.connect(this.user)[method]()) - .to.emit(this.manager, 'CalledRestricted') - .withArgs(this.user); - }); - }); - - describe('when calling a non-restricted target function', function () { - const method = 'fnUnrestricted()'; - - beforeEach('set required role', async function () { - this.role = { id: 879435n }; - await this.manager.$_setTargetFunctionRole( - this.manager, - this.manager[method].getFragment().selector, - this.role.id, - ); - }); - - it('succeeds called by anyone', async function () { - await expect(this.manager.connect(this.user)[method]()) - .to.emit(this.manager, 'CalledUnrestricted') - .withArgs(this.user); - }); - }); - }); - - describe('access managed target operations', function () { - describe('when calling a restricted target function', function () { - const method = 'fnRestricted()'; - - beforeEach('set required role', async function () { - this.role = { id: 3597243n }; - await this.manager.$_setTargetFunctionRole( - this.target, - this.target[method].getFragment().selector, - this.role.id, - ); - }); - - describe('restrictions', function () { - beforeEach('set method and args', function () { - this.caller = this.user; - this.calldata = this.target.interface.encodeFunctionData(method, []); - }); - - shouldBehaveLikeAManagedRestrictedOperation(); - }); - - it('succeeds called by a role member', async function () { - await this.manager.$_grantRole(this.role.id, this.user, 0, 0); - - await expect(this.target.connect(this.user)[method]()) - .to.emit(this.target, 'CalledRestricted') - .withArgs(this.user); - }); - }); - - describe('when calling a non-restricted target function', function () { - const method = 'fnUnrestricted()'; - - beforeEach('set required role', async function () { - this.role = { id: 879435n }; - await this.manager.$_setTargetFunctionRole( - this.target, - this.target[method].getFragment().selector, - this.role.id, - ); - }); - - it('succeeds called by anyone', async function () { - await expect(this.target.connect(this.user)[method]()) - .to.emit(this.target, 'CalledUnrestricted') - .withArgs(this.user); - }); - }); - }); - - describe('#schedule', function () { - beforeEach('set target function role', async function () { - this.method = this.target.fnRestricted.getFragment(); - this.role = { id: 498305n }; - this.caller = this.user; - - await this.manager.$_setTargetFunctionRole(this.target, this.method.selector, this.role.id); - await this.manager.$_grantRole(this.role.id, this.caller, 0, 1); // nonzero execution delay - - this.calldata = this.target.interface.encodeFunctionData(this.method, []); - this.delay = time.duration.weeks(2); - }); - - describe('restrictions', function () { - testAsCanCall({ - closed() { - it('reverts as AccessManagerUnauthorizedCall', async function () { - const { schedule } = await prepareOperation(this.manager, { - caller: this.caller, - target: this.target, - calldata: this.calldata, - delay: this.delay, - }); - await expect(schedule()) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerUnauthorizedCall') - .withArgs(this.caller, this.target, this.calldata.substring(0, 10)); - }); - }, - open: { - callerIsTheManager: { - executing() { - it.skip('is not reachable because schedule is not restrictable'); - }, - notExecuting() { - it('reverts as AccessManagerUnauthorizedCall', async function () { - const { schedule } = await prepareOperation(this.manager, { - caller: this.caller, - target: this.target, - calldata: this.calldata, - delay: this.delay, - }); - await expect(schedule()) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerUnauthorizedCall') - .withArgs(this.caller, this.target, this.calldata.substring(0, 10)); - }); - }, - }, - callerIsNotTheManager: { - publicRoleIsRequired() { - it('reverts as AccessManagerUnauthorizedCall', async function () { - // prepareOperation is not used here because it alters the next block timestamp - await expect(this.manager.connect(this.caller).schedule(this.target, this.calldata, MAX_UINT48)) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerUnauthorizedCall') - .withArgs(this.caller, this.target, this.calldata.substring(0, 10)); - }); - }, - specificRoleIsRequired: { - requiredRoleIsGranted: { - roleGrantingIsDelayed: { - callerHasAnExecutionDelay: { - beforeGrantDelay() { - it('reverts as AccessManagerUnauthorizedCall', async function () { - // prepareOperation is not used here because it alters the next block timestamp - await expect(this.manager.connect(this.caller).schedule(this.target, this.calldata, MAX_UINT48)) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerUnauthorizedCall') - .withArgs(this.caller, this.target, this.calldata.substring(0, 10)); - }); - }, - afterGrantDelay() { - it('succeeds', async function () { - // prepareOperation is not used here because it alters the next block timestamp - await this.manager.connect(this.caller).schedule(this.target, this.calldata, MAX_UINT48); - }); - }, - }, - callerHasNoExecutionDelay: { - beforeGrantDelay() { - it('reverts as AccessManagerUnauthorizedCall', async function () { - // prepareOperation is not used here because it alters the next block timestamp - await expect(this.manager.connect(this.caller).schedule(this.target, this.calldata, MAX_UINT48)) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerUnauthorizedCall') - .withArgs(this.caller, this.target, this.calldata.substring(0, 10)); - }); - }, - afterGrantDelay() { - it('reverts as AccessManagerUnauthorizedCall', async function () { - // prepareOperation is not used here because it alters the next block timestamp - await expect(this.manager.connect(this.caller).schedule(this.target, this.calldata, MAX_UINT48)) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerUnauthorizedCall') - .withArgs(this.caller, this.target, this.calldata.substring(0, 10)); - }); - }, - }, - }, - roleGrantingIsNotDelayed: { - callerHasAnExecutionDelay() { - it('succeeds', async function () { - const { schedule } = await prepareOperation(this.manager, { - caller: this.caller, - target: this.target, - calldata: this.calldata, - delay: this.delay, - }); - - await schedule(); - }); - }, - callerHasNoExecutionDelay() { - it('reverts as AccessManagerUnauthorizedCall', async function () { - // prepareOperation is not used here because it alters the next block timestamp - await expect(this.manager.connect(this.caller).schedule(this.target, this.calldata, MAX_UINT48)) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerUnauthorizedCall') - .withArgs(this.caller, this.target, this.calldata.substring(0, 10)); - }); - }, - }, - }, - requiredRoleIsNotGranted() { - it('reverts as AccessManagerUnauthorizedCall', async function () { - const { schedule } = await prepareOperation(this.manager, { - caller: this.caller, - target: this.target, - calldata: this.calldata, - delay: this.delay, - }); - await expect(schedule()) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerUnauthorizedCall') - .withArgs(this.caller, this.target, this.calldata.substring(0, 10)); - }); - }, - }, - }, - }, - }); - }); - - it('schedules an operation at the specified execution date if it is larger than caller execution delay', async function () { - const { operationId, scheduledAt, schedule } = await prepareOperation(this.manager, { - caller: this.caller, - target: this.target, - calldata: this.calldata, - delay: this.delay, - }); - - const txResponse = await schedule(); - - expect(await this.manager.getSchedule(operationId)).to.equal(scheduledAt + this.delay); - await expect(txResponse) - .to.emit(this.manager, 'OperationScheduled') - .withArgs(operationId, '1', scheduledAt + this.delay, this.caller, this.target, this.calldata); - }); - - it('schedules an operation at the minimum execution date if no specified execution date (when == 0)', async function () { - const executionDelay = await time.duration.hours(72); - await this.manager.$_grantRole(this.role.id, this.caller, 0, executionDelay); - - const txResponse = await this.manager.connect(this.caller).schedule(this.target, this.calldata, 0); - const scheduledAt = await time.clockFromReceipt.timestamp(txResponse); - - const operationId = await this.manager.hashOperation(this.caller, this.target, this.calldata); - - expect(await this.manager.getSchedule(operationId)).to.equal(scheduledAt + executionDelay); - await expect(txResponse) - .to.emit(this.manager, 'OperationScheduled') - .withArgs(operationId, '1', scheduledAt + executionDelay, this.caller, this.target, this.calldata); - }); - - it('increases the nonce of an operation scheduled more than once', async function () { - // Setup and check initial nonce - const expectedOperationId = hashOperation(this.caller, this.target, this.calldata); - expect(await this.manager.getNonce(expectedOperationId)).to.equal('0'); - - // Schedule - const op1 = await prepareOperation(this.manager, { - caller: this.caller, - target: this.target, - calldata: this.calldata, - delay: this.delay, - }); - await expect(op1.schedule()) - .to.emit(this.manager, 'OperationScheduled') - .withArgs(op1.operationId, 1n, op1.scheduledAt + this.delay, this.caller, this.target, this.calldata); - expect(expectedOperationId).to.equal(op1.operationId); - - // Consume - await time.increaseBy.timestamp(this.delay); - await this.manager.$_consumeScheduledOp(expectedOperationId); - - // Check nonce - expect(await this.manager.getNonce(expectedOperationId)).to.equal('1'); - - // Schedule again - const op2 = await prepareOperation(this.manager, { - caller: this.caller, - target: this.target, - calldata: this.calldata, - delay: this.delay, - }); - await expect(op2.schedule()) - .to.emit(this.manager, 'OperationScheduled') - .withArgs(op2.operationId, 2n, op2.scheduledAt + this.delay, this.caller, this.target, this.calldata); - expect(expectedOperationId).to.equal(op2.operationId); - - // Check final nonce - expect(await this.manager.getNonce(expectedOperationId)).to.equal('2'); - }); - - it('reverts if the specified execution date is before the current timestamp + caller execution delay', async function () { - const executionDelay = time.duration.weeks(1) + this.delay; - await this.manager.$_grantRole(this.role.id, this.caller, 0, executionDelay); - - const { schedule } = await prepareOperation(this.manager, { - caller: this.caller, - target: this.target, - calldata: this.calldata, - delay: this.delay, - }); - - await expect(schedule()) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerUnauthorizedCall') - .withArgs(this.caller, this.target, this.calldata.substring(0, 10)); - }); - - it('reverts if an operation is already schedule', async function () { - const op1 = await prepareOperation(this.manager, { - caller: this.caller, - target: this.target, - calldata: this.calldata, - delay: this.delay, - }); - - await op1.schedule(); - - const op2 = await prepareOperation(this.manager, { - caller: this.caller, - target: this.target, - calldata: this.calldata, - delay: this.delay, - }); - - await expect(op2.schedule()) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerAlreadyScheduled') - .withArgs(op1.operationId); - }); - - it('panics scheduling calldata with less than 4 bytes', async function () { - const calldata = '0x1234'; // 2 bytes - - // Managed contract - const op1 = await prepareOperation(this.manager, { - caller: this.caller, - target: this.target, - calldata: calldata, - delay: this.delay, - }); - await expect(op1.schedule()).to.be.revertedWithoutReason(); - - // Manager contract - const op2 = await prepareOperation(this.manager, { - caller: this.caller, - target: this.manager, - calldata: calldata, - delay: this.delay, - }); - await expect(op2.schedule()).to.be.revertedWithoutReason(); - }); - - it('reverts scheduling an unknown operation to the manager', async function () { - const calldata = '0x12345678'; - - const { schedule } = await prepareOperation(this.manager, { - caller: this.caller, - target: this.manager, - calldata, - delay: this.delay, - }); - - await expect(schedule()) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerUnauthorizedCall') - .withArgs(this.caller, this.manager, calldata); - }); - }); - - describe('#execute', function () { - beforeEach('set target function role', async function () { - this.method = this.target.fnRestricted.getFragment(); - this.role = { id: 9825430n }; - this.caller = this.user; - - await this.manager.$_setTargetFunctionRole(this.target, this.method.selector, this.role.id); - await this.manager.$_grantRole(this.role.id, this.caller, 0, 0); - - this.calldata = this.target.interface.encodeFunctionData(this.method, []); - }); - - describe('restrictions', function () { - testAsCanCall({ - closed() { - it('reverts as AccessManagerUnauthorizedCall', async function () { - await expect(this.manager.connect(this.caller).execute(this.target, this.calldata)) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerUnauthorizedCall') - .withArgs(this.caller, this.target, this.calldata.substring(0, 10)); - }); - }, - open: { - callerIsTheManager: { - executing() { - it('succeeds', async function () { - await this.manager.connect(this.caller).execute(this.target, this.calldata); - }); - }, - notExecuting() { - it('reverts as AccessManagerUnauthorizedCall', async function () { - await expect(this.manager.connect(this.caller).execute(this.target, this.calldata)) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerUnauthorizedCall') - .withArgs(this.caller, this.target, this.calldata.substring(0, 10)); - }); - }, - }, - callerIsNotTheManager: { - publicRoleIsRequired() { - it('succeeds', async function () { - await this.manager.connect(this.caller).execute(this.target, this.calldata); - }); - }, - specificRoleIsRequired: { - requiredRoleIsGranted: { - roleGrantingIsDelayed: { - callerHasAnExecutionDelay: { - beforeGrantDelay() { - it('reverts as AccessManagerUnauthorizedCall', async function () { - await expect(this.manager.connect(this.caller).execute(this.target, this.calldata)) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerUnauthorizedCall') - .withArgs(this.caller, this.target, this.calldata.substring(0, 10)); - }); - }, - afterGrantDelay: function self() { - self.mineDelay = true; - - beforeEach('define schedule delay', function () { - this.scheduleIn = time.duration.days(21); // For testAsSchedulableOperation - }); - - testAsSchedulableOperation(LIKE_COMMON_SCHEDULABLE); - }, - }, - callerHasNoExecutionDelay: { - beforeGrantDelay() { - it('reverts as AccessManagerUnauthorizedCall', async function () { - await expect(this.manager.connect(this.caller).execute(this.target, this.calldata)) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerUnauthorizedCall') - .withArgs(this.caller, this.target, this.calldata.substring(0, 10)); - }); - }, - afterGrantDelay: function self() { - self.mineDelay = true; - - it('succeeds', async function () { - await this.manager.connect(this.caller).execute(this.target, this.calldata); - }); - }, - }, - }, - roleGrantingIsNotDelayed: { - callerHasAnExecutionDelay() { - beforeEach('define schedule delay', function () { - this.scheduleIn = time.duration.days(15); // For testAsSchedulableOperation - }); - - testAsSchedulableOperation(LIKE_COMMON_SCHEDULABLE); - }, - callerHasNoExecutionDelay() { - it('succeeds', async function () { - await this.manager.connect(this.caller).execute(this.target, this.calldata); - }); - }, - }, - }, - requiredRoleIsNotGranted() { - it('reverts as AccessManagerUnauthorizedCall', async function () { - await expect(this.manager.connect(this.caller).execute(this.target, this.calldata)) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerUnauthorizedCall') - .withArgs(this.caller, this.target, this.calldata.substring(0, 10)); - }); - }, - }, - }, - }, - }); - }); - - it('executes with a delay consuming the scheduled operation', async function () { - const delay = time.duration.hours(4); - await this.manager.$_grantRole(this.role.id, this.caller, 0, 1); // Execution delay is needed so the operation is consumed - - const { operationId, schedule } = await prepareOperation(this.manager, { - caller: this.caller, - target: this.target, - calldata: this.calldata, - delay, - }); - await schedule(); - await time.increaseBy.timestamp(delay); - await expect(this.manager.connect(this.caller).execute(this.target, this.calldata)) - .to.emit(this.manager, 'OperationExecuted') - .withArgs(operationId, 1n); - - expect(await this.manager.getSchedule(operationId)).to.equal(0n); - }); - - it('executes with no delay consuming a scheduled operation', async function () { - const delay = time.duration.hours(4); - - // give caller an execution delay - await this.manager.$_grantRole(this.role.id, this.caller, 0, 1); - - const { operationId, schedule } = await prepareOperation(this.manager, { - caller: this.caller, - target: this.target, - calldata: this.calldata, - delay, - }); - await schedule(); - - // remove the execution delay - await this.manager.$_grantRole(this.role.id, this.caller, 0, 0); - - await time.increaseBy.timestamp(delay); - await expect(this.manager.connect(this.caller).execute(this.target, this.calldata)) - .to.emit(this.manager, 'OperationExecuted') - .withArgs(operationId, 1n); - - expect(await this.manager.getSchedule(operationId)).to.equal(0n); - }); - - it('keeps the original _executionId after finishing the call', async function () { - const executionIdBefore = await ethers.provider.getStorage(this.manager, EXECUTION_ID_STORAGE_SLOT); - await this.manager.connect(this.caller).execute(this.target, this.calldata); - const executionIdAfter = await ethers.provider.getStorage(this.manager, EXECUTION_ID_STORAGE_SLOT); - expect(executionIdBefore).to.equal(executionIdAfter); - }); - - it('reverts executing twice', async function () { - const delay = time.duration.hours(2); - await this.manager.$_grantRole(this.role.id, this.caller, 0, 1); // Execution delay is needed so the operation is consumed - - const { operationId, schedule } = await prepareOperation(this.manager, { - caller: this.caller, - target: this.target, - calldata: this.calldata, - delay, - }); - await schedule(); - await time.increaseBy.timestamp(delay); - await this.manager.connect(this.caller).execute(this.target, this.calldata); - await expect(this.manager.connect(this.caller).execute(this.target, this.calldata)) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerNotScheduled') - .withArgs(operationId); - }); - }); - - describe('#consumeScheduledOp', function () { - beforeEach('define scheduling parameters', async function () { - const method = this.target.fnRestricted.getFragment(); - this.caller = await ethers.getSigner(this.target.target); - await impersonate(this.caller.address); - this.calldata = this.target.interface.encodeFunctionData(method, []); - this.role = { id: 9834983n }; - - await this.manager.$_setTargetFunctionRole(this.target, method.selector, this.role.id); - await this.manager.$_grantRole(this.role.id, this.caller, 0, 1); // nonzero execution delay - - this.scheduleIn = time.duration.hours(10); // For testAsSchedulableOperation - }); - - describe('when caller is not consuming scheduled operation', function () { - beforeEach('set consuming false', async function () { - await this.target.setIsConsumingScheduledOp(false, ethers.toBeHex(CONSUMING_SCHEDULE_STORAGE_SLOT, 32)); - }); - - it('reverts as AccessManagerUnauthorizedConsume', async function () { - await expect(this.manager.connect(this.caller).consumeScheduledOp(this.caller, this.calldata)) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerUnauthorizedConsume') - .withArgs(this.caller); - }); - }); - - describe('when caller is consuming scheduled operation', function () { - beforeEach('set consuming true', async function () { - await this.target.setIsConsumingScheduledOp(true, ethers.toBeHex(CONSUMING_SCHEDULE_STORAGE_SLOT, 32)); - }); - - testAsSchedulableOperation({ - scheduled: { - before() { - it('reverts as AccessManagerNotReady', async function () { - await expect(this.manager.connect(this.caller).consumeScheduledOp(this.caller, this.calldata)) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerNotReady') - .withArgs(this.operationId); - }); - }, - after() { - it('consumes the scheduled operation and resets timepoint', async function () { - expect(await this.manager.getSchedule(this.operationId)).to.equal(this.scheduledAt + this.scheduleIn); - - await expect(this.manager.connect(this.caller).consumeScheduledOp(this.caller, this.calldata)) - .to.emit(this.manager, 'OperationExecuted') - .withArgs(this.operationId, 1n); - expect(await this.manager.getSchedule(this.operationId)).to.equal(0n); - }); - }, - expired() { - it('reverts as AccessManagerExpired', async function () { - await expect(this.manager.connect(this.caller).consumeScheduledOp(this.caller, this.calldata)) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerExpired') - .withArgs(this.operationId); - }); - }, - }, - notScheduled() { - it('reverts as AccessManagerNotScheduled', async function () { - await expect(this.manager.connect(this.caller).consumeScheduledOp(this.caller, this.calldata)) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerNotScheduled') - .withArgs(this.operationId); - }); - }, - }); - }); - }); - - describe('#cancelScheduledOp', function () { - beforeEach('setup scheduling', async function () { - this.method = this.target.fnRestricted.getFragment(); - this.caller = this.roles.SOME.members[0]; - await this.manager.$_setTargetFunctionRole(this.target, this.method.selector, this.roles.SOME.id); - await this.manager.$_grantRole(this.roles.SOME.id, this.caller, 0, 1); // nonzero execution delay - - this.calldata = this.target.interface.encodeFunctionData(this.method, []); - this.scheduleIn = time.duration.days(10); // For testAsSchedulableOperation - }); - - testAsSchedulableOperation({ - scheduled: { - before() { - describe('when caller is the scheduler', function () { - it('succeeds', async function () { - await this.manager.connect(this.caller).cancel(this.caller, this.target, this.calldata); - }); - }); - - describe('when caller is an admin', function () { - it('succeeds', async function () { - await this.manager.connect(this.roles.ADMIN.members[0]).cancel(this.caller, this.target, this.calldata); - }); - }); - - describe('when caller is the role guardian', function () { - it('succeeds', async function () { - await this.manager - .connect(this.roles.SOME_GUARDIAN.members[0]) - .cancel(this.caller, this.target, this.calldata); - }); - }); - - describe('when caller is any other account', function () { - it('reverts as AccessManagerUnauthorizedCancel', async function () { - await expect(this.manager.connect(this.other).cancel(this.caller, this.target, this.calldata)) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerUnauthorizedCancel') - .withArgs(this.other, this.caller, this.target, this.method.selector); - }); - }); - }, - after() { - it('succeeds', async function () { - await this.manager.connect(this.caller).cancel(this.caller, this.target, this.calldata); - }); - }, - expired() { - it('succeeds', async function () { - await this.manager.connect(this.caller).cancel(this.caller, this.target, this.calldata); - }); - }, - }, - notScheduled() { - it('reverts as AccessManagerNotScheduled', async function () { - await expect(this.manager.cancel(this.caller, this.target, this.calldata)) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerNotScheduled') - .withArgs(this.operationId); - }); - }, - }); - - it('cancels an operation and resets schedule', async function () { - const { operationId, schedule } = await prepareOperation(this.manager, { - caller: this.caller, - target: this.target, - calldata: this.calldata, - delay: this.scheduleIn, - }); - await schedule(); - await expect(this.manager.connect(this.caller).cancel(this.caller, this.target, this.calldata)) - .to.emit(this.manager, 'OperationCanceled') - .withArgs(operationId, 1n); - expect(await this.manager.getSchedule(operationId)).to.equal('0'); - }); - }); - - describe('with Ownable target contract', function () { - const roleId = 1n; - - beforeEach(async function () { - this.ownable = await ethers.deployContract('$Ownable', [this.manager]); - - // add user to role - await this.manager.$_grantRole(roleId, this.user, 0, 0); - }); - - it('initial state', async function () { - expect(await this.ownable.owner()).to.equal(this.manager); - }); - - describe('Contract is closed', function () { - beforeEach(async function () { - await this.manager.$_setTargetClosed(this.ownable, true); - }); - - it('directly call: reverts', async function () { - await expect(this.ownable.connect(this.user).$_checkOwner()) - .to.be.revertedWithCustomError(this.ownable, 'OwnableUnauthorizedAccount') - .withArgs(this.user); - }); - - it('relayed call (with role): reverts', async function () { - await expect( - this.manager.connect(this.user).execute(this.ownable, this.ownable.$_checkOwner.getFragment().selector), - ) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerUnauthorizedCall') - .withArgs(this.user, this.ownable, this.ownable.$_checkOwner.getFragment().selector); - }); - - it('relayed call (without role): reverts', async function () { - await expect( - this.manager.connect(this.other).execute(this.ownable, this.ownable.$_checkOwner.getFragment().selector), - ) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerUnauthorizedCall') - .withArgs(this.other, this.ownable, this.ownable.$_checkOwner.getFragment().selector); - }); - }); - - describe('Contract is managed', function () { - describe('function is open to specific role', function () { - beforeEach(async function () { - await this.manager.$_setTargetFunctionRole( - this.ownable, - this.ownable.$_checkOwner.getFragment().selector, - roleId, - ); - }); - - it('directly call: reverts', async function () { - await expect(this.ownable.connect(this.user).$_checkOwner()) - .to.be.revertedWithCustomError(this.ownable, 'OwnableUnauthorizedAccount') - .withArgs(this.user); - }); - - it('relayed call (with role): success', async function () { - await this.manager.connect(this.user).execute(this.ownable, this.ownable.$_checkOwner.getFragment().selector); - }); - - it('relayed call (without role): reverts', async function () { - await expect( - this.manager.connect(this.other).execute(this.ownable, this.ownable.$_checkOwner.getFragment().selector), - ) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerUnauthorizedCall') - .withArgs(this.other, this.ownable, this.ownable.$_checkOwner.getFragment().selector); - }); - }); - - describe('function is open to public role', function () { - beforeEach(async function () { - await this.manager.$_setTargetFunctionRole( - this.ownable, - this.ownable.$_checkOwner.getFragment().selector, - this.roles.PUBLIC.id, - ); - }); - - it('directly call: reverts', async function () { - await expect(this.ownable.connect(this.user).$_checkOwner()) - .to.be.revertedWithCustomError(this.ownable, 'OwnableUnauthorizedAccount') - .withArgs(this.user); - }); - - it('relayed call (with role): success', async function () { - await this.manager.connect(this.user).execute(this.ownable, this.ownable.$_checkOwner.getFragment().selector); - }); - - it('relayed call (without role): success', async function () { - await this.manager - .connect(this.other) - .execute(this.ownable, this.ownable.$_checkOwner.getFragment().selector); - }); - }); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/access/manager/AuthorityUtils.test.js b/lib/openzeppelin-contracts/test/access/manager/AuthorityUtils.test.js deleted file mode 100644 index 905913f..0000000 --- a/lib/openzeppelin-contracts/test/access/manager/AuthorityUtils.test.js +++ /dev/null @@ -1,102 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -async function fixture() { - const [user, other] = await ethers.getSigners(); - - const mock = await ethers.deployContract('$AuthorityUtils'); - const notAuthorityMock = await ethers.deployContract('NotAuthorityMock'); - const authorityNoDelayMock = await ethers.deployContract('AuthorityNoDelayMock'); - const authorityDelayMock = await ethers.deployContract('AuthorityDelayMock'); - const authorityNoResponse = await ethers.deployContract('AuthorityNoResponse'); - - return { - user, - other, - mock, - notAuthorityMock, - authorityNoDelayMock, - authorityDelayMock, - authorityNoResponse, - }; -} - -describe('AuthorityUtils', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('canCallWithDelay', function () { - describe('when authority does not have a canCall function', function () { - beforeEach(async function () { - this.authority = this.notAuthorityMock; - }); - - it('returns (immediate = 0, delay = 0)', async function () { - const { immediate, delay } = await this.mock.$canCallWithDelay( - this.authority, - this.user, - this.other, - '0x12345678', - ); - expect(immediate).to.be.false; - expect(delay).to.equal(0n); - }); - }); - - describe('when authority has no delay', function () { - beforeEach(async function () { - this.authority = this.authorityNoDelayMock; - this.immediate = true; - await this.authority._setImmediate(this.immediate); - }); - - it('returns (immediate, delay = 0)', async function () { - const { immediate, delay } = await this.mock.$canCallWithDelay( - this.authority, - this.user, - this.other, - '0x12345678', - ); - expect(immediate).to.equal(this.immediate); - expect(delay).to.equal(0n); - }); - }); - - describe('when authority replies with a delay', function () { - beforeEach(async function () { - this.authority = this.authorityDelayMock; - }); - - for (const immediate of [true, false]) { - for (const delay of [0n, 42n]) { - it(`returns (immediate=${immediate}, delay=${delay})`, async function () { - await this.authority._setImmediate(immediate); - await this.authority._setDelay(delay); - const result = await this.mock.$canCallWithDelay(this.authority, this.user, this.other, '0x12345678'); - expect(result.immediate).to.equal(immediate); - expect(result.delay).to.equal(delay); - }); - } - } - }); - - describe('when authority replies with empty data', function () { - beforeEach(async function () { - this.authority = this.authorityNoResponse; - }); - - it('returns (immediate = 0, delay = 0)', async function () { - const { immediate, delay } = await this.mock.$canCallWithDelay( - this.authority, - this.user, - this.other, - '0x12345678', - ); - expect(immediate).to.be.false; - expect(delay).to.equal(0n); - }); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/finance/VestingWallet.behavior.js b/lib/openzeppelin-contracts/test/finance/VestingWallet.behavior.js deleted file mode 100644 index b45ffee..0000000 --- a/lib/openzeppelin-contracts/test/finance/VestingWallet.behavior.js +++ /dev/null @@ -1,87 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const time = require('../helpers/time'); - -async function envSetup(mock, beneficiary, token) { - return { - eth: { - checkRelease: async (tx, amount) => { - await expect(tx).to.changeEtherBalances([mock, beneficiary], [-amount, amount]); - }, - setupFailure: async () => { - const beneficiaryMock = await ethers.deployContract('EtherReceiverMock'); - await beneficiaryMock.setAcceptEther(false); - await mock.connect(beneficiary).transferOwnership(beneficiaryMock); - return { args: [], error: [mock, 'FailedCall'] }; - }, - releasedEvent: 'EtherReleased', - args: [], - }, - token: { - checkRelease: async (tx, amount) => { - await expect(tx).to.emit(token, 'Transfer').withArgs(mock, beneficiary, amount); - await expect(tx).to.changeTokenBalances(token, [mock, beneficiary], [-amount, amount]); - }, - setupFailure: async () => { - const pausableToken = await ethers.deployContract('$ERC20Pausable', ['Name', 'Symbol']); - await pausableToken.$_pause(); - return { - args: [ethers.Typed.address(pausableToken)], - error: [pausableToken, 'EnforcedPause'], - }; - }, - releasedEvent: 'ERC20Released', - args: [ethers.Typed.address(token)], - }, - }; -} - -function shouldBehaveLikeVesting() { - it('check vesting schedule', async function () { - for (const timestamp of this.schedule) { - await time.increaseTo.timestamp(timestamp); - const vesting = this.vestingFn(timestamp); - - expect(await this.mock.vestedAmount(...this.args, timestamp)).to.equal(vesting); - expect(await this.mock.releasable(...this.args)).to.equal(vesting); - } - }); - - it('execute vesting schedule', async function () { - let released = 0n; - { - const tx = await this.mock.release(...this.args); - await expect(tx) - .to.emit(this.mock, this.releasedEvent) - .withArgs(...this.args, 0); - - await this.checkRelease(tx, 0n); - } - - for (const timestamp of this.schedule) { - await time.increaseTo.timestamp(timestamp, false); - const vested = this.vestingFn(timestamp); - - const tx = await this.mock.release(...this.args); - await expect(tx).to.emit(this.mock, this.releasedEvent); - - await this.checkRelease(tx, vested - released); - released = vested; - } - }); - - it('should revert on transaction failure', async function () { - const { args, error } = await this.setupFailure(); - - for (const timestamp of this.schedule) { - await time.increaseTo.timestamp(timestamp); - - await expect(this.mock.release(...args)).to.be.revertedWithCustomError(...error); - } - }); -} - -module.exports = { - envSetup, - shouldBehaveLikeVesting, -}; diff --git a/lib/openzeppelin-contracts/test/finance/VestingWallet.test.js b/lib/openzeppelin-contracts/test/finance/VestingWallet.test.js deleted file mode 100644 index b89258d..0000000 --- a/lib/openzeppelin-contracts/test/finance/VestingWallet.test.js +++ /dev/null @@ -1,65 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { min } = require('../helpers/math'); -const time = require('../helpers/time'); - -const { envSetup, shouldBehaveLikeVesting } = require('./VestingWallet.behavior'); - -async function fixture() { - const amount = ethers.parseEther('100'); - const duration = time.duration.years(4); - const start = (await time.clock.timestamp()) + time.duration.hours(1); - - const [sender, beneficiary] = await ethers.getSigners(); - const mock = await ethers.deployContract('VestingWallet', [beneficiary, start, duration]); - - const token = await ethers.deployContract('$ERC20', ['Name', 'Symbol']); - await token.$_mint(mock, amount); - await sender.sendTransaction({ to: mock, value: amount }); - - const env = await envSetup(mock, beneficiary, token); - - const schedule = Array.from({ length: 64 }, (_, i) => (BigInt(i) * duration) / 60n + start); - const vestingFn = timestamp => min(amount, (amount * (timestamp - start)) / duration); - - return { mock, duration, start, beneficiary, schedule, vestingFn, env }; -} - -describe('VestingWallet', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - it('rejects zero address for beneficiary', async function () { - await expect(ethers.deployContract('VestingWallet', [ethers.ZeroAddress, this.start, this.duration])) - .revertedWithCustomError(this.mock, 'OwnableInvalidOwner') - .withArgs(ethers.ZeroAddress); - }); - - it('check vesting contract', async function () { - expect(await this.mock.owner()).to.equal(this.beneficiary); - expect(await this.mock.start()).to.equal(this.start); - expect(await this.mock.duration()).to.equal(this.duration); - expect(await this.mock.end()).to.equal(this.start + this.duration); - }); - - describe('vesting schedule', function () { - describe('Eth vesting', function () { - beforeEach(async function () { - Object.assign(this, this.env.eth); - }); - - shouldBehaveLikeVesting(); - }); - - describe('ERC20 vesting', function () { - beforeEach(async function () { - Object.assign(this, this.env.token); - }); - - shouldBehaveLikeVesting(); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/finance/VestingWalletCliff.test.js b/lib/openzeppelin-contracts/test/finance/VestingWalletCliff.test.js deleted file mode 100644 index 799b24c..0000000 --- a/lib/openzeppelin-contracts/test/finance/VestingWalletCliff.test.js +++ /dev/null @@ -1,70 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { min } = require('../helpers/math'); -const time = require('../helpers/time'); - -const { envSetup, shouldBehaveLikeVesting } = require('./VestingWallet.behavior'); - -async function fixture() { - const amount = ethers.parseEther('100'); - const duration = time.duration.years(4); - const start = (await time.clock.timestamp()) + time.duration.hours(1); - const cliffDuration = time.duration.years(1); - const cliff = start + cliffDuration; - - const [sender, beneficiary] = await ethers.getSigners(); - const mock = await ethers.deployContract('$VestingWalletCliff', [beneficiary, start, duration, cliffDuration]); - - const token = await ethers.deployContract('$ERC20', ['Name', 'Symbol']); - await token.$_mint(mock, amount); - await sender.sendTransaction({ to: mock, value: amount }); - - const env = await envSetup(mock, beneficiary, token); - - const schedule = Array.from({ length: 64 }, (_, i) => (BigInt(i) * duration) / 60n + start); - const vestingFn = timestamp => min(amount, timestamp < cliff ? 0n : (amount * (timestamp - start)) / duration); - - return { mock, duration, start, beneficiary, cliff, schedule, vestingFn, env }; -} - -describe('VestingWalletCliff', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - it('rejects a larger cliff than vesting duration', async function () { - await expect( - ethers.deployContract('$VestingWalletCliff', [this.beneficiary, this.start, this.duration, this.duration + 1n]), - ) - .revertedWithCustomError(this.mock, 'InvalidCliffDuration') - .withArgs(this.duration + 1n, this.duration); - }); - - it('check vesting contract', async function () { - expect(await this.mock.owner()).to.equal(this.beneficiary); - expect(await this.mock.start()).to.equal(this.start); - expect(await this.mock.duration()).to.equal(this.duration); - expect(await this.mock.end()).to.equal(this.start + this.duration); - expect(await this.mock.cliff()).to.equal(this.cliff); - }); - - describe('vesting schedule', function () { - describe('Eth vesting', function () { - beforeEach(async function () { - Object.assign(this, this.env.eth); - }); - - shouldBehaveLikeVesting(); - }); - - describe('ERC20 vesting', function () { - beforeEach(async function () { - Object.assign(this, this.env.token); - }); - - shouldBehaveLikeVesting(); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/governance/Governor.t.sol b/lib/openzeppelin-contracts/test/governance/Governor.t.sol deleted file mode 100644 index 958461a..0000000 --- a/lib/openzeppelin-contracts/test/governance/Governor.t.sol +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {Test} from "forge-std/Test.sol"; -import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; -import {Governor} from "@openzeppelin/contracts/governance/Governor.sol"; - -contract GovernorInternalTest is Test, Governor { - constructor() Governor("") {} - - function testValidDescriptionForProposer(string memory description, address proposer, bool includeProposer) public { - if (includeProposer) { - description = string.concat(description, "#proposer=", Strings.toHexString(proposer)); - } - assertTrue(_isValidDescriptionForProposer(proposer, description)); - } - - function testInvalidDescriptionForProposer( - string memory description, - address commitProposer, - address actualProposer - ) public { - vm.assume(commitProposer != actualProposer); - description = string.concat(description, "#proposer=", Strings.toHexString(commitProposer)); - assertFalse(_isValidDescriptionForProposer(actualProposer, description)); - } - - // We don't need to truly implement the missing functions because we are just testing - // internal helpers. - - function clock() public pure override returns (uint48) {} - - // solhint-disable-next-line func-name-mixedcase - function CLOCK_MODE() public pure override returns (string memory) {} - - // solhint-disable-next-line func-name-mixedcase - function COUNTING_MODE() public pure virtual override returns (string memory) {} - - function votingDelay() public pure virtual override returns (uint256) {} - - function votingPeriod() public pure virtual override returns (uint256) {} - - function quorum(uint256) public pure virtual override returns (uint256) {} - - function hasVoted(uint256, address) public pure virtual override returns (bool) {} - - function _quorumReached(uint256) internal pure virtual override returns (bool) {} - - function _voteSucceeded(uint256) internal pure virtual override returns (bool) {} - - function _getVotes(address, uint256, bytes memory) internal pure virtual override returns (uint256) {} - - function _countVote(uint256, address, uint8, uint256, bytes memory) internal virtual override returns (uint256) {} -} diff --git a/lib/openzeppelin-contracts/test/governance/Governor.test.js b/lib/openzeppelin-contracts/test/governance/Governor.test.js deleted file mode 100644 index 3e48ccf..0000000 --- a/lib/openzeppelin-contracts/test/governance/Governor.test.js +++ /dev/null @@ -1,992 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { GovernorHelper } = require('../helpers/governance'); -const { getDomain, Ballot } = require('../helpers/eip712'); -const { ProposalState, VoteType } = require('../helpers/enums'); -const time = require('../helpers/time'); - -const { shouldSupportInterfaces } = require('../utils/introspection/SupportsInterface.behavior'); -const { shouldBehaveLikeERC6372 } = require('./utils/ERC6372.behavior'); - -const TOKENS = [ - { Token: '$ERC20Votes', mode: 'blocknumber' }, - { Token: '$ERC20VotesTimestampMock', mode: 'timestamp' }, - { Token: '$ERC20VotesLegacyMock', mode: 'blocknumber' }, -]; - -const name = 'OZ-Governor'; -const version = '1'; -const tokenName = 'MockToken'; -const tokenSymbol = 'MTKN'; -const tokenSupply = ethers.parseEther('100'); -const votingDelay = 4n; -const votingPeriod = 16n; -const value = ethers.parseEther('1'); - -const signBallot = account => (contract, message) => - getDomain(contract).then(domain => account.signTypedData(domain, { Ballot }, message)); - -async function deployToken(contractName) { - try { - return await ethers.deployContract(contractName, [tokenName, tokenSymbol, tokenName, version]); - } catch (error) { - if (error.message == 'incorrect number of arguments to constructor') { - // ERC20VotesLegacyMock has a different construction that uses version='1' by default. - return ethers.deployContract(contractName, [tokenName, tokenSymbol, tokenName]); - } - throw error; - } -} - -describe('Governor', function () { - for (const { Token, mode } of TOKENS) { - const fixture = async () => { - const [owner, proposer, voter1, voter2, voter3, voter4, userEOA] = await ethers.getSigners(); - const receiver = await ethers.deployContract('CallReceiverMock'); - - const token = await deployToken(Token, [tokenName, tokenSymbol, version]); - const mock = await ethers.deployContract('$GovernorMock', [ - name, // name - votingDelay, // initialVotingDelay - votingPeriod, // initialVotingPeriod - 0n, // initialProposalThreshold - token, // tokenAddress - 10n, // quorumNumeratorValue - ]); - - await owner.sendTransaction({ to: mock, value }); - await token.$_mint(owner, tokenSupply); - - const helper = new GovernorHelper(mock, mode); - await helper.connect(owner).delegate({ token: token, to: voter1, value: ethers.parseEther('10') }); - await helper.connect(owner).delegate({ token: token, to: voter2, value: ethers.parseEther('7') }); - await helper.connect(owner).delegate({ token: token, to: voter3, value: ethers.parseEther('5') }); - await helper.connect(owner).delegate({ token: token, to: voter4, value: ethers.parseEther('2') }); - - return { - owner, - proposer, - voter1, - voter2, - voter3, - voter4, - userEOA, - receiver, - token, - mock, - helper, - }; - }; - - describe(`using ${Token}`, function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - // initiate fresh proposal - this.proposal = this.helper.setProposal( - [ - { - target: this.receiver.target, - data: this.receiver.interface.encodeFunctionData('mockFunction'), - value, - }, - ], - '', - ); - }); - - shouldSupportInterfaces(['ERC1155Receiver', 'Governor']); - shouldBehaveLikeERC6372(mode); - - it('deployment check', async function () { - expect(await this.mock.name()).to.equal(name); - expect(await this.mock.token()).to.equal(this.token); - expect(await this.mock.votingDelay()).to.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.equal(votingPeriod); - expect(await this.mock.quorum(0)).to.equal(0n); - expect(await this.mock.COUNTING_MODE()).to.equal('support=bravo&quorum=for,abstain'); - }); - - it('nominal workflow', async function () { - // Before - expect(await this.mock.proposalProposer(this.proposal.id)).to.equal(ethers.ZeroAddress); - expect(await this.mock.hasVoted(this.proposal.id, this.owner)).to.be.false; - expect(await this.mock.hasVoted(this.proposal.id, this.voter1)).to.be.false; - expect(await this.mock.hasVoted(this.proposal.id, this.voter2)).to.be.false; - expect(await ethers.provider.getBalance(this.mock)).to.equal(value); - expect(await ethers.provider.getBalance(this.receiver)).to.equal(0n); - - expect(await this.mock.proposalEta(this.proposal.id)).to.equal(0n); - expect(await this.mock.proposalNeedsQueuing(this.proposal.id)).to.be.false; - - // Run proposal - const txPropose = await this.helper.connect(this.proposer).propose(); - const timepoint = await time.clockFromReceipt[mode](txPropose); - - await expect(txPropose) - .to.emit(this.mock, 'ProposalCreated') - .withArgs( - this.proposal.id, - this.proposer, - this.proposal.targets, - this.proposal.values, - this.proposal.signatures, - this.proposal.data, - timepoint + votingDelay, - timepoint + votingDelay + votingPeriod, - this.proposal.description, - ); - - await this.helper.waitForSnapshot(); - - await expect(this.helper.connect(this.voter1).vote({ support: VoteType.For, reason: 'This is nice' })) - .to.emit(this.mock, 'VoteCast') - .withArgs(this.voter1, this.proposal.id, VoteType.For, ethers.parseEther('10'), 'This is nice'); - - await expect(this.helper.connect(this.voter2).vote({ support: VoteType.For })) - .to.emit(this.mock, 'VoteCast') - .withArgs(this.voter2, this.proposal.id, VoteType.For, ethers.parseEther('7'), ''); - - await expect(this.helper.connect(this.voter3).vote({ support: VoteType.Against })) - .to.emit(this.mock, 'VoteCast') - .withArgs(this.voter3, this.proposal.id, VoteType.Against, ethers.parseEther('5'), ''); - - await expect(this.helper.connect(this.voter4).vote({ support: VoteType.Abstain })) - .to.emit(this.mock, 'VoteCast') - .withArgs(this.voter4, this.proposal.id, VoteType.Abstain, ethers.parseEther('2'), ''); - - await this.helper.waitForDeadline(); - - const txExecute = await this.helper.execute(); - - await expect(txExecute).to.emit(this.mock, 'ProposalExecuted').withArgs(this.proposal.id); - - await expect(txExecute).to.emit(this.receiver, 'MockFunctionCalled'); - - // After - expect(await this.mock.proposalProposer(this.proposal.id)).to.equal(this.proposer); - expect(await this.mock.hasVoted(this.proposal.id, this.owner)).to.be.false; - expect(await this.mock.hasVoted(this.proposal.id, this.voter1)).to.be.true; - expect(await this.mock.hasVoted(this.proposal.id, this.voter2)).to.be.true; - expect(await ethers.provider.getBalance(this.mock)).to.equal(0n); - expect(await ethers.provider.getBalance(this.receiver)).to.equal(value); - - expect(await this.mock.proposalEta(this.proposal.id)).to.equal(0n); - expect(await this.mock.proposalNeedsQueuing(this.proposal.id)).to.be.false; - }); - - it('send ethers', async function () { - this.helper.setProposal( - [ - { - target: this.userEOA.address, - value, - }, - ], - '', - ); - - // Run proposal - await expect(async () => { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - return this.helper.execute(); - }).to.changeEtherBalances([this.mock, this.userEOA], [-value, value]); - }); - - describe('vote with signature', function () { - it('votes with an EOA signature', async function () { - await this.token.connect(this.voter1).delegate(this.userEOA); - - const nonce = await this.mock.nonces(this.userEOA); - - // Run proposal - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await expect( - this.helper.vote({ - support: VoteType.For, - voter: this.userEOA.address, - nonce, - signature: signBallot(this.userEOA), - }), - ) - .to.emit(this.mock, 'VoteCast') - .withArgs(this.userEOA, this.proposal.id, VoteType.For, ethers.parseEther('10'), ''); - - await this.helper.waitForDeadline(); - await this.helper.execute(); - - // After - expect(await this.mock.hasVoted(this.proposal.id, this.userEOA)).to.be.true; - expect(await this.mock.nonces(this.userEOA)).to.equal(nonce + 1n); - }); - - it('votes with a valid EIP-1271 signature', async function () { - const wallet = await ethers.deployContract('ERC1271WalletMock', [this.userEOA]); - - await this.token.connect(this.voter1).delegate(wallet); - - const nonce = await this.mock.nonces(this.userEOA); - - // Run proposal - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await expect( - this.helper.vote({ - support: VoteType.For, - voter: wallet.target, - nonce, - signature: signBallot(this.userEOA), - }), - ) - .to.emit(this.mock, 'VoteCast') - .withArgs(wallet, this.proposal.id, VoteType.For, ethers.parseEther('10'), ''); - await this.helper.waitForDeadline(); - await this.helper.execute(); - - // After - expect(await this.mock.hasVoted(this.proposal.id, wallet)).to.be.true; - expect(await this.mock.nonces(wallet)).to.equal(nonce + 1n); - }); - - afterEach('no other votes are cast', async function () { - expect(await this.mock.hasVoted(this.proposal.id, this.owner)).to.be.false; - expect(await this.mock.hasVoted(this.proposal.id, this.voter1)).to.be.false; - expect(await this.mock.hasVoted(this.proposal.id, this.voter2)).to.be.false; - }); - }); - - describe('should revert', function () { - describe('on propose', function () { - it('if proposal already exists', async function () { - await this.helper.propose(); - await expect(this.helper.propose()) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs(this.proposal.id, ProposalState.Pending, ethers.ZeroHash); - }); - - it('if proposer has below threshold votes', async function () { - const votes = ethers.parseEther('10'); - const threshold = ethers.parseEther('1000'); - await this.mock.$_setProposalThreshold(threshold); - await expect(this.helper.connect(this.voter1).propose()) - .to.be.revertedWithCustomError(this.mock, 'GovernorInsufficientProposerVotes') - .withArgs(this.voter1, votes, threshold); - }); - }); - - describe('on vote', function () { - it('if proposal does not exist', async function () { - await expect(this.helper.connect(this.voter1).vote({ support: VoteType.For })) - .to.be.revertedWithCustomError(this.mock, 'GovernorNonexistentProposal') - .withArgs(this.proposal.id); - }); - - it('if voting has not started', async function () { - await this.helper.propose(); - await expect(this.helper.connect(this.voter1).vote({ support: VoteType.For })) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Pending, - GovernorHelper.proposalStatesToBitMap([ProposalState.Active]), - ); - }); - - it('if support value is invalid', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await expect(this.helper.vote({ support: 255 })).to.be.revertedWithCustomError( - this.mock, - 'GovernorInvalidVoteType', - ); - }); - - it('if vote was already casted', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await expect(this.helper.connect(this.voter1).vote({ support: VoteType.For })) - .to.be.revertedWithCustomError(this.mock, 'GovernorAlreadyCastVote') - .withArgs(this.voter1); - }); - - it('if voting is over', async function () { - await this.helper.propose(); - await this.helper.waitForDeadline(); - await expect(this.helper.connect(this.voter1).vote({ support: VoteType.For })) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Defeated, - GovernorHelper.proposalStatesToBitMap([ProposalState.Active]), - ); - }); - }); - - describe('on vote by signature', function () { - beforeEach(async function () { - await this.token.connect(this.voter1).delegate(this.userEOA); - - // Run proposal - await this.helper.propose(); - await this.helper.waitForSnapshot(); - }); - - it('if signature does not match signer', async function () { - const nonce = await this.mock.nonces(this.userEOA); - - function tamper(str, index, mask) { - const arrayStr = ethers.getBytes(str); - arrayStr[index] ^= mask; - return ethers.hexlify(arrayStr); - } - - const voteParams = { - support: VoteType.For, - voter: this.userEOA.address, - nonce, - signature: (...args) => signBallot(this.userEOA)(...args).then(sig => tamper(sig, 42, 0xff)), - }; - - await expect(this.helper.vote(voteParams)) - .to.be.revertedWithCustomError(this.mock, 'GovernorInvalidSignature') - .withArgs(voteParams.voter); - }); - - it('if vote nonce is incorrect', async function () { - const nonce = await this.mock.nonces(this.userEOA); - - const voteParams = { - support: VoteType.For, - voter: this.userEOA.address, - nonce: nonce + 1n, - signature: signBallot(this.userEOA), - }; - - await expect(this.helper.vote(voteParams)) - .to.be.revertedWithCustomError(this.mock, 'GovernorInvalidSignature') - .withArgs(voteParams.voter); - }); - }); - - describe('on queue', function () { - it('always', async function () { - await this.helper.connect(this.proposer).propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await expect(this.helper.queue()).to.be.revertedWithCustomError(this.mock, 'GovernorQueueNotImplemented'); - }); - }); - - describe('on execute', function () { - it('if proposal does not exist', async function () { - await expect(this.helper.execute()) - .to.be.revertedWithCustomError(this.mock, 'GovernorNonexistentProposal') - .withArgs(this.proposal.id); - }); - - it('if quorum is not reached', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter3).vote({ support: VoteType.For }); - await expect(this.helper.execute()) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Active, - GovernorHelper.proposalStatesToBitMap([ProposalState.Succeeded, ProposalState.Queued]), - ); - }); - - it('if score not reached', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.Against }); - await expect(this.helper.execute()) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Active, - GovernorHelper.proposalStatesToBitMap([ProposalState.Succeeded, ProposalState.Queued]), - ); - }); - - it('if voting is not over', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await expect(this.helper.execute()) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Active, - GovernorHelper.proposalStatesToBitMap([ProposalState.Succeeded, ProposalState.Queued]), - ); - }); - - it('if receiver revert without reason', async function () { - this.helper.setProposal( - [ - { - target: this.receiver.target, - data: this.receiver.interface.encodeFunctionData('mockFunctionRevertsNoReason'), - }, - ], - '', - ); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await expect(this.helper.execute()).to.be.revertedWithCustomError(this.mock, 'FailedCall'); - }); - - it('if receiver revert with reason', async function () { - this.helper.setProposal( - [ - { - target: this.receiver.target, - data: this.receiver.interface.encodeFunctionData('mockFunctionRevertsReason'), - }, - ], - '', - ); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await expect(this.helper.execute()).to.be.revertedWith('CallReceiverMock: reverting'); - }); - - it('if proposal was already executed', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.execute(); - await expect(this.helper.execute()) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Executed, - GovernorHelper.proposalStatesToBitMap([ProposalState.Succeeded, ProposalState.Queued]), - ); - }); - }); - }); - - describe('state', function () { - it('Unset', async function () { - await expect(this.mock.state(this.proposal.id)) - .to.be.revertedWithCustomError(this.mock, 'GovernorNonexistentProposal') - .withArgs(this.proposal.id); - }); - - it('Pending & Active', async function () { - await this.helper.propose(); - expect(await this.mock.state(this.proposal.id)).to.equal(ProposalState.Pending); - await this.helper.waitForSnapshot(); - expect(await this.mock.state(this.proposal.id)).to.equal(ProposalState.Pending); - await this.helper.waitForSnapshot(1n); - expect(await this.mock.state(this.proposal.id)).to.equal(ProposalState.Active); - }); - - it('Defeated', async function () { - await this.helper.propose(); - await this.helper.waitForDeadline(); - expect(await this.mock.state(this.proposal.id)).to.equal(ProposalState.Active); - await this.helper.waitForDeadline(1n); - expect(await this.mock.state(this.proposal.id)).to.equal(ProposalState.Defeated); - }); - - it('Succeeded', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - expect(await this.mock.state(this.proposal.id)).to.equal(ProposalState.Active); - await this.helper.waitForDeadline(1n); - expect(await this.mock.state(this.proposal.id)).to.equal(ProposalState.Succeeded); - }); - - it('Executed', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.execute(); - expect(await this.mock.state(this.proposal.id)).to.equal(ProposalState.Executed); - }); - }); - - describe('cancel', function () { - describe('internal', function () { - it('before proposal', async function () { - await expect(this.helper.cancel('internal')) - .to.be.revertedWithCustomError(this.mock, 'GovernorNonexistentProposal') - .withArgs(this.proposal.id); - }); - - it('after proposal', async function () { - await this.helper.propose(); - - await this.helper.cancel('internal'); - expect(await this.mock.state(this.proposal.id)).to.equal(ProposalState.Canceled); - - await this.helper.waitForSnapshot(); - await expect(this.helper.connect(this.voter1).vote({ support: VoteType.For })) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Canceled, - GovernorHelper.proposalStatesToBitMap([ProposalState.Active]), - ); - }); - - it('after vote', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - - await this.helper.cancel('internal'); - expect(await this.mock.state(this.proposal.id)).to.equal(ProposalState.Canceled); - - await this.helper.waitForDeadline(); - await expect(this.helper.execute()) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Canceled, - GovernorHelper.proposalStatesToBitMap([ProposalState.Succeeded, ProposalState.Queued]), - ); - }); - - it('after deadline', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - - await this.helper.cancel('internal'); - expect(await this.mock.state(this.proposal.id)).to.equal(ProposalState.Canceled); - - await expect(this.helper.execute()) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Canceled, - GovernorHelper.proposalStatesToBitMap([ProposalState.Succeeded, ProposalState.Queued]), - ); - }); - - it('after execution', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.execute(); - - await expect(this.helper.cancel('internal')) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Executed, - GovernorHelper.proposalStatesToBitMap( - [ProposalState.Canceled, ProposalState.Expired, ProposalState.Executed], - { inverted: true }, - ), - ); - }); - }); - - describe('public', function () { - it('before proposal', async function () { - await expect(this.helper.cancel('external')) - .to.be.revertedWithCustomError(this.mock, 'GovernorNonexistentProposal') - .withArgs(this.proposal.id); - }); - - it('after proposal', async function () { - await this.helper.propose(); - - await this.helper.cancel('external'); - }); - - it('after proposal - restricted to proposer', async function () { - await this.helper.connect(this.proposer).propose(); - - await expect(this.helper.connect(this.owner).cancel('external')) - .to.be.revertedWithCustomError(this.mock, 'GovernorOnlyProposer') - .withArgs(this.owner); - }); - - it('after vote started', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(1n); // snapshot + 1 block - - await expect(this.helper.cancel('external')) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Active, - GovernorHelper.proposalStatesToBitMap([ProposalState.Pending]), - ); - }); - - it('after vote', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - - await expect(this.helper.cancel('external')) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Active, - GovernorHelper.proposalStatesToBitMap([ProposalState.Pending]), - ); - }); - - it('after deadline', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - - await expect(this.helper.cancel('external')) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Succeeded, - GovernorHelper.proposalStatesToBitMap([ProposalState.Pending]), - ); - }); - - it('after execution', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.execute(); - - await expect(this.helper.cancel('external')) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Executed, - GovernorHelper.proposalStatesToBitMap([ProposalState.Pending]), - ); - }); - }); - }); - - describe('proposal length', function () { - it('empty', async function () { - this.helper.setProposal([], ''); - - await expect(this.helper.propose()) - .to.be.revertedWithCustomError(this.mock, 'GovernorInvalidProposalLength') - .withArgs(0, 0, 0); - }); - - it('mismatch #1', async function () { - this.helper.setProposal( - { - targets: [], - values: [0n], - data: [this.receiver.interface.encodeFunctionData('mockFunction')], - }, - '', - ); - await expect(this.helper.propose()) - .to.be.revertedWithCustomError(this.mock, 'GovernorInvalidProposalLength') - .withArgs(0, 1, 1); - }); - - it('mismatch #2', async function () { - this.helper.setProposal( - { - targets: [this.receiver.target], - values: [], - data: [this.receiver.interface.encodeFunctionData('mockFunction')], - }, - '', - ); - await expect(this.helper.propose()) - .to.be.revertedWithCustomError(this.mock, 'GovernorInvalidProposalLength') - .withArgs(1, 1, 0); - }); - - it('mismatch #3', async function () { - this.helper.setProposal( - { - targets: [this.receiver.target], - values: [0n], - data: [], - }, - '', - ); - await expect(this.helper.propose()) - .to.be.revertedWithCustomError(this.mock, 'GovernorInvalidProposalLength') - .withArgs(1, 0, 1); - }); - }); - - describe('frontrun protection using description suffix', function () { - function shouldPropose() { - it('proposer can propose', async function () { - const txPropose = await this.helper.connect(this.proposer).propose(); - - await expect(txPropose) - .to.emit(this.mock, 'ProposalCreated') - .withArgs( - this.proposal.id, - this.proposer, - this.proposal.targets, - this.proposal.values, - this.proposal.signatures, - this.proposal.data, - (await time.clockFromReceipt[mode](txPropose)) + votingDelay, - (await time.clockFromReceipt[mode](txPropose)) + votingDelay + votingPeriod, - this.proposal.description, - ); - }); - - it('someone else can propose', async function () { - const txPropose = await this.helper.connect(this.voter1).propose(); - - await expect(txPropose) - .to.emit(this.mock, 'ProposalCreated') - .withArgs( - this.proposal.id, - this.voter1, - this.proposal.targets, - this.proposal.values, - this.proposal.signatures, - this.proposal.data, - (await time.clockFromReceipt[mode](txPropose)) + votingDelay, - (await time.clockFromReceipt[mode](txPropose)) + votingDelay + votingPeriod, - this.proposal.description, - ); - }); - } - - describe('without protection', function () { - describe('without suffix', function () { - shouldPropose(); - }); - - describe('with different suffix', function () { - beforeEach(function () { - this.proposal = this.helper.setProposal( - [ - { - target: this.receiver.target, - data: this.receiver.interface.encodeFunctionData('mockFunction'), - value, - }, - ], - `#wrong-suffix=${this.proposer}`, - ); - }); - - shouldPropose(); - }); - - describe('with proposer suffix but bad address part', function () { - beforeEach(function () { - this.proposal = this.helper.setProposal( - [ - { - target: this.receiver.target, - data: this.receiver.interface.encodeFunctionData('mockFunction'), - value, - }, - ], - `#proposer=0x3C44CdDdB6a900fa2b585dd299e03d12FA429XYZ`, // XYZ are not a valid hex char - ); - }); - - shouldPropose(); - }); - }); - - describe('with protection via proposer suffix', function () { - beforeEach(function () { - this.proposal = this.helper.setProposal( - [ - { - target: this.receiver.target, - data: this.receiver.interface.encodeFunctionData('mockFunction'), - value, - }, - ], - `#proposer=${this.proposer}`, - ); - }); - - shouldPropose(); - }); - }); - - describe('onlyGovernance updates', function () { - it('setVotingDelay is protected', async function () { - await expect(this.mock.connect(this.owner).setVotingDelay(0n)) - .to.be.revertedWithCustomError(this.mock, 'GovernorOnlyExecutor') - .withArgs(this.owner); - }); - - it('setVotingPeriod is protected', async function () { - await expect(this.mock.connect(this.owner).setVotingPeriod(32n)) - .to.be.revertedWithCustomError(this.mock, 'GovernorOnlyExecutor') - .withArgs(this.owner); - }); - - it('setProposalThreshold is protected', async function () { - await expect(this.mock.connect(this.owner).setProposalThreshold(1_000_000_000_000_000_000n)) - .to.be.revertedWithCustomError(this.mock, 'GovernorOnlyExecutor') - .withArgs(this.owner); - }); - - it('can setVotingDelay through governance', async function () { - this.helper.setProposal( - [ - { - target: this.mock.target, - data: this.mock.interface.encodeFunctionData('setVotingDelay', [0n]), - }, - ], - '', - ); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - - await expect(this.helper.execute()).to.emit(this.mock, 'VotingDelaySet').withArgs(4n, 0n); - - expect(await this.mock.votingDelay()).to.equal(0n); - }); - - it('can setVotingPeriod through governance', async function () { - this.helper.setProposal( - [ - { - target: this.mock.target, - data: this.mock.interface.encodeFunctionData('setVotingPeriod', [32n]), - }, - ], - '', - ); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - - await expect(this.helper.execute()).to.emit(this.mock, 'VotingPeriodSet').withArgs(16n, 32n); - - expect(await this.mock.votingPeriod()).to.equal(32n); - }); - - it('cannot setVotingPeriod to 0 through governance', async function () { - const votingPeriod = 0n; - - this.helper.setProposal( - [ - { - target: this.mock.target, - data: this.mock.interface.encodeFunctionData('setVotingPeriod', [votingPeriod]), - }, - ], - '', - ); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - - await expect(this.helper.execute()) - .to.be.revertedWithCustomError(this.mock, 'GovernorInvalidVotingPeriod') - .withArgs(votingPeriod); - }); - - it('can setProposalThreshold to 0 through governance', async function () { - this.helper.setProposal( - [ - { - target: this.mock.target, - data: this.mock.interface.encodeFunctionData('setProposalThreshold', [1_000_000_000_000_000_000n]), - }, - ], - '', - ); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - - await expect(this.helper.execute()) - .to.emit(this.mock, 'ProposalThresholdSet') - .withArgs(0n, 1_000_000_000_000_000_000n); - - expect(await this.mock.proposalThreshold()).to.equal(1_000_000_000_000_000_000n); - }); - }); - - describe('safe receive', function () { - describe('ERC721', function () { - const tokenId = 1n; - - beforeEach(async function () { - this.token = await ethers.deployContract('$ERC721', ['Non Fungible Token', 'NFT']); - await this.token.$_mint(this.owner, tokenId); - }); - - it('can receive an ERC721 safeTransfer', async function () { - await this.token.connect(this.owner).safeTransferFrom(this.owner, this.mock, tokenId); - }); - }); - - describe('ERC1155', function () { - const tokenIds = { - 1: 1000n, - 2: 2000n, - 3: 3000n, - }; - - beforeEach(async function () { - this.token = await ethers.deployContract('$ERC1155', ['https://token-cdn-domain/{id}.json']); - await this.token.$_mintBatch(this.owner, Object.keys(tokenIds), Object.values(tokenIds), '0x'); - }); - - it('can receive ERC1155 safeTransfer', async function () { - await this.token.connect(this.owner).safeTransferFrom( - this.owner, - this.mock, - ...Object.entries(tokenIds)[0], // id + amount - '0x', - ); - }); - - it('can receive ERC1155 safeBatchTransfer', async function () { - await this.token - .connect(this.owner) - .safeBatchTransferFrom(this.owner, this.mock, Object.keys(tokenIds), Object.values(tokenIds), '0x'); - }); - }); - }); - }); - } -}); diff --git a/lib/openzeppelin-contracts/test/governance/TimelockController.test.js b/lib/openzeppelin-contracts/test/governance/TimelockController.test.js deleted file mode 100644 index 08410d4..0000000 --- a/lib/openzeppelin-contracts/test/governance/TimelockController.test.js +++ /dev/null @@ -1,1279 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); - -const { GovernorHelper } = require('../helpers/governance'); -const { OperationState } = require('../helpers/enums'); -const time = require('../helpers/time'); - -const { shouldSupportInterfaces } = require('../utils/introspection/SupportsInterface.behavior'); - -const salt = '0x025e7b0be353a74631ad648c667493c0e1cd31caa4cc2d3520fdc171ea0cc726'; // a random value - -const MINDELAY = time.duration.days(1); -const DEFAULT_ADMIN_ROLE = ethers.ZeroHash; -const PROPOSER_ROLE = ethers.id('PROPOSER_ROLE'); -const EXECUTOR_ROLE = ethers.id('EXECUTOR_ROLE'); -const CANCELLER_ROLE = ethers.id('CANCELLER_ROLE'); - -const getAddress = obj => obj.address ?? obj.target ?? obj; - -function genOperation(target, value, data, predecessor, salt) { - const id = ethers.keccak256( - ethers.AbiCoder.defaultAbiCoder().encode( - ['address', 'uint256', 'bytes', 'uint256', 'bytes32'], - [getAddress(target), value, data, predecessor, salt], - ), - ); - return { id, target, value, data, predecessor, salt }; -} - -function genOperationBatch(targets, values, payloads, predecessor, salt) { - const id = ethers.keccak256( - ethers.AbiCoder.defaultAbiCoder().encode( - ['address[]', 'uint256[]', 'bytes[]', 'uint256', 'bytes32'], - [targets.map(getAddress), values, payloads, predecessor, salt], - ), - ); - return { id, targets, values, payloads, predecessor, salt }; -} - -async function fixture() { - const [admin, proposer, canceller, executor, other] = await ethers.getSigners(); - - const mock = await ethers.deployContract('TimelockController', [MINDELAY, [proposer], [executor], admin]); - const callreceivermock = await ethers.deployContract('CallReceiverMock'); - const implementation2 = await ethers.deployContract('Implementation2'); - - expect(await mock.hasRole(CANCELLER_ROLE, proposer)).to.be.true; - await mock.connect(admin).revokeRole(CANCELLER_ROLE, proposer); - await mock.connect(admin).grantRole(CANCELLER_ROLE, canceller); - - return { - admin, - proposer, - canceller, - executor, - other, - mock, - callreceivermock, - implementation2, - }; -} - -describe('TimelockController', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - shouldSupportInterfaces(['ERC1155Receiver']); - - it('initial state', async function () { - expect(await this.mock.getMinDelay()).to.equal(MINDELAY); - - expect(await this.mock.DEFAULT_ADMIN_ROLE()).to.equal(DEFAULT_ADMIN_ROLE); - expect(await this.mock.PROPOSER_ROLE()).to.equal(PROPOSER_ROLE); - expect(await this.mock.EXECUTOR_ROLE()).to.equal(EXECUTOR_ROLE); - expect(await this.mock.CANCELLER_ROLE()).to.equal(CANCELLER_ROLE); - - expect( - await Promise.all( - [PROPOSER_ROLE, CANCELLER_ROLE, EXECUTOR_ROLE].map(role => this.mock.hasRole(role, this.proposer)), - ), - ).to.deep.equal([true, false, false]); - - expect( - await Promise.all( - [PROPOSER_ROLE, CANCELLER_ROLE, EXECUTOR_ROLE].map(role => this.mock.hasRole(role, this.canceller)), - ), - ).to.deep.equal([false, true, false]); - - expect( - await Promise.all( - [PROPOSER_ROLE, CANCELLER_ROLE, EXECUTOR_ROLE].map(role => this.mock.hasRole(role, this.executor)), - ), - ).to.deep.equal([false, false, true]); - }); - - it('optional admin', async function () { - const mock = await ethers.deployContract('TimelockController', [ - MINDELAY, - [this.proposer], - [this.executor], - ethers.ZeroAddress, - ]); - expect(await mock.hasRole(DEFAULT_ADMIN_ROLE, this.admin)).to.be.false; - expect(await mock.hasRole(DEFAULT_ADMIN_ROLE, mock.target)).to.be.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.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.equal(this.operation.id); - }); - }); - describe('simple', function () { - describe('schedule', function () { - beforeEach(async function () { - this.operation = genOperation( - '0x31754f590B97fD975Eb86938f18Cc304E264D2F2', - 0n, - '0x3bf92ccc', - ethers.ZeroHash, - salt, - ); - }); - - it('proposer can schedule', async function () { - const tx = await this.mock - .connect(this.proposer) - .schedule( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - ); - - await expect(tx) - .to.emit(this.mock, 'CallScheduled') - .withArgs( - this.operation.id, - 0n, - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - MINDELAY, - ) - .to.emit(this.mock, 'CallSalt') - .withArgs(this.operation.id, this.operation.salt); - - expect(await this.mock.getTimestamp(this.operation.id)).to.equal( - (await time.clockFromReceipt.timestamp(tx)) + MINDELAY, - ); - }); - - it('prevent overwriting active operation', async function () { - await this.mock - .connect(this.proposer) - .schedule( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - ); - - await expect( - this.mock - .connect(this.proposer) - .schedule( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - ), - ) - .to.be.revertedWithCustomError(this.mock, 'TimelockUnexpectedOperationState') - .withArgs(this.operation.id, GovernorHelper.proposalStatesToBitMap(OperationState.Unset)); - }); - - it('prevent non-proposer from committing', async function () { - await expect( - this.mock - .connect(this.other) - .schedule( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - ), - ) - .to.be.revertedWithCustomError(this.mock, 'AccessControlUnauthorizedAccount') - .withArgs(this.other, PROPOSER_ROLE); - }); - - it('enforce minimum delay', async function () { - await expect( - this.mock - .connect(this.proposer) - .schedule( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - MINDELAY - 1n, - ), - ) - .to.be.revertedWithCustomError(this.mock, 'TimelockInsufficientDelay') - .withArgs(MINDELAY - 1n, MINDELAY); - }); - - it('schedule operation with salt zero', async function () { - await expect( - this.mock - .connect(this.proposer) - .schedule( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - ethers.ZeroHash, - MINDELAY, - ), - ).to.not.emit(this.mock, 'CallSalt'); - }); - }); - - describe('execute', function () { - beforeEach(async function () { - this.operation = genOperation( - '0xAe22104DCD970750610E6FE15E623468A98b15f7', - 0n, - '0x13e414de', - ethers.ZeroHash, - '0xc1059ed2dc130227aa1d1d539ac94c641306905c020436c636e19e3fab56fc7f', - ); - }); - - it('revert if operation is not scheduled', async function () { - await expect( - this.mock - .connect(this.executor) - .execute( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - ), - ) - .to.be.revertedWithCustomError(this.mock, 'TimelockUnexpectedOperationState') - .withArgs(this.operation.id, GovernorHelper.proposalStatesToBitMap(OperationState.Ready)); - }); - - describe('with scheduled operation', function () { - beforeEach(async function () { - await this.mock - .connect(this.proposer) - .schedule( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - ); - }); - - it('revert if execution comes too early 1/2', async function () { - await expect( - this.mock - .connect(this.executor) - .execute( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - ), - ) - .to.be.revertedWithCustomError(this.mock, 'TimelockUnexpectedOperationState') - .withArgs(this.operation.id, GovernorHelper.proposalStatesToBitMap(OperationState.Ready)); - }); - - it('revert if execution comes too early 2/2', async function () { - // -1 is too tight, test sometime fails - await this.mock.getTimestamp(this.operation.id).then(clock => time.increaseTo.timestamp(clock - 5n)); - - await expect( - this.mock - .connect(this.executor) - .execute( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - ), - ) - .to.be.revertedWithCustomError(this.mock, 'TimelockUnexpectedOperationState') - .withArgs(this.operation.id, GovernorHelper.proposalStatesToBitMap(OperationState.Ready)); - }); - - describe('on time', function () { - beforeEach(async function () { - await this.mock.getTimestamp(this.operation.id).then(time.increaseTo.timestamp); - }); - - it('executor can reveal', async function () { - await expect( - this.mock - .connect(this.executor) - .execute( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - ), - ) - .to.emit(this.mock, 'CallExecuted') - .withArgs(this.operation.id, 0n, this.operation.target, this.operation.value, this.operation.data); - }); - - it('prevent non-executor from revealing', async function () { - await expect( - this.mock - .connect(this.other) - .execute( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - ), - ) - .to.be.revertedWithCustomError(this.mock, 'AccessControlUnauthorizedAccount') - .withArgs(this.other, EXECUTOR_ROLE); - }); - - it('prevents reentrancy execution', async function () { - // Create operation - const reentrant = await ethers.deployContract('$TimelockReentrant'); - const reentrantOperation = genOperation( - reentrant, - 0n, - reentrant.interface.encodeFunctionData('reenter'), - ethers.ZeroHash, - salt, - ); - - // Schedule so it can be executed - await this.mock - .connect(this.proposer) - .schedule( - reentrantOperation.target, - reentrantOperation.value, - reentrantOperation.data, - reentrantOperation.predecessor, - reentrantOperation.salt, - MINDELAY, - ); - - // Advance on time to make the operation executable - await this.mock.getTimestamp(reentrantOperation.id).then(time.increaseTo.timestamp); - - // Grant executor role to the reentrant contract - await this.mock.connect(this.admin).grantRole(EXECUTOR_ROLE, reentrant); - - // Prepare reenter - const data = this.mock.interface.encodeFunctionData('execute', [ - getAddress(reentrantOperation.target), - reentrantOperation.value, - reentrantOperation.data, - reentrantOperation.predecessor, - reentrantOperation.salt, - ]); - await reentrant.enableRentrancy(this.mock, data); - - // Expect to fail - await expect( - this.mock - .connect(this.executor) - .execute( - reentrantOperation.target, - reentrantOperation.value, - reentrantOperation.data, - reentrantOperation.predecessor, - reentrantOperation.salt, - ), - ) - .to.be.revertedWithCustomError(this.mock, 'TimelockUnexpectedOperationState') - .withArgs(reentrantOperation.id, GovernorHelper.proposalStatesToBitMap(OperationState.Ready)); - - // Disable reentrancy - await reentrant.disableReentrancy(); - const nonReentrantOperation = reentrantOperation; // Not anymore - - // Try again successfully - await expect( - this.mock - .connect(this.executor) - .execute( - nonReentrantOperation.target, - nonReentrantOperation.value, - nonReentrantOperation.data, - nonReentrantOperation.predecessor, - nonReentrantOperation.salt, - ), - ) - .to.emit(this.mock, 'CallExecuted') - .withArgs( - nonReentrantOperation.id, - 0n, - getAddress(nonReentrantOperation), - nonReentrantOperation.value, - nonReentrantOperation.data, - ); - }); - }); - }); - }); - }); - - describe('batch', function () { - describe('schedule', function () { - beforeEach(async function () { - this.operation = genOperationBatch( - Array(8).fill('0xEd912250835c812D4516BBD80BdaEA1bB63a293C'), - Array(8).fill(0n), - Array(8).fill('0x2fcb7a88'), - ethers.ZeroHash, - '0x6cf9d042ade5de78bed9ffd075eb4b2a4f6b1736932c2dc8af517d6e066f51f5', - ); - }); - - it('proposer can schedule', async function () { - const tx = this.mock - .connect(this.proposer) - .scheduleBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - ); - for (const i in this.operation.targets) { - await expect(tx) - .to.emit(this.mock, 'CallScheduled') - .withArgs( - this.operation.id, - i, - getAddress(this.operation.targets[i]), - this.operation.values[i], - this.operation.payloads[i], - this.operation.predecessor, - MINDELAY, - ) - .to.emit(this.mock, 'CallSalt') - .withArgs(this.operation.id, this.operation.salt); - } - - expect(await this.mock.getTimestamp(this.operation.id)).to.equal( - (await time.clockFromReceipt.timestamp(tx)) + MINDELAY, - ); - }); - - it('prevent overwriting active operation', async function () { - await this.mock - .connect(this.proposer) - .scheduleBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - ); - - await expect( - this.mock - .connect(this.proposer) - .scheduleBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - ), - ) - .to.be.revertedWithCustomError(this.mock, 'TimelockUnexpectedOperationState') - .withArgs(this.operation.id, GovernorHelper.proposalStatesToBitMap(OperationState.Unset)); - }); - - it('length of batch parameter must match #1', async function () { - await expect( - this.mock - .connect(this.proposer) - .scheduleBatch( - this.operation.targets, - [], - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - ), - ) - .to.be.revertedWithCustomError(this.mock, 'TimelockInvalidOperationLength') - .withArgs(this.operation.targets.length, this.operation.payloads.length, 0n); - }); - - it('length of batch parameter must match #1', async function () { - await expect( - this.mock - .connect(this.proposer) - .scheduleBatch( - this.operation.targets, - this.operation.values, - [], - this.operation.predecessor, - this.operation.salt, - MINDELAY, - ), - ) - .to.be.revertedWithCustomError(this.mock, 'TimelockInvalidOperationLength') - .withArgs(this.operation.targets.length, 0n, this.operation.payloads.length); - }); - - it('prevent non-proposer from committing', async function () { - await expect( - this.mock - .connect(this.other) - .scheduleBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - ), - ) - .to.be.revertedWithCustomError(this.mock, 'AccessControlUnauthorizedAccount') - .withArgs(this.other, PROPOSER_ROLE); - }); - - it('enforce minimum delay', async function () { - await expect( - this.mock - .connect(this.proposer) - .scheduleBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - MINDELAY - 1n, - ), - ) - .to.be.revertedWithCustomError(this.mock, 'TimelockInsufficientDelay') - .withArgs(MINDELAY - 1n, MINDELAY); - }); - }); - - describe('execute', function () { - beforeEach(async function () { - this.operation = genOperationBatch( - Array(8).fill('0x76E53CcEb05131Ef5248553bEBDb8F70536830b1'), - Array(8).fill(0n), - Array(8).fill('0x58a60f63'), - ethers.ZeroHash, - '0x9545eeabc7a7586689191f78a5532443698538e54211b5bd4d7dc0fc0102b5c7', - ); - }); - - it('revert if operation is not scheduled', async function () { - await expect( - this.mock - .connect(this.executor) - .executeBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - ), - ) - .to.be.revertedWithCustomError(this.mock, 'TimelockUnexpectedOperationState') - .withArgs(this.operation.id, GovernorHelper.proposalStatesToBitMap(OperationState.Ready)); - }); - - describe('with scheduled operation', function () { - beforeEach(async function () { - await this.mock - .connect(this.proposer) - .scheduleBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - ); - }); - - it('revert if execution comes too early 1/2', async function () { - await expect( - this.mock - .connect(this.executor) - .executeBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - ), - ) - .to.be.revertedWithCustomError(this.mock, 'TimelockUnexpectedOperationState') - .withArgs(this.operation.id, GovernorHelper.proposalStatesToBitMap(OperationState.Ready)); - }); - - it('revert if execution comes too early 2/2', async function () { - // -1 is to tight, test sometime fails - await this.mock.getTimestamp(this.operation.id).then(clock => time.increaseTo.timestamp(clock - 5n)); - - await expect( - this.mock - .connect(this.executor) - .executeBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - ), - ) - .to.be.revertedWithCustomError(this.mock, 'TimelockUnexpectedOperationState') - .withArgs(this.operation.id, GovernorHelper.proposalStatesToBitMap(OperationState.Ready)); - }); - - describe('on time', function () { - beforeEach(async function () { - await this.mock.getTimestamp(this.operation.id).then(time.increaseTo.timestamp); - }); - - it('executor can reveal', async function () { - const tx = this.mock - .connect(this.executor) - .executeBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - ); - for (const i in this.operation.targets) { - await expect(tx) - .to.emit(this.mock, 'CallExecuted') - .withArgs( - this.operation.id, - i, - this.operation.targets[i], - this.operation.values[i], - this.operation.payloads[i], - ); - } - }); - - it('prevent non-executor from revealing', async function () { - await expect( - this.mock - .connect(this.other) - .executeBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - ), - ) - .to.be.revertedWithCustomError(this.mock, 'AccessControlUnauthorizedAccount') - .withArgs(this.other, EXECUTOR_ROLE); - }); - - it('length mismatch #1', async function () { - await expect( - this.mock - .connect(this.executor) - .executeBatch( - [], - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - ), - ) - .to.be.revertedWithCustomError(this.mock, 'TimelockInvalidOperationLength') - .withArgs(0, this.operation.payloads.length, this.operation.values.length); - }); - - it('length mismatch #2', async function () { - await expect( - this.mock - .connect(this.executor) - .executeBatch( - this.operation.targets, - [], - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - ), - ) - .to.be.revertedWithCustomError(this.mock, 'TimelockInvalidOperationLength') - .withArgs(this.operation.targets.length, this.operation.payloads.length, 0n); - }); - - it('length mismatch #3', async function () { - await expect( - this.mock - .connect(this.executor) - .executeBatch( - this.operation.targets, - this.operation.values, - [], - this.operation.predecessor, - this.operation.salt, - ), - ) - .to.be.revertedWithCustomError(this.mock, 'TimelockInvalidOperationLength') - .withArgs(this.operation.targets.length, 0n, this.operation.values.length); - }); - - it('prevents reentrancy execution', async function () { - // Create operation - const reentrant = await ethers.deployContract('$TimelockReentrant'); - const reentrantBatchOperation = genOperationBatch( - [reentrant], - [0n], - [reentrant.interface.encodeFunctionData('reenter')], - ethers.ZeroHash, - salt, - ); - - // Schedule so it can be executed - await this.mock - .connect(this.proposer) - .scheduleBatch( - reentrantBatchOperation.targets, - reentrantBatchOperation.values, - reentrantBatchOperation.payloads, - reentrantBatchOperation.predecessor, - reentrantBatchOperation.salt, - MINDELAY, - ); - - // Advance on time to make the operation executable - await this.mock.getTimestamp(reentrantBatchOperation.id).then(time.increaseTo.timestamp); - - // Grant executor role to the reentrant contract - await this.mock.connect(this.admin).grantRole(EXECUTOR_ROLE, reentrant); - - // Prepare reenter - const data = this.mock.interface.encodeFunctionData('executeBatch', [ - reentrantBatchOperation.targets.map(getAddress), - reentrantBatchOperation.values, - reentrantBatchOperation.payloads, - reentrantBatchOperation.predecessor, - reentrantBatchOperation.salt, - ]); - await reentrant.enableRentrancy(this.mock, data); - - // Expect to fail - await expect( - this.mock - .connect(this.executor) - .executeBatch( - reentrantBatchOperation.targets, - reentrantBatchOperation.values, - reentrantBatchOperation.payloads, - reentrantBatchOperation.predecessor, - reentrantBatchOperation.salt, - ), - ) - .to.be.revertedWithCustomError(this.mock, 'TimelockUnexpectedOperationState') - .withArgs(reentrantBatchOperation.id, GovernorHelper.proposalStatesToBitMap(OperationState.Ready)); - - // Disable reentrancy - await reentrant.disableReentrancy(); - const nonReentrantBatchOperation = reentrantBatchOperation; // Not anymore - - // Try again successfully - const tx = this.mock - .connect(this.executor) - .executeBatch( - nonReentrantBatchOperation.targets, - nonReentrantBatchOperation.values, - nonReentrantBatchOperation.payloads, - nonReentrantBatchOperation.predecessor, - nonReentrantBatchOperation.salt, - ); - for (const i in nonReentrantBatchOperation.targets) { - await expect(tx) - .to.emit(this.mock, 'CallExecuted') - .withArgs( - nonReentrantBatchOperation.id, - i, - nonReentrantBatchOperation.targets[i], - nonReentrantBatchOperation.values[i], - nonReentrantBatchOperation.payloads[i], - ); - } - }); - }); - }); - - it('partial execution', async function () { - const operation = genOperationBatch( - [this.callreceivermock, this.callreceivermock, this.callreceivermock], - [0n, 0n, 0n], - [ - this.callreceivermock.interface.encodeFunctionData('mockFunction'), - this.callreceivermock.interface.encodeFunctionData('mockFunctionRevertsNoReason'), - this.callreceivermock.interface.encodeFunctionData('mockFunction'), - ], - ethers.ZeroHash, - '0x8ac04aa0d6d66b8812fb41d39638d37af0a9ab11da507afd65c509f8ed079d3e', - ); - - await this.mock - .connect(this.proposer) - .scheduleBatch( - operation.targets, - operation.values, - operation.payloads, - operation.predecessor, - operation.salt, - MINDELAY, - ); - - await this.mock.getTimestamp(operation.id).then(time.increaseTo.timestamp); - - await expect( - this.mock - .connect(this.executor) - .executeBatch( - operation.targets, - operation.values, - operation.payloads, - operation.predecessor, - operation.salt, - ), - ).to.be.revertedWithCustomError(this.mock, 'FailedCall'); - }); - }); - }); - - describe('cancel', function () { - beforeEach(async function () { - this.operation = genOperation( - '0xC6837c44AA376dbe1d2709F13879E040CAb653ca', - 0n, - '0x296e58dd', - ethers.ZeroHash, - '0xa2485763600634800df9fc9646fb2c112cf98649c55f63dd1d9c7d13a64399d9', - ); - await this.mock - .connect(this.proposer) - .schedule( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - ); - }); - - it('canceller can cancel', async function () { - await expect(this.mock.connect(this.canceller).cancel(this.operation.id)) - .to.emit(this.mock, 'Cancelled') - .withArgs(this.operation.id); - }); - - it('cannot cancel invalid operation', async function () { - await expect(this.mock.connect(this.canceller).cancel(ethers.ZeroHash)) - .to.be.revertedWithCustomError(this.mock, 'TimelockUnexpectedOperationState') - .withArgs( - ethers.ZeroHash, - GovernorHelper.proposalStatesToBitMap([OperationState.Waiting, OperationState.Ready]), - ); - }); - - it('prevent non-canceller from canceling', async function () { - await expect(this.mock.connect(this.other).cancel(this.operation.id)) - .to.be.revertedWithCustomError(this.mock, 'AccessControlUnauthorizedAccount') - .withArgs(this.other, CANCELLER_ROLE); - }); - }); - }); - - describe('maintenance', function () { - it('prevent unauthorized maintenance', async function () { - await expect(this.mock.connect(this.other).updateDelay(0n)) - .to.be.revertedWithCustomError(this.mock, 'TimelockUnauthorizedCaller') - .withArgs(this.other); - }); - - it('timelock scheduled maintenance', async function () { - const newDelay = time.duration.hours(6); - const operation = genOperation( - this.mock, - 0n, - this.mock.interface.encodeFunctionData('updateDelay', [newDelay]), - ethers.ZeroHash, - '0xf8e775b2c5f4d66fb5c7fa800f35ef518c262b6014b3c0aee6ea21bff157f108', - ); - - await this.mock - .connect(this.proposer) - .schedule(operation.target, operation.value, operation.data, operation.predecessor, operation.salt, MINDELAY); - - await this.mock.getTimestamp(operation.id).then(time.increaseTo.timestamp); - - await expect( - this.mock - .connect(this.executor) - .execute(operation.target, operation.value, operation.data, operation.predecessor, operation.salt), - ) - .to.emit(this.mock, 'MinDelayChange') - .withArgs(MINDELAY, newDelay); - - expect(await this.mock.getMinDelay()).to.equal(newDelay); - }); - }); - - describe('dependency', function () { - beforeEach(async function () { - this.operation1 = genOperation( - '0xdE66bD4c97304200A95aE0AadA32d6d01A867E39', - 0n, - '0x01dc731a', - ethers.ZeroHash, - '0x64e932133c7677402ead2926f86205e2ca4686aebecf5a8077627092b9bb2feb', - ); - this.operation2 = genOperation( - '0x3c7944a3F1ee7fc8c5A5134ba7c79D11c3A1FCa3', - 0n, - '0x8f531849', - this.operation1.id, - '0x036e1311cac523f9548e6461e29fb1f8f9196b91910a41711ea22f5de48df07d', - ); - await this.mock - .connect(this.proposer) - .schedule( - this.operation1.target, - this.operation1.value, - this.operation1.data, - this.operation1.predecessor, - this.operation1.salt, - MINDELAY, - ); - await this.mock - .connect(this.proposer) - .schedule( - this.operation2.target, - this.operation2.value, - this.operation2.data, - this.operation2.predecessor, - this.operation2.salt, - MINDELAY, - ); - - await this.mock.getTimestamp(this.operation2.id).then(time.increaseTo.timestamp); - }); - - it('cannot execute before dependency', async function () { - await expect( - this.mock - .connect(this.executor) - .execute( - this.operation2.target, - this.operation2.value, - this.operation2.data, - this.operation2.predecessor, - this.operation2.salt, - ), - ) - .to.be.revertedWithCustomError(this.mock, 'TimelockUnexecutedPredecessor') - .withArgs(this.operation1.id); - }); - - it('can execute after dependency', async function () { - await this.mock - .connect(this.executor) - .execute( - this.operation1.target, - this.operation1.value, - this.operation1.data, - this.operation1.predecessor, - this.operation1.salt, - ); - await this.mock - .connect(this.executor) - .execute( - this.operation2.target, - this.operation2.value, - this.operation2.data, - this.operation2.predecessor, - this.operation2.salt, - ); - }); - }); - - describe('usage scenario', function () { - this.timeout(10000); - - it('call', async function () { - const operation = genOperation( - this.implementation2, - 0n, - this.implementation2.interface.encodeFunctionData('setValue', [42n]), - ethers.ZeroHash, - '0x8043596363daefc89977b25f9d9b4d06c3910959ef0c4d213557a903e1b555e2', - ); - - await this.mock - .connect(this.proposer) - .schedule(operation.target, operation.value, operation.data, operation.predecessor, operation.salt, MINDELAY); - - await this.mock.getTimestamp(operation.id).then(time.increaseTo.timestamp); - - await this.mock - .connect(this.executor) - .execute(operation.target, operation.value, operation.data, operation.predecessor, operation.salt); - - expect(await this.implementation2.getValue()).to.equal(42n); - }); - - it('call reverting', async function () { - const operation = genOperation( - this.callreceivermock, - 0n, - this.callreceivermock.interface.encodeFunctionData('mockFunctionRevertsNoReason'), - ethers.ZeroHash, - '0xb1b1b276fdf1a28d1e00537ea73b04d56639128b08063c1a2f70a52e38cba693', - ); - - await this.mock - .connect(this.proposer) - .schedule(operation.target, operation.value, operation.data, operation.predecessor, operation.salt, MINDELAY); - - await this.mock.getTimestamp(operation.id).then(time.increaseTo.timestamp); - - await expect( - this.mock - .connect(this.executor) - .execute(operation.target, operation.value, operation.data, operation.predecessor, operation.salt), - ).to.be.revertedWithCustomError(this.mock, 'FailedCall'); - }); - - it('call throw', async function () { - const operation = genOperation( - this.callreceivermock, - 0n, - this.callreceivermock.interface.encodeFunctionData('mockFunctionThrows'), - ethers.ZeroHash, - '0xe5ca79f295fc8327ee8a765fe19afb58f4a0cbc5053642bfdd7e73bc68e0fc67', - ); - - await this.mock - .connect(this.proposer) - .schedule(operation.target, operation.value, operation.data, operation.predecessor, operation.salt, MINDELAY); - - await this.mock.getTimestamp(operation.id).then(time.increaseTo.timestamp); - - // Targeted function reverts with a panic code (0x1) + the timelock bubble the panic code - await expect( - this.mock - .connect(this.executor) - .execute(operation.target, operation.value, operation.data, operation.predecessor, operation.salt), - ).to.be.revertedWithPanic(PANIC_CODES.ASSERTION_ERROR); - }); - - it('call out of gas', async function () { - const operation = genOperation( - this.callreceivermock, - 0n, - this.callreceivermock.interface.encodeFunctionData('mockFunctionOutOfGas'), - ethers.ZeroHash, - '0xf3274ce7c394c5b629d5215723563a744b817e1730cca5587c567099a14578fd', - ); - - await this.mock - .connect(this.proposer) - .schedule(operation.target, operation.value, operation.data, operation.predecessor, operation.salt, MINDELAY); - - await this.mock.getTimestamp(operation.id).then(time.increaseTo.timestamp); - - await expect( - this.mock - .connect(this.executor) - .execute(operation.target, operation.value, operation.data, operation.predecessor, operation.salt, { - gasLimit: '100000', - }), - ).to.be.revertedWithCustomError(this.mock, 'FailedCall'); - }); - - it('call payable with eth', async function () { - const operation = genOperation( - this.callreceivermock, - 1, - this.callreceivermock.interface.encodeFunctionData('mockFunction'), - ethers.ZeroHash, - '0x5ab73cd33477dcd36c1e05e28362719d0ed59a7b9ff14939de63a43073dc1f44', - ); - - await this.mock - .connect(this.proposer) - .schedule(operation.target, operation.value, operation.data, operation.predecessor, operation.salt, MINDELAY); - - await this.mock.getTimestamp(operation.id).then(time.increaseTo.timestamp); - - expect(await ethers.provider.getBalance(this.mock)).to.equal(0n); - expect(await ethers.provider.getBalance(this.callreceivermock)).to.equal(0n); - - await this.mock - .connect(this.executor) - .execute(operation.target, operation.value, operation.data, operation.predecessor, operation.salt, { - value: 1, - }); - - expect(await ethers.provider.getBalance(this.mock)).to.equal(0n); - expect(await ethers.provider.getBalance(this.callreceivermock)).to.equal(1n); - }); - - it('call nonpayable with eth', async function () { - const operation = genOperation( - this.callreceivermock, - 1, - this.callreceivermock.interface.encodeFunctionData('mockFunctionNonPayable'), - ethers.ZeroHash, - '0xb78edbd920c7867f187e5aa6294ae5a656cfbf0dea1ccdca3751b740d0f2bdf8', - ); - - await this.mock - .connect(this.proposer) - .schedule(operation.target, operation.value, operation.data, operation.predecessor, operation.salt, MINDELAY); - - await this.mock.getTimestamp(operation.id).then(time.increaseTo.timestamp); - - expect(await ethers.provider.getBalance(this.mock)).to.equal(0n); - expect(await ethers.provider.getBalance(this.callreceivermock)).to.equal(0n); - - await expect( - this.mock - .connect(this.executor) - .execute(operation.target, operation.value, operation.data, operation.predecessor, operation.salt), - ).to.be.revertedWithCustomError(this.mock, 'FailedCall'); - - expect(await ethers.provider.getBalance(this.mock)).to.equal(0n); - expect(await ethers.provider.getBalance(this.callreceivermock)).to.equal(0n); - }); - - it('call reverting with eth', async function () { - const operation = genOperation( - this.callreceivermock, - 1, - this.callreceivermock.interface.encodeFunctionData('mockFunctionRevertsNoReason'), - ethers.ZeroHash, - '0xdedb4563ef0095db01d81d3f2decf57cf83e4a72aa792af14c43a792b56f4de6', - ); - - await this.mock - .connect(this.proposer) - .schedule(operation.target, operation.value, operation.data, operation.predecessor, operation.salt, MINDELAY); - - await this.mock.getTimestamp(operation.id).then(time.increaseTo.timestamp); - - expect(await ethers.provider.getBalance(this.mock)).to.equal(0n); - expect(await ethers.provider.getBalance(this.callreceivermock)).to.equal(0n); - - await expect( - this.mock - .connect(this.executor) - .execute(operation.target, operation.value, operation.data, operation.predecessor, operation.salt), - ).to.be.revertedWithCustomError(this.mock, 'FailedCall'); - - expect(await ethers.provider.getBalance(this.mock)).to.equal(0n); - expect(await ethers.provider.getBalance(this.callreceivermock)).to.equal(0n); - }); - }); - - describe('safe receive', function () { - describe('ERC721', function () { - const tokenId = 1n; - - beforeEach(async function () { - this.token = await ethers.deployContract('$ERC721', ['Non Fungible Token', 'NFT']); - await this.token.$_mint(this.other, tokenId); - }); - - it('can receive an ERC721 safeTransfer', async function () { - await this.token.connect(this.other).safeTransferFrom(this.other, this.mock, tokenId); - }); - }); - - describe('ERC1155', function () { - const tokenIds = { - 1: 1000n, - 2: 2000n, - 3: 3000n, - }; - - beforeEach(async function () { - this.token = await ethers.deployContract('$ERC1155', ['https://token-cdn-domain/{id}.json']); - await this.token.$_mintBatch(this.other, Object.keys(tokenIds), Object.values(tokenIds), '0x'); - }); - - it('can receive ERC1155 safeTransfer', async function () { - await this.token.connect(this.other).safeTransferFrom( - this.other, - this.mock, - ...Object.entries(tokenIds)[0n], // id + amount - '0x', - ); - }); - - it('can receive ERC1155 safeBatchTransfer', async function () { - await this.token - .connect(this.other) - .safeBatchTransferFrom(this.other, this.mock, Object.keys(tokenIds), Object.values(tokenIds), '0x'); - }); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/governance/extensions/GovernorCountingFractional.test.js b/lib/openzeppelin-contracts/test/governance/extensions/GovernorCountingFractional.test.js deleted file mode 100644 index 393dbad..0000000 --- a/lib/openzeppelin-contracts/test/governance/extensions/GovernorCountingFractional.test.js +++ /dev/null @@ -1,248 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { GovernorHelper } = require('../../helpers/governance'); -const { VoteType } = require('../../helpers/enums'); -const { zip } = require('../../helpers/iterate'); -const { sum } = require('../../helpers/math'); - -const TOKENS = [ - { Token: '$ERC20Votes', mode: 'blocknumber' }, - { Token: '$ERC20VotesTimestampMock', mode: 'timestamp' }, -]; - -const name = 'OZ-Governor'; -const version = '1'; -const tokenName = 'MockToken'; -const tokenSymbol = 'MTKN'; -const tokenSupply = ethers.parseEther('100'); -const votingDelay = 4n; -const votingPeriod = 16n; -const value = ethers.parseEther('1'); - -describe('GovernorCountingFractional', function () { - for (const { Token, mode } of TOKENS) { - const fixture = async () => { - const [owner, proposer, voter1, voter2, voter3, voter4, other] = await ethers.getSigners(); - const receiver = await ethers.deployContract('CallReceiverMock'); - - const token = await ethers.deployContract(Token, [tokenName, tokenSymbol, version]); - const mock = await ethers.deployContract('$GovernorFractionalMock', [ - name, // name - votingDelay, // initialVotingDelay - votingPeriod, // initialVotingPeriod - 0n, // initialProposalThreshold - token, // tokenAddress - 10n, // quorumNumeratorValue - ]); - - await owner.sendTransaction({ to: mock, value }); - await token.$_mint(owner, tokenSupply); - - const helper = new GovernorHelper(mock, mode); - await helper.connect(owner).delegate({ token, to: voter1, value: ethers.parseEther('10') }); - await helper.connect(owner).delegate({ token, to: voter2, value: ethers.parseEther('7') }); - await helper.connect(owner).delegate({ token, to: voter3, value: ethers.parseEther('5') }); - await helper.connect(owner).delegate({ token, to: voter4, value: ethers.parseEther('2') }); - - return { owner, proposer, voter1, voter2, voter3, voter4, other, receiver, token, mock, helper }; - }; - - describe(`using ${Token}`, function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - - // default proposal - this.proposal = this.helper.setProposal( - [ - { - target: this.receiver.target, - value, - data: this.receiver.interface.encodeFunctionData('mockFunction'), - }, - ], - '', - ); - }); - - it('deployment check', async function () { - expect(await this.mock.name()).to.equal(name); - expect(await this.mock.token()).to.equal(this.token); - expect(await this.mock.votingDelay()).to.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.equal(votingPeriod); - expect(await this.mock.COUNTING_MODE()).to.equal( - 'support=bravo,fractional&quorum=for,abstain¶ms=fractional', - ); - }); - - it('nominal is unaffected', async function () { - await this.helper.connect(this.proposer).propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For, reason: 'This is nice' }); - await this.helper.connect(this.voter2).vote({ support: VoteType.For }); - await this.helper.connect(this.voter3).vote({ support: VoteType.Against }); - await this.helper.connect(this.voter4).vote({ support: VoteType.Abstain }); - await this.helper.waitForDeadline(); - await this.helper.execute(); - - expect(await this.mock.hasVoted(this.proposal.id, this.owner)).to.be.false; - expect(await this.mock.hasVoted(this.proposal.id, this.voter1)).to.be.true; - expect(await this.mock.hasVoted(this.proposal.id, this.voter2)).to.be.true; - expect(await ethers.provider.getBalance(this.mock)).to.equal(0n); - expect(await ethers.provider.getBalance(this.receiver)).to.equal(value); - }); - - describe('voting with a fraction of the weight', function () { - it('twice', async function () { - await this.helper.connect(this.proposer).propose(); - await this.helper.waitForSnapshot(); - - expect(await this.mock.proposalVotes(this.proposal.id)).to.deep.equal([0n, 0n, 0n]); - expect(await this.mock.hasVoted(this.proposal.id, this.voter2)).to.equal(false); - expect(await this.mock.usedVotes(this.proposal.id, this.voter2)).to.equal(0n); - - const steps = [ - ['0', '2', '1'], - ['1', '0', '1'], - ].map(votes => votes.map(vote => ethers.parseEther(vote))); - - for (const votes of steps) { - const params = ethers.solidityPacked(['uint128', 'uint128', 'uint128'], votes); - await expect( - this.helper.connect(this.voter2).vote({ - support: VoteType.Parameters, - reason: 'no particular reason', - params, - }), - ) - .to.emit(this.mock, 'VoteCastWithParams') - .withArgs( - this.voter2, - this.proposal.id, - VoteType.Parameters, - sum(...votes), - 'no particular reason', - params, - ); - } - - expect(await this.mock.proposalVotes(this.proposal.id)).to.deep.equal(zip(...steps).map(v => sum(...v))); - expect(await this.mock.hasVoted(this.proposal.id, this.voter2)).to.equal(true); - expect(await this.mock.usedVotes(this.proposal.id, this.voter2)).to.equal(sum(...[].concat(...steps))); - }); - - it('fractional then nominal', async function () { - await this.helper.connect(this.proposer).propose(); - await this.helper.waitForSnapshot(); - - expect(await this.mock.proposalVotes(this.proposal.id)).to.deep.equal([0n, 0n, 0n]); - expect(await this.mock.hasVoted(this.proposal.id, this.voter2)).to.equal(false); - expect(await this.mock.usedVotes(this.proposal.id, this.voter2)).to.equal(0n); - - const weight = ethers.parseEther('7'); - const fractional = ['1', '2', '1'].map(ethers.parseEther); - - const params = ethers.solidityPacked(['uint128', 'uint128', 'uint128'], fractional); - await expect( - this.helper.connect(this.voter2).vote({ - support: VoteType.Parameters, - reason: 'no particular reason', - params, - }), - ) - .to.emit(this.mock, 'VoteCastWithParams') - .withArgs( - this.voter2, - this.proposal.id, - VoteType.Parameters, - sum(...fractional), - 'no particular reason', - params, - ); - - await expect(this.helper.connect(this.voter2).vote({ support: VoteType.Against })) - .to.emit(this.mock, 'VoteCast') - .withArgs(this.voter2, this.proposal.id, VoteType.Against, weight - sum(...fractional), ''); - - expect(await this.mock.proposalVotes(this.proposal.id)).to.deep.equal([ - weight - sum(...fractional.slice(1)), - ...fractional.slice(1), - ]); - expect(await this.mock.hasVoted(this.proposal.id, this.voter2)).to.equal(true); - expect(await this.mock.usedVotes(this.proposal.id, this.voter2)).to.equal(weight); - }); - - it('revert if params spend more than available', async function () { - await this.helper.connect(this.proposer).propose(); - await this.helper.waitForSnapshot(); - - const weight = ethers.parseEther('7'); - const fractional = ['0', '1000', '0'].map(ethers.parseEther); - - await expect( - this.helper.connect(this.voter2).vote({ - support: VoteType.Parameters, - reason: 'no particular reason', - params: ethers.solidityPacked(['uint128', 'uint128', 'uint128'], fractional), - }), - ) - .to.be.revertedWithCustomError(this.mock, 'GovernorExceedRemainingWeight') - .withArgs(this.voter2, sum(...fractional), weight); - }); - - it('revert if no weight remaining', async function () { - await this.helper.connect(this.proposer).propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter2).vote({ support: VoteType.For }); - - await expect( - this.helper.connect(this.voter2).vote({ - support: VoteType.Parameters, - reason: 'no particular reason', - params: ethers.solidityPacked(['uint128', 'uint128', 'uint128'], [0n, 1n, 0n]), - }), - ) - .to.be.revertedWithCustomError(this.mock, 'GovernorAlreadyCastVote') - .withArgs(this.voter2); - }); - - it('revert if params are not properly formatted #1', async function () { - await this.helper.connect(this.proposer).propose(); - await this.helper.waitForSnapshot(); - - await expect( - this.helper.connect(this.voter2).vote({ - support: VoteType.Parameters, - reason: 'no particular reason', - params: ethers.solidityPacked(['uint128', 'uint128'], [0n, 1n]), - }), - ).to.be.revertedWithCustomError(this.mock, 'GovernorInvalidVoteParams'); - }); - - it('revert if params are not properly formatted #2', async function () { - await this.helper.connect(this.proposer).propose(); - await this.helper.waitForSnapshot(); - - await expect( - this.helper.connect(this.voter2).vote({ - support: VoteType.Against, - reason: 'no particular reason', - params: ethers.solidityPacked(['uint128', 'uint128', 'uint128'], [0n, 1n, 0n]), - }), - ).to.be.revertedWithCustomError(this.mock, 'GovernorInvalidVoteParams'); - }); - - it('revert if vote type is invalid', async function () { - await this.helper.connect(this.proposer).propose(); - await this.helper.waitForSnapshot(); - - await expect(this.helper.connect(this.voter2).vote({ support: 128n })).to.be.revertedWithCustomError( - this.mock, - 'GovernorInvalidVoteType', - ); - }); - }); - }); - } -}); diff --git a/lib/openzeppelin-contracts/test/governance/extensions/GovernorERC721.test.js b/lib/openzeppelin-contracts/test/governance/extensions/GovernorERC721.test.js deleted file mode 100644 index 1ae5508..0000000 --- a/lib/openzeppelin-contracts/test/governance/extensions/GovernorERC721.test.js +++ /dev/null @@ -1,131 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { GovernorHelper } = require('../../helpers/governance'); -const { VoteType } = require('../../helpers/enums'); - -const TOKENS = [ - { Token: '$ERC721Votes', mode: 'blocknumber' }, - { Token: '$ERC721VotesTimestampMock', mode: 'timestamp' }, -]; - -const name = 'OZ-Governor'; -const version = '1'; -const tokenName = 'MockNFToken'; -const tokenSymbol = 'MTKN'; -const NFT0 = 0n; -const NFT1 = 1n; -const NFT2 = 2n; -const NFT3 = 3n; -const NFT4 = 4n; -const votingDelay = 4n; -const votingPeriod = 16n; -const value = ethers.parseEther('1'); - -describe('GovernorERC721', function () { - for (const { Token, mode } of TOKENS) { - const fixture = async () => { - const [owner, voter1, voter2, voter3, voter4] = await ethers.getSigners(); - const receiver = await ethers.deployContract('CallReceiverMock'); - - const token = await ethers.deployContract(Token, [tokenName, tokenSymbol, version]); - const mock = await ethers.deployContract('$GovernorMock', [ - name, // name - votingDelay, // initialVotingDelay - votingPeriod, // initialVotingPeriod - 0n, // initialProposalThreshold - token, // tokenAddress - 10n, // quorumNumeratorValue - ]); - - await owner.sendTransaction({ to: mock, value }); - await Promise.all([NFT0, NFT1, NFT2, NFT3, NFT4].map(tokenId => token.$_mint(owner, tokenId))); - - const helper = new GovernorHelper(mock, mode); - await helper.connect(owner).delegate({ token, to: voter1, tokenId: NFT0 }); - await helper.connect(owner).delegate({ token, to: voter2, tokenId: NFT1 }); - await helper.connect(owner).delegate({ token, to: voter2, tokenId: NFT2 }); - await helper.connect(owner).delegate({ token, to: voter3, tokenId: NFT3 }); - await helper.connect(owner).delegate({ token, to: voter4, tokenId: NFT4 }); - - return { - owner, - voter1, - voter2, - voter3, - voter4, - receiver, - token, - mock, - helper, - }; - }; - - describe(`using ${Token}`, function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - // initiate fresh proposal - this.proposal = this.helper.setProposal( - [ - { - target: this.receiver.target, - data: this.receiver.interface.encodeFunctionData('mockFunction'), - value, - }, - ], - '', - ); - }); - - it('deployment check', async function () { - expect(await this.mock.name()).to.equal(name); - expect(await this.mock.token()).to.equal(this.token); - expect(await this.mock.votingDelay()).to.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.equal(votingPeriod); - expect(await this.mock.quorum(0n)).to.equal(0n); - - expect(await this.token.getVotes(this.voter1)).to.equal(1n); // NFT0 - expect(await this.token.getVotes(this.voter2)).to.equal(2n); // NFT1 & NFT2 - expect(await this.token.getVotes(this.voter3)).to.equal(1n); // NFT3 - expect(await this.token.getVotes(this.voter4)).to.equal(1n); // NFT4 - }); - - it('voting with ERC721 token', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - - await expect(this.helper.connect(this.voter1).vote({ support: VoteType.For })) - .to.emit(this.mock, 'VoteCast') - .withArgs(this.voter1, this.proposal.id, VoteType.For, 1n, ''); - - await expect(this.helper.connect(this.voter2).vote({ support: VoteType.For })) - .to.emit(this.mock, 'VoteCast') - .withArgs(this.voter2, this.proposal.id, VoteType.For, 2n, ''); - - await expect(this.helper.connect(this.voter3).vote({ support: VoteType.Against })) - .to.emit(this.mock, 'VoteCast') - .withArgs(this.voter3, this.proposal.id, VoteType.Against, 1n, ''); - - await expect(this.helper.connect(this.voter4).vote({ support: VoteType.Abstain })) - .to.emit(this.mock, 'VoteCast') - .withArgs(this.voter4, this.proposal.id, VoteType.Abstain, 1n, ''); - - await this.helper.waitForDeadline(); - await this.helper.execute(); - - expect(await this.mock.hasVoted(this.proposal.id, this.owner)).to.be.false; - expect(await this.mock.hasVoted(this.proposal.id, this.voter1)).to.be.true; - expect(await this.mock.hasVoted(this.proposal.id, this.voter2)).to.be.true; - expect(await this.mock.hasVoted(this.proposal.id, this.voter3)).to.be.true; - expect(await this.mock.hasVoted(this.proposal.id, this.voter4)).to.be.true; - - expect(await this.mock.proposalVotes(this.proposal.id)).to.deep.equal([ - 1n, // againstVotes - 3n, // forVotes - 1n, // abstainVotes - ]); - }); - }); - } -}); diff --git a/lib/openzeppelin-contracts/test/governance/extensions/GovernorPreventLateQuorum.test.js b/lib/openzeppelin-contracts/test/governance/extensions/GovernorPreventLateQuorum.test.js deleted file mode 100644 index aac0e68..0000000 --- a/lib/openzeppelin-contracts/test/governance/extensions/GovernorPreventLateQuorum.test.js +++ /dev/null @@ -1,185 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { GovernorHelper } = require('../../helpers/governance'); -const { ProposalState, VoteType } = require('../../helpers/enums'); -const time = require('../../helpers/time'); - -const TOKENS = [ - { Token: '$ERC20Votes', mode: 'blocknumber' }, - { Token: '$ERC20VotesTimestampMock', mode: 'timestamp' }, -]; - -const name = 'OZ-Governor'; -const version = '1'; -const tokenName = 'MockToken'; -const tokenSymbol = 'MTKN'; -const tokenSupply = ethers.parseEther('100'); -const votingDelay = 4n; -const votingPeriod = 16n; -const lateQuorumVoteExtension = 8n; -const quorum = ethers.parseEther('1'); -const value = ethers.parseEther('1'); - -describe('GovernorPreventLateQuorum', function () { - for (const { Token, mode } of TOKENS) { - const fixture = async () => { - const [owner, proposer, voter1, voter2, voter3, voter4] = await ethers.getSigners(); - const receiver = await ethers.deployContract('CallReceiverMock'); - - const token = await ethers.deployContract(Token, [tokenName, tokenSymbol, version]); - const mock = await ethers.deployContract('$GovernorPreventLateQuorumMock', [ - name, // name - votingDelay, // initialVotingDelay - votingPeriod, // initialVotingPeriod - 0n, // initialProposalThreshold - token, // tokenAddress - lateQuorumVoteExtension, - quorum, - ]); - - await owner.sendTransaction({ to: mock, value }); - await token.$_mint(owner, tokenSupply); - - const helper = new GovernorHelper(mock, mode); - await helper.connect(owner).delegate({ token, to: voter1, value: ethers.parseEther('10') }); - await helper.connect(owner).delegate({ token, to: voter2, value: ethers.parseEther('7') }); - await helper.connect(owner).delegate({ token, to: voter3, value: ethers.parseEther('5') }); - await helper.connect(owner).delegate({ token, to: voter4, value: ethers.parseEther('2') }); - - return { owner, proposer, voter1, voter2, voter3, voter4, receiver, token, mock, helper }; - }; - - describe(`using ${Token}`, function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - // initiate fresh proposal - this.proposal = this.helper.setProposal( - [ - { - target: this.receiver.target, - data: this.receiver.interface.encodeFunctionData('mockFunction'), - value, - }, - ], - '', - ); - }); - - it('deployment check', async function () { - expect(await this.mock.name()).to.equal(name); - expect(await this.mock.token()).to.equal(this.token); - expect(await this.mock.votingDelay()).to.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.equal(votingPeriod); - expect(await this.mock.quorum(0)).to.equal(quorum); - expect(await this.mock.lateQuorumVoteExtension()).to.equal(lateQuorumVoteExtension); - }); - - it('nominal workflow unaffected', async function () { - const txPropose = await this.helper.connect(this.proposer).propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.connect(this.voter2).vote({ support: VoteType.For }); - await this.helper.connect(this.voter3).vote({ support: VoteType.Against }); - await this.helper.connect(this.voter4).vote({ support: VoteType.Abstain }); - await this.helper.waitForDeadline(); - await this.helper.execute(); - - expect(await this.mock.hasVoted(this.proposal.id, this.owner)).to.be.false; - expect(await this.mock.hasVoted(this.proposal.id, this.voter1)).to.be.true; - expect(await this.mock.hasVoted(this.proposal.id, this.voter2)).to.be.true; - expect(await this.mock.hasVoted(this.proposal.id, this.voter3)).to.be.true; - expect(await this.mock.hasVoted(this.proposal.id, this.voter4)).to.be.true; - - expect(await this.mock.proposalVotes(this.proposal.id)).to.deep.equal([ - ethers.parseEther('5'), // againstVotes - ethers.parseEther('17'), // forVotes - ethers.parseEther('2'), // abstainVotes - ]); - - const voteStart = (await time.clockFromReceipt[mode](txPropose)) + votingDelay; - const voteEnd = (await time.clockFromReceipt[mode](txPropose)) + votingDelay + votingPeriod; - expect(await this.mock.proposalSnapshot(this.proposal.id)).to.equal(voteStart); - expect(await this.mock.proposalDeadline(this.proposal.id)).to.equal(voteEnd); - - await expect(txPropose) - .to.emit(this.mock, 'ProposalCreated') - .withArgs( - this.proposal.id, - this.proposer, - this.proposal.targets, - this.proposal.values, - this.proposal.signatures, - this.proposal.data, - voteStart, - voteEnd, - this.proposal.description, - ); - }); - - it('Delay is extended to prevent last minute take-over', async function () { - const txPropose = await this.helper.connect(this.proposer).propose(); - - // compute original schedule - const snapshotTimepoint = (await time.clockFromReceipt[mode](txPropose)) + votingDelay; - const deadlineTimepoint = (await time.clockFromReceipt[mode](txPropose)) + votingDelay + votingPeriod; - expect(await this.mock.proposalSnapshot(this.proposal.id)).to.equal(snapshotTimepoint); - expect(await this.mock.proposalDeadline(this.proposal.id)).to.equal(deadlineTimepoint); - // wait for the last minute to vote - await this.helper.waitForDeadline(-1n); - const txVote = await this.helper.connect(this.voter2).vote({ support: VoteType.For }); - - // cannot execute yet - expect(await this.mock.state(this.proposal.id)).to.equal(ProposalState.Active); - - // compute new extended schedule - const extendedDeadline = (await time.clockFromReceipt[mode](txVote)) + lateQuorumVoteExtension; - expect(await this.mock.proposalSnapshot(this.proposal.id)).to.equal(snapshotTimepoint); - expect(await this.mock.proposalDeadline(this.proposal.id)).to.equal(extendedDeadline); - - // still possible to vote - await this.helper.connect(this.voter1).vote({ support: VoteType.Against }); - - await this.helper.waitForDeadline(); - expect(await this.mock.state(this.proposal.id)).to.equal(ProposalState.Active); - await this.helper.waitForDeadline(1n); - expect(await this.mock.state(this.proposal.id)).to.equal(ProposalState.Defeated); - - // check extension event - await expect(txVote).to.emit(this.mock, 'ProposalExtended').withArgs(this.proposal.id, extendedDeadline); - }); - - describe('onlyGovernance updates', function () { - it('setLateQuorumVoteExtension is protected', async function () { - await expect(this.mock.connect(this.owner).setLateQuorumVoteExtension(0n)) - .to.be.revertedWithCustomError(this.mock, 'GovernorOnlyExecutor') - .withArgs(this.owner); - }); - - it('can setLateQuorumVoteExtension through governance', async function () { - this.helper.setProposal( - [ - { - target: this.mock.target, - data: this.mock.interface.encodeFunctionData('setLateQuorumVoteExtension', [0n]), - }, - ], - '', - ); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - - await expect(this.helper.execute()) - .to.emit(this.mock, 'LateQuorumVoteExtensionSet') - .withArgs(lateQuorumVoteExtension, 0n); - - expect(await this.mock.lateQuorumVoteExtension()).to.equal(0n); - }); - }); - }); - } -}); diff --git a/lib/openzeppelin-contracts/test/governance/extensions/GovernorStorage.test.js b/lib/openzeppelin-contracts/test/governance/extensions/GovernorStorage.test.js deleted file mode 100644 index ef56fa5..0000000 --- a/lib/openzeppelin-contracts/test/governance/extensions/GovernorStorage.test.js +++ /dev/null @@ -1,155 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { anyValue } = require('@nomicfoundation/hardhat-chai-matchers/withArgs'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); - -const { GovernorHelper, timelockSalt } = require('../../helpers/governance'); -const { VoteType } = require('../../helpers/enums'); - -const TOKENS = [ - { Token: '$ERC20Votes', mode: 'blocknumber' }, - { Token: '$ERC20VotesTimestampMock', mode: 'timestamp' }, -]; - -const DEFAULT_ADMIN_ROLE = ethers.ZeroHash; -const PROPOSER_ROLE = ethers.id('PROPOSER_ROLE'); -const EXECUTOR_ROLE = ethers.id('EXECUTOR_ROLE'); -const CANCELLER_ROLE = ethers.id('CANCELLER_ROLE'); - -const name = 'OZ-Governor'; -const version = '1'; -const tokenName = 'MockToken'; -const tokenSymbol = 'MTKN'; -const tokenSupply = ethers.parseEther('100'); -const votingDelay = 4n; -const votingPeriod = 16n; -const value = ethers.parseEther('1'); -const delay = 3600n; - -describe('GovernorStorage', function () { - for (const { Token, mode } of TOKENS) { - const fixture = async () => { - const [deployer, owner, proposer, voter1, voter2, voter3, voter4] = await ethers.getSigners(); - const receiver = await ethers.deployContract('CallReceiverMock'); - - const token = await ethers.deployContract(Token, [tokenName, tokenSymbol, version]); - const timelock = await ethers.deployContract('TimelockController', [delay, [], [], deployer]); - const mock = await ethers.deployContract('$GovernorStorageMock', [ - name, - votingDelay, - votingPeriod, - 0n, - timelock, - token, - 0n, - ]); - - await owner.sendTransaction({ to: timelock, value }); - await token.$_mint(owner, tokenSupply); - await timelock.grantRole(PROPOSER_ROLE, mock); - await timelock.grantRole(PROPOSER_ROLE, owner); - await timelock.grantRole(CANCELLER_ROLE, mock); - await timelock.grantRole(CANCELLER_ROLE, owner); - await timelock.grantRole(EXECUTOR_ROLE, ethers.ZeroAddress); - await timelock.revokeRole(DEFAULT_ADMIN_ROLE, deployer); - - const helper = new GovernorHelper(mock, mode); - await helper.connect(owner).delegate({ token, to: voter1, value: ethers.parseEther('10') }); - await helper.connect(owner).delegate({ token, to: voter2, value: ethers.parseEther('7') }); - await helper.connect(owner).delegate({ token, to: voter3, value: ethers.parseEther('5') }); - await helper.connect(owner).delegate({ token, to: voter4, value: ethers.parseEther('2') }); - - return { deployer, owner, proposer, voter1, voter2, voter3, voter4, receiver, token, timelock, mock, helper }; - }; - - describe(`using ${Token}`, function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - // initiate fresh proposal - this.proposal = this.helper.setProposal( - [ - { - target: this.receiver.target, - data: this.receiver.interface.encodeFunctionData('mockFunction'), - value, - }, - ], - '', - ); - this.proposal.timelockid = await this.timelock.hashOperationBatch( - ...this.proposal.shortProposal.slice(0, 3), - ethers.ZeroHash, - timelockSalt(this.mock.target, this.proposal.shortProposal[3]), - ); - }); - - describe('proposal indexing', function () { - it('before propose', async function () { - expect(await this.mock.proposalCount()).to.equal(0n); - - await expect(this.mock.proposalDetailsAt(0n)).to.be.revertedWithPanic(PANIC_CODES.ARRAY_ACCESS_OUT_OF_BOUNDS); - - await expect(this.mock.proposalDetails(this.proposal.id)) - .to.be.revertedWithCustomError(this.mock, 'GovernorNonexistentProposal') - .withArgs(this.proposal.id); - }); - - it('after propose', async function () { - await this.helper.propose(); - - expect(await this.mock.proposalCount()).to.equal(1n); - - expect(await this.mock.proposalDetailsAt(0n)).to.deep.equal([ - this.proposal.id, - this.proposal.targets, - this.proposal.values, - this.proposal.data, - this.proposal.descriptionHash, - ]); - - expect(await this.mock.proposalDetails(this.proposal.id)).to.deep.equal([ - this.proposal.targets, - this.proposal.values, - this.proposal.data, - this.proposal.descriptionHash, - ]); - }); - }); - - it('queue and execute by id', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.connect(this.voter2).vote({ support: VoteType.For }); - await this.helper.connect(this.voter3).vote({ support: VoteType.Against }); - await this.helper.connect(this.voter4).vote({ support: VoteType.Abstain }); - await this.helper.waitForDeadline(); - - await expect(this.mock.queue(this.proposal.id)) - .to.emit(this.mock, 'ProposalQueued') - .withArgs(this.proposal.id, anyValue) - .to.emit(this.timelock, 'CallScheduled') - .withArgs(this.proposal.timelockid, ...Array(6).fill(anyValue)) - .to.emit(this.timelock, 'CallSalt') - .withArgs(this.proposal.timelockid, anyValue); - - await this.helper.waitForEta(); - - await expect(this.mock.execute(this.proposal.id)) - .to.emit(this.mock, 'ProposalExecuted') - .withArgs(this.proposal.id) - .to.emit(this.timelock, 'CallExecuted') - .withArgs(this.proposal.timelockid, ...Array(4).fill(anyValue)) - .to.emit(this.receiver, 'MockFunctionCalled'); - }); - - it('cancel by id', async function () { - await this.helper.connect(this.proposer).propose(); - await expect(this.mock.connect(this.proposer).cancel(this.proposal.id)) - .to.emit(this.mock, 'ProposalCanceled') - .withArgs(this.proposal.id); - }); - }); - } -}); diff --git a/lib/openzeppelin-contracts/test/governance/extensions/GovernorTimelockAccess.test.js b/lib/openzeppelin-contracts/test/governance/extensions/GovernorTimelockAccess.test.js deleted file mode 100644 index c3d3b32..0000000 --- a/lib/openzeppelin-contracts/test/governance/extensions/GovernorTimelockAccess.test.js +++ /dev/null @@ -1,864 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { anyValue } = require('@nomicfoundation/hardhat-chai-matchers/withArgs'); - -const { GovernorHelper } = require('../../helpers/governance'); -const { hashOperation } = require('../../helpers/access-manager'); -const { max } = require('../../helpers/math'); -const { selector } = require('../../helpers/methods'); -const { ProposalState, VoteType } = require('../../helpers/enums'); -const time = require('../../helpers/time'); - -function prepareOperation({ sender, target, value = 0n, data = '0x' }) { - return { - id: hashOperation(sender, target, data), - operation: { target, value, data }, - selector: data.slice(0, 10).padEnd(10, '0'), - }; -} - -const TOKENS = [ - { Token: '$ERC20Votes', mode: 'blocknumber' }, - { Token: '$ERC20VotesTimestampMock', mode: 'timestamp' }, -]; - -const name = 'OZ-Governor'; -const version = '1'; -const tokenName = 'MockToken'; -const tokenSymbol = 'MTKN'; -const tokenSupply = ethers.parseEther('100'); -const votingDelay = 4n; -const votingPeriod = 16n; -const value = ethers.parseEther('1'); - -describe('GovernorTimelockAccess', function () { - for (const { Token, mode } of TOKENS) { - const fixture = async () => { - const [admin, voter1, voter2, voter3, voter4, other] = await ethers.getSigners(); - - const manager = await ethers.deployContract('$AccessManager', [admin]); - const receiver = await ethers.deployContract('$AccessManagedTarget', [manager]); - - const token = await ethers.deployContract(Token, [tokenName, tokenSymbol, version]); - const mock = await ethers.deployContract('$GovernorTimelockAccessMock', [ - name, - votingDelay, - votingPeriod, - 0n, - manager, - 0n, - token, - 0n, - ]); - - await admin.sendTransaction({ to: mock, value }); - await token.$_mint(admin, tokenSupply); - - const helper = new GovernorHelper(mock, mode); - await helper.connect(admin).delegate({ token, to: voter1, value: ethers.parseEther('10') }); - await helper.connect(admin).delegate({ token, to: voter2, value: ethers.parseEther('7') }); - await helper.connect(admin).delegate({ token, to: voter3, value: ethers.parseEther('5') }); - await helper.connect(admin).delegate({ token, to: voter4, value: ethers.parseEther('2') }); - - return { admin, voter1, voter2, voter3, voter4, other, manager, receiver, token, mock, helper }; - }; - - describe(`using ${Token}`, function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - - // restricted proposal - this.restricted = prepareOperation({ - sender: this.mock.target, - target: this.receiver.target, - data: this.receiver.interface.encodeFunctionData('fnRestricted'), - }); - - this.unrestricted = prepareOperation({ - sender: this.mock.target, - target: this.receiver.target, - data: this.receiver.interface.encodeFunctionData('fnUnrestricted'), - }); - - this.fallback = prepareOperation({ - sender: this.mock.target, - target: this.receiver.target, - data: '0x1234', - }); - }); - - it('accepts ether transfers', async function () { - await this.admin.sendTransaction({ to: this.mock, value: 1n }); - }); - - it('post deployment check', async function () { - expect(await this.mock.name()).to.equal(name); - expect(await this.mock.token()).to.equal(this.token); - expect(await this.mock.votingDelay()).to.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.equal(votingPeriod); - expect(await this.mock.quorum(0n)).to.equal(0n); - - expect(await this.mock.accessManager()).to.equal(this.manager); - }); - - it('sets base delay (seconds)', async function () { - const baseDelay = time.duration.hours(10n); - - // Only through governance - await expect(this.mock.connect(this.voter1).setBaseDelaySeconds(baseDelay)) - .to.be.revertedWithCustomError(this.mock, 'GovernorOnlyExecutor') - .withArgs(this.voter1); - - this.proposal = await this.helper.setProposal( - [ - { - target: this.mock.target, - data: this.mock.interface.encodeFunctionData('setBaseDelaySeconds', [baseDelay]), - }, - ], - 'descr', - ); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - - await expect(this.helper.execute()).to.emit(this.mock, 'BaseDelaySet').withArgs(0n, baseDelay); - - expect(await this.mock.baseDelaySeconds()).to.equal(baseDelay); - }); - - it('sets access manager ignored', async function () { - const selectors = ['0x12345678', '0x87654321', '0xabcdef01']; - - // Only through governance - await expect(this.mock.connect(this.voter1).setAccessManagerIgnored(this.other, selectors, true)) - .to.be.revertedWithCustomError(this.mock, 'GovernorOnlyExecutor') - .withArgs(this.voter1); - - // Ignore - await this.helper.setProposal( - [ - { - target: this.mock.target, - data: this.mock.interface.encodeFunctionData('setAccessManagerIgnored', [ - this.other.address, - selectors, - true, - ]), - }, - ], - 'descr', - ); - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - - const ignoreReceipt = this.helper.execute(); - for (const selector of selectors) { - await expect(ignoreReceipt) - .to.emit(this.mock, 'AccessManagerIgnoredSet') - .withArgs(this.other, selector, true); - expect(await this.mock.isAccessManagerIgnored(this.other, selector)).to.be.true; - } - - // Unignore - await this.helper.setProposal( - [ - { - target: this.mock.target, - data: this.mock.interface.encodeFunctionData('setAccessManagerIgnored', [ - this.other.address, - selectors, - false, - ]), - }, - ], - 'descr', - ); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - - const unignoreReceipt = this.helper.execute(); - for (const selector of selectors) { - await expect(unignoreReceipt) - .to.emit(this.mock, 'AccessManagerIgnoredSet') - .withArgs(this.other, selector, false); - expect(await this.mock.isAccessManagerIgnored(this.other, selector)).to.be.false; - } - }); - - it('sets access manager ignored when target is the governor', async function () { - const selectors = ['0x12345678', '0x87654321', '0xabcdef01']; - - await this.helper.setProposal( - [ - { - target: this.mock.target, - data: this.mock.interface.encodeFunctionData('setAccessManagerIgnored', [ - this.mock.target, - selectors, - true, - ]), - }, - ], - 'descr', - ); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - - const tx = this.helper.execute(); - for (const selector of selectors) { - await expect(tx).to.emit(this.mock, 'AccessManagerIgnoredSet').withArgs(this.mock, selector, true); - expect(await this.mock.isAccessManagerIgnored(this.mock, selector)).to.be.true; - } - }); - - it('does not need to queue proposals with no delay', async function () { - const roleId = 1n; - const executionDelay = 0n; - const baseDelay = 0n; - - // Set execution delay - await this.manager.connect(this.admin).setTargetFunctionRole(this.receiver, [this.restricted.selector], roleId); - await this.manager.connect(this.admin).grantRole(roleId, this.mock, executionDelay); - - // Set base delay - await this.mock.$_setBaseDelaySeconds(baseDelay); - - await this.helper.setProposal([this.restricted.operation], 'descr'); - await this.helper.propose(); - expect(await this.mock.proposalNeedsQueuing(this.helper.currentProposal.id)).to.be.false; - }); - - it('needs to queue proposals with any delay', async function () { - const roleId = 1n; - const delays = [ - [time.duration.hours(1n), time.duration.hours(2n)], - [time.duration.hours(2n), time.duration.hours(1n)], - ]; - - for (const [executionDelay, baseDelay] of delays) { - // Set execution delay - await this.manager - .connect(this.admin) - .setTargetFunctionRole(this.receiver, [this.restricted.selector], roleId); - await this.manager.connect(this.admin).grantRole(roleId, this.mock, executionDelay); - - // Set base delay - await this.mock.$_setBaseDelaySeconds(baseDelay); - - await this.helper.setProposal( - [this.restricted.operation], - `executionDelay=${executionDelay.toString()}}baseDelay=${baseDelay.toString()}}`, - ); - await this.helper.propose(); - expect(await this.mock.proposalNeedsQueuing(this.helper.currentProposal.id)).to.be.true; - } - }); - - describe('execution plan', function () { - it('returns plan for delayed operations', async function () { - const roleId = 1n; - const delays = [ - [time.duration.hours(1n), time.duration.hours(2n)], - [time.duration.hours(2n), time.duration.hours(1n)], - ]; - - for (const [executionDelay, baseDelay] of delays) { - // Set execution delay - await this.manager - .connect(this.admin) - .setTargetFunctionRole(this.receiver, [this.restricted.selector], roleId); - await this.manager.connect(this.admin).grantRole(roleId, this.mock, executionDelay); - - // Set base delay - await this.mock.$_setBaseDelaySeconds(baseDelay); - - this.proposal = await this.helper.setProposal( - [this.restricted.operation], - `executionDelay=${executionDelay.toString()}}baseDelay=${baseDelay.toString()}}`, - ); - await this.helper.propose(); - - expect(await this.mock.proposalExecutionPlan(this.proposal.id)).to.deep.equal([ - max(baseDelay, executionDelay), - [true], - [true], - ]); - } - }); - - it('returns plan for not delayed operations', async function () { - const roleId = 1n; - const executionDelay = 0n; - const baseDelay = 0n; - - // Set execution delay - await this.manager - .connect(this.admin) - .setTargetFunctionRole(this.receiver, [this.restricted.selector], roleId); - await this.manager.connect(this.admin).grantRole(roleId, this.mock, executionDelay); - - // Set base delay - await this.mock.$_setBaseDelaySeconds(baseDelay); - - this.proposal = await this.helper.setProposal([this.restricted.operation], `descr`); - await this.helper.propose(); - - expect(await this.mock.proposalExecutionPlan(this.proposal.id)).to.deep.equal([0n, [true], [false]]); - }); - - it('returns plan for an operation ignoring the manager', async function () { - await this.mock.$_setAccessManagerIgnored(this.receiver, this.restricted.selector, true); - - const roleId = 1n; - const delays = [ - [time.duration.hours(1n), time.duration.hours(2n)], - [time.duration.hours(2n), time.duration.hours(1n)], - ]; - - for (const [executionDelay, baseDelay] of delays) { - // Set execution delay - await this.manager - .connect(this.admin) - .setTargetFunctionRole(this.receiver, [this.restricted.selector], roleId); - await this.manager.connect(this.admin).grantRole(roleId, this.mock, executionDelay); - - // Set base delay - await this.mock.$_setBaseDelaySeconds(baseDelay); - - this.proposal = await this.helper.setProposal( - [this.restricted.operation], - `executionDelay=${executionDelay.toString()}}baseDelay=${baseDelay.toString()}}`, - ); - await this.helper.propose(); - - expect(await this.mock.proposalExecutionPlan(this.proposal.id)).to.deep.equal([ - baseDelay, - [false], - [false], - ]); - } - }); - }); - - describe('base delay only', function () { - for (const [delay, queue] of [ - [0, true], - [0, false], - [1000, true], - ]) { - it(`delay ${delay}, ${queue ? 'with' : 'without'} queuing`, async function () { - await this.mock.$_setBaseDelaySeconds(delay); - - this.proposal = await this.helper.setProposal([this.unrestricted.operation], 'descr'); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - if (await this.mock.proposalNeedsQueuing(this.proposal.id)) { - expect(await this.helper.queue()) - .to.emit(this.mock, 'ProposalQueued') - .withArgs(this.proposal.id, anyValue); - } - if (delay > 0) { - await this.helper.waitForEta(); - } - await expect(this.helper.execute()) - .to.emit(this.mock, 'ProposalExecuted') - .withArgs(this.proposal.id) - .to.emit(this.receiver, 'CalledUnrestricted'); - }); - } - }); - - it('reverts when an operation is executed before eta', async function () { - const delay = time.duration.hours(2n); - await this.mock.$_setBaseDelaySeconds(delay); - - this.proposal = await this.helper.setProposal([this.unrestricted.operation], 'descr'); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await expect(this.helper.execute()) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnmetDelay') - .withArgs(this.proposal.id, await this.mock.proposalEta(this.proposal.id)); - }); - - it('reverts with a proposal including multiple operations but one of those was cancelled in the manager', async function () { - const delay = time.duration.hours(2n); - const roleId = 1n; - - await this.manager.connect(this.admin).setTargetFunctionRole(this.receiver, [this.restricted.selector], roleId); - await this.manager.connect(this.admin).grantRole(roleId, this.mock, delay); - - // Set proposals - const original = new GovernorHelper(this.mock, mode); - await original.setProposal([this.restricted.operation, this.unrestricted.operation], 'descr'); - - // Go through all the governance process - await original.propose(); - await original.waitForSnapshot(); - await original.connect(this.voter1).vote({ support: VoteType.For }); - await original.waitForDeadline(); - await original.queue(); - await original.waitForEta(); - - // Suddenly cancel one of the proposed operations in the manager - await this.manager - .connect(this.admin) - .cancel(this.mock, this.restricted.operation.target, this.restricted.operation.data); - - // Reschedule the same operation in a different proposal to avoid "AccessManagerNotScheduled" error - const rescheduled = new GovernorHelper(this.mock, mode); - await rescheduled.setProposal([this.restricted.operation], 'descr'); - await rescheduled.propose(); - await rescheduled.waitForSnapshot(); - await rescheduled.connect(this.voter1).vote({ support: VoteType.For }); - await rescheduled.waitForDeadline(); - await rescheduled.queue(); // This will schedule it again in the manager - await rescheduled.waitForEta(); - - // Attempt to execute - await expect(original.execute()) - .to.be.revertedWithCustomError(this.mock, 'GovernorMismatchedNonce') - .withArgs(original.currentProposal.id, 1, 2); - }); - - it('single operation with access manager delay', async function () { - const delay = 1000n; - const roleId = 1n; - - await this.manager.connect(this.admin).setTargetFunctionRole(this.receiver, [this.restricted.selector], roleId); - await this.manager.connect(this.admin).grantRole(roleId, this.mock, delay); - - this.proposal = await this.helper.setProposal([this.restricted.operation], 'descr'); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - const txQueue = await this.helper.queue(); - await this.helper.waitForEta(); - const txExecute = await this.helper.execute(); - - await expect(txQueue) - .to.emit(this.mock, 'ProposalQueued') - .withArgs(this.proposal.id, anyValue) - .to.emit(this.manager, 'OperationScheduled') - .withArgs( - this.restricted.id, - 1n, - (await time.clockFromReceipt.timestamp(txQueue)) + delay, - this.mock.target, - this.restricted.operation.target, - this.restricted.operation.data, - ); - - await expect(txExecute) - .to.emit(this.mock, 'ProposalExecuted') - .withArgs(this.proposal.id) - .to.emit(this.manager, 'OperationExecuted') - .withArgs(this.restricted.id, 1n) - .to.emit(this.receiver, 'CalledRestricted'); - }); - - it('bundle of varied operations', async function () { - const managerDelay = 1000n; - const roleId = 1n; - const baseDelay = managerDelay * 2n; - - await this.mock.$_setBaseDelaySeconds(baseDelay); - - await this.manager.connect(this.admin).setTargetFunctionRole(this.receiver, [this.restricted.selector], roleId); - await this.manager.connect(this.admin).grantRole(roleId, this.mock, managerDelay); - - this.proposal = await this.helper.setProposal( - [this.restricted.operation, this.unrestricted.operation, this.fallback.operation], - 'descr', - ); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - const txQueue = await this.helper.queue(); - await this.helper.waitForEta(); - const txExecute = await this.helper.execute(); - - await expect(txQueue) - .to.emit(this.mock, 'ProposalQueued') - .withArgs(this.proposal.id, anyValue) - .to.emit(this.manager, 'OperationScheduled') - .withArgs( - this.restricted.id, - 1n, - (await time.clockFromReceipt.timestamp(txQueue)) + baseDelay, - this.mock.target, - this.restricted.operation.target, - this.restricted.operation.data, - ); - - await expect(txExecute) - .to.emit(this.mock, 'ProposalExecuted') - .withArgs(this.proposal.id) - .to.emit(this.manager, 'OperationExecuted') - .withArgs(this.restricted.id, 1n) - .to.emit(this.receiver, 'CalledRestricted') - .to.emit(this.receiver, 'CalledUnrestricted') - .to.emit(this.receiver, 'CalledFallback'); - }); - - describe('cancel', function () { - const delay = 1000n; - const roleId = 1n; - - beforeEach(async function () { - await this.manager - .connect(this.admin) - .setTargetFunctionRole(this.receiver, [this.restricted.selector], roleId); - await this.manager.connect(this.admin).grantRole(roleId, this.mock, delay); - }); - - it('cancels restricted with delay after queue (internal)', async function () { - this.proposal = await this.helper.setProposal([this.restricted.operation], 'descr'); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - - await expect(this.helper.cancel('internal')) - .to.emit(this.mock, 'ProposalCanceled') - .withArgs(this.proposal.id) - .to.emit(this.manager, 'OperationCanceled') - .withArgs(this.restricted.id, 1n); - - await this.helper.waitForEta(); - - await expect(this.helper.execute()) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Canceled, - GovernorHelper.proposalStatesToBitMap([ProposalState.Succeeded, ProposalState.Queued]), - ); - }); - - it('cancels restricted with queueing if the same operation is part of a more recent proposal (internal)', async function () { - // Set proposals - const original = new GovernorHelper(this.mock, mode); - await original.setProposal([this.restricted.operation], 'descr'); - - // Go through all the governance process - await original.propose(); - await original.waitForSnapshot(); - await original.connect(this.voter1).vote({ support: VoteType.For }); - await original.waitForDeadline(); - await original.queue(); - - // Cancel the operation in the manager - await this.manager - .connect(this.admin) - .cancel(this.mock, this.restricted.operation.target, this.restricted.operation.data); - - // Another proposal is added with the same operation - const rescheduled = new GovernorHelper(this.mock, mode); - await rescheduled.setProposal([this.restricted.operation], 'another descr'); - - // Queue the new proposal - await rescheduled.propose(); - await rescheduled.waitForSnapshot(); - await rescheduled.connect(this.voter1).vote({ support: VoteType.For }); - await rescheduled.waitForDeadline(); - await rescheduled.queue(); // This will schedule it again in the manager - - // Cancel - const eta = await this.mock.proposalEta(rescheduled.currentProposal.id); - - await expect(original.cancel('internal')) - .to.emit(this.mock, 'ProposalCanceled') - .withArgs(original.currentProposal.id); - - await time.clock.timestamp().then(clock => time.increaseTo.timestamp(max(clock + 1n, eta))); - - await expect(original.execute()) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - original.currentProposal.id, - ProposalState.Canceled, - GovernorHelper.proposalStatesToBitMap([ProposalState.Succeeded, ProposalState.Queued]), - ); - }); - - it('cancels unrestricted with queueing (internal)', async function () { - this.proposal = await this.helper.setProposal([this.unrestricted.operation], 'descr'); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - - const eta = await this.mock.proposalEta(this.proposal.id); - - await expect(this.helper.cancel('internal')) - .to.emit(this.mock, 'ProposalCanceled') - .withArgs(this.proposal.id); - - await time.clock.timestamp().then(clock => time.increaseTo.timestamp(max(clock + 1n, eta))); - - await expect(this.helper.execute()) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Canceled, - GovernorHelper.proposalStatesToBitMap([ProposalState.Succeeded, ProposalState.Queued]), - ); - }); - - it('cancels unrestricted without queueing (internal)', async function () { - this.proposal = await this.helper.setProposal([this.unrestricted.operation], 'descr'); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - - await expect(this.helper.cancel('internal')) - .to.emit(this.mock, 'ProposalCanceled') - .withArgs(this.proposal.id); - - await expect(this.helper.execute()) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Canceled, - GovernorHelper.proposalStatesToBitMap([ProposalState.Succeeded, ProposalState.Queued]), - ); - }); - - it('cancels calls already canceled by guardian', async function () { - const operationA = { target: this.receiver.target, data: this.restricted.selector + '00' }; - const operationB = { target: this.receiver.target, data: this.restricted.selector + '01' }; - const operationC = { target: this.receiver.target, data: this.restricted.selector + '02' }; - const operationAId = hashOperation(this.mock.target, operationA.target, operationA.data); - const operationBId = hashOperation(this.mock.target, operationB.target, operationB.data); - - const proposal1 = new GovernorHelper(this.mock, mode); - const proposal2 = new GovernorHelper(this.mock, mode); - proposal1.setProposal([operationA, operationB], 'proposal A+B'); - proposal2.setProposal([operationA, operationC], 'proposal A+C'); - - for (const p of [proposal1, proposal2]) { - await p.propose(); - await p.waitForSnapshot(); - await p.connect(this.voter1).vote({ support: VoteType.For }); - await p.waitForDeadline(); - } - - // Can queue the first proposal - await proposal1.queue(); - - // Cannot queue the second proposal: operation A already scheduled with delay - await expect(proposal2.queue()) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerAlreadyScheduled') - .withArgs(operationAId); - - // Admin cancels operation B on the manager - await this.manager.connect(this.admin).cancel(this.mock, operationB.target, operationB.data); - - // Still cannot queue the second proposal: operation A already scheduled with delay - await expect(proposal2.queue()) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerAlreadyScheduled') - .withArgs(operationAId); - - await proposal1.waitForEta(); - - // Cannot execute first proposal: operation B has been canceled - await expect(proposal1.execute()) - .to.be.revertedWithCustomError(this.manager, 'AccessManagerNotScheduled') - .withArgs(operationBId); - - // Cancel the first proposal to release operation A - await proposal1.cancel('internal'); - - // can finally queue the second proposal - await proposal2.queue(); - - await proposal2.waitForEta(); - - // Can execute second proposal - await proposal2.execute(); - }); - }); - - describe('ignore AccessManager', function () { - it('defaults', async function () { - expect(await this.mock.isAccessManagerIgnored(this.receiver, this.restricted.selector)).to.be.false; - expect(await this.mock.isAccessManagerIgnored(this.mock, '0x12341234')).to.be.true; - }); - - it('internal setter', async function () { - await expect(this.mock.$_setAccessManagerIgnored(this.receiver, this.restricted.selector, true)) - .to.emit(this.mock, 'AccessManagerIgnoredSet') - .withArgs(this.receiver, this.restricted.selector, true); - - expect(await this.mock.isAccessManagerIgnored(this.receiver, this.restricted.selector)).to.be.true; - - await expect(this.mock.$_setAccessManagerIgnored(this.mock, '0x12341234', false)) - .to.emit(this.mock, 'AccessManagerIgnoredSet') - .withArgs(this.mock, '0x12341234', false); - - expect(await this.mock.isAccessManagerIgnored(this.mock, '0x12341234')).to.be.false; - }); - - it('external setter', async function () { - const setAccessManagerIgnored = (...args) => - this.mock.interface.encodeFunctionData('setAccessManagerIgnored', args); - - await this.helper.setProposal( - [ - { - target: this.mock.target, - data: setAccessManagerIgnored( - this.receiver.target, - [this.restricted.selector, this.unrestricted.selector], - true, - ), - }, - { - target: this.mock.target, - data: setAccessManagerIgnored(this.mock.target, ['0x12341234', '0x67896789'], false), - }, - ], - 'descr', - ); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - - await expect(this.helper.execute()).to.emit(this.mock, 'AccessManagerIgnoredSet'); - - expect(await this.mock.isAccessManagerIgnored(this.receiver, this.restricted.selector)).to.be.true; - expect(await this.mock.isAccessManagerIgnored(this.receiver, this.unrestricted.selector)).to.be.true; - expect(await this.mock.isAccessManagerIgnored(this.mock, '0x12341234')).to.be.false; - expect(await this.mock.isAccessManagerIgnored(this.mock, '0x67896789')).to.be.false; - }); - - it('locked function', async function () { - const setAccessManagerIgnored = selector('setAccessManagerIgnored(address,bytes4[],bool)'); - - await expect( - this.mock.$_setAccessManagerIgnored(this.mock, setAccessManagerIgnored, true), - ).to.be.revertedWithCustomError(this.mock, 'GovernorLockedIgnore'); - - await this.mock.$_setAccessManagerIgnored(this.receiver, setAccessManagerIgnored, true); - }); - - it('ignores access manager', async function () { - const amount = 100n; - const target = this.token.target; - const data = this.token.interface.encodeFunctionData('transfer', [this.voter4.address, amount]); - const selector = data.slice(0, 10); - await this.token.$_mint(this.mock, amount); - - const roleId = 1n; - await this.manager.connect(this.admin).setTargetFunctionRole(target, [selector], roleId); - await this.manager.connect(this.admin).grantRole(roleId, this.mock, 0); - - await this.helper.setProposal([{ target, data }], 'descr #1'); - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - - await expect(this.helper.execute()) - .to.be.revertedWithCustomError(this.token, 'ERC20InsufficientBalance') - .withArgs(this.manager, 0n, amount); - - await this.mock.$_setAccessManagerIgnored(target, selector, true); - - await this.helper.setProposal([{ target, data }], 'descr #2'); - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - - await expect(this.helper.execute()).to.emit(this.token, 'Transfer').withArgs(this.mock, this.voter4, amount); - }); - }); - - describe('operating on an Ownable contract', function () { - const method = selector('$_checkOwner()'); - - beforeEach(async function () { - this.ownable = await ethers.deployContract('$Ownable', [this.manager]); - this.operation = { - target: this.ownable.target, - data: this.ownable.interface.encodeFunctionData('$_checkOwner'), - }; - }); - - it('succeeds with delay', async function () { - const roleId = 1n; - const executionDelay = time.duration.hours(2n); - const baseDelay = time.duration.hours(1n); - - // Set execution delay - await this.manager.connect(this.admin).setTargetFunctionRole(this.ownable, [method], roleId); - await this.manager.connect(this.admin).grantRole(roleId, this.mock, executionDelay); - - // Set base delay - await this.mock.$_setBaseDelaySeconds(baseDelay); - - await this.helper.setProposal([this.operation], `descr`); - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - await this.helper.execute(); // Don't revert - }); - - it('succeeds without delay', async function () { - const roleId = 1n; - const executionDelay = 0n; - const baseDelay = 0n; - - // Set execution delay - await this.manager.connect(this.admin).setTargetFunctionRole(this.ownable, [method], roleId); - await this.manager.connect(this.admin).grantRole(roleId, this.mock, executionDelay); - - // Set base delay - await this.mock.$_setBaseDelaySeconds(baseDelay); - - await this.helper.setProposal([this.operation], `descr`); - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.execute(); // Don't revert - }); - }); - }); - } -}); diff --git a/lib/openzeppelin-contracts/test/governance/extensions/GovernorTimelockCompound.test.js b/lib/openzeppelin-contracts/test/governance/extensions/GovernorTimelockCompound.test.js deleted file mode 100644 index 545bf35..0000000 --- a/lib/openzeppelin-contracts/test/governance/extensions/GovernorTimelockCompound.test.js +++ /dev/null @@ -1,448 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { anyValue } = require('@nomicfoundation/hardhat-chai-matchers/withArgs'); - -const { GovernorHelper } = require('../../helpers/governance'); -const { ProposalState, VoteType } = require('../../helpers/enums'); -const time = require('../../helpers/time'); - -const TOKENS = [ - { Token: '$ERC20Votes', mode: 'blocknumber' }, - { Token: '$ERC20VotesTimestampMock', mode: 'timestamp' }, -]; - -const name = 'OZ-Governor'; -const version = '1'; -const tokenName = 'MockToken'; -const tokenSymbol = 'MTKN'; -const tokenSupply = ethers.parseEther('100'); -const votingDelay = 4n; -const votingPeriod = 16n; -const value = ethers.parseEther('1'); -const defaultDelay = time.duration.days(2n); - -describe('GovernorTimelockCompound', function () { - for (const { Token, mode } of TOKENS) { - const fixture = async () => { - const [deployer, owner, voter1, voter2, voter3, voter4, other] = await ethers.getSigners(); - const receiver = await ethers.deployContract('CallReceiverMock'); - - const token = await ethers.deployContract(Token, [tokenName, tokenSymbol, version]); - const predictGovernor = await deployer - .getNonce() - .then(nonce => ethers.getCreateAddress({ from: deployer.address, nonce: nonce + 1 })); - const timelock = await ethers.deployContract('CompTimelock', [predictGovernor, defaultDelay]); - const mock = await ethers.deployContract('$GovernorTimelockCompoundMock', [ - name, - votingDelay, - votingPeriod, - 0n, - timelock, - token, - 0n, - ]); - - await owner.sendTransaction({ to: timelock, value }); - await token.$_mint(owner, tokenSupply); - - const helper = new GovernorHelper(mock, mode); - await helper.connect(owner).delegate({ token, to: voter1, value: ethers.parseEther('10') }); - await helper.connect(owner).delegate({ token, to: voter2, value: ethers.parseEther('7') }); - await helper.connect(owner).delegate({ token, to: voter3, value: ethers.parseEther('5') }); - await helper.connect(owner).delegate({ token, to: voter4, value: ethers.parseEther('2') }); - - return { deployer, owner, voter1, voter2, voter3, voter4, other, receiver, token, mock, timelock, helper }; - }; - - describe(`using ${Token}`, function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - - // default proposal - this.proposal = this.helper.setProposal( - [ - { - target: this.receiver.target, - value, - data: this.receiver.interface.encodeFunctionData('mockFunction'), - }, - ], - '', - ); - }); - - it("doesn't accept ether transfers", async function () { - await expect(this.owner.sendTransaction({ to: this.mock, value: 1n })).to.be.revertedWithCustomError( - this.mock, - 'GovernorDisabledDeposit', - ); - }); - - it('post deployment check', async function () { - expect(await this.mock.name()).to.equal(name); - expect(await this.mock.token()).to.equal(this.token); - expect(await this.mock.votingDelay()).to.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.equal(votingPeriod); - expect(await this.mock.quorum(0n)).to.equal(0n); - - expect(await this.mock.timelock()).to.equal(this.timelock); - expect(await this.timelock.admin()).to.equal(this.mock); - }); - - it('nominal', async function () { - expect(await this.mock.proposalEta(this.proposal.id)).to.equal(0n); - expect(await this.mock.proposalNeedsQueuing(this.proposal.id)).to.be.true; - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.connect(this.voter2).vote({ support: VoteType.For }); - await this.helper.connect(this.voter3).vote({ support: VoteType.Against }); - await this.helper.connect(this.voter4).vote({ support: VoteType.Abstain }); - await this.helper.waitForDeadline(); - const txQueue = await this.helper.queue(); - - const eta = (await time.clockFromReceipt.timestamp(txQueue)) + defaultDelay; - expect(await this.mock.proposalEta(this.proposal.id)).to.equal(eta); - expect(await this.mock.proposalNeedsQueuing(this.proposal.id)).to.be.true; - - await this.helper.waitForEta(); - const txExecute = await this.helper.execute(); - - await expect(txQueue) - .to.emit(this.mock, 'ProposalQueued') - .withArgs(this.proposal.id, eta) - .to.emit(this.timelock, 'QueueTransaction') - .withArgs(...Array(5).fill(anyValue), eta); - - await expect(txExecute) - .to.emit(this.mock, 'ProposalExecuted') - .withArgs(this.proposal.id) - .to.emit(this.timelock, 'ExecuteTransaction') - .withArgs(...Array(5).fill(anyValue), eta) - .to.emit(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.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await expect(this.helper.queue()) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Queued, - GovernorHelper.proposalStatesToBitMap([ProposalState.Succeeded]), - ); - }); - - it('if proposal contains duplicate calls', async function () { - const action = { - target: this.token.target, - data: this.token.interface.encodeFunctionData('approve', [this.receiver.target, ethers.MaxUint256]), - }; - const { id } = this.helper.setProposal([action, action], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await expect(this.helper.queue()) - .to.be.revertedWithCustomError(this.mock, 'GovernorAlreadyQueuedProposal') - .withArgs(id); - await expect(this.helper.execute()) - .to.be.revertedWithCustomError(this.mock, 'GovernorNotQueuedProposal') - .withArgs(id); - }); - }); - - describe('on execute', function () { - it('if not queued', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(1n); - - expect(await this.mock.state(this.proposal.id)).to.equal(ProposalState.Succeeded); - - await expect(this.helper.execute()) - .to.be.revertedWithCustomError(this.mock, 'GovernorNotQueuedProposal') - .withArgs(this.proposal.id); - }); - - it('if too early', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - - expect(await this.mock.state(this.proposal.id)).to.equal(ProposalState.Queued); - - await expect(this.helper.execute()).to.be.rejectedWith( - "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.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(time.duration.days(30)); - - expect(await this.mock.state(this.proposal.id)).to.equal(ProposalState.Expired); - - await expect(this.helper.execute()) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Expired, - GovernorHelper.proposalStatesToBitMap([ProposalState.Succeeded, ProposalState.Queued]), - ); - }); - - it('if already executed', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - await this.helper.execute(); - - await expect(this.helper.execute()) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Executed, - GovernorHelper.proposalStatesToBitMap([ProposalState.Succeeded, ProposalState.Queued]), - ); - }); - }); - - describe('on safe receive', function () { - describe('ERC721', function () { - const tokenId = 1n; - - beforeEach(async function () { - this.token = await ethers.deployContract('$ERC721', ['Non Fungible Token', 'NFT']); - await this.token.$_mint(this.owner, tokenId); - }); - - it("can't receive an ERC721 safeTransfer", async function () { - await expect( - this.token.connect(this.owner).safeTransferFrom(this.owner, this.mock, tokenId), - ).to.be.revertedWithCustomError(this.mock, 'GovernorDisabledDeposit'); - }); - }); - - describe('ERC1155', function () { - const tokenIds = { - 1: 1000n, - 2: 2000n, - 3: 3000n, - }; - - beforeEach(async function () { - this.token = await ethers.deployContract('$ERC1155', ['https://token-cdn-domain/{id}.json']); - await this.token.$_mintBatch(this.owner, Object.keys(tokenIds), Object.values(tokenIds), '0x'); - }); - - it("can't receive ERC1155 safeTransfer", async function () { - await expect( - this.token.connect(this.owner).safeTransferFrom( - this.owner, - this.mock, - ...Object.entries(tokenIds)[0], // id + amount - '0x', - ), - ).to.be.revertedWithCustomError(this.mock, 'GovernorDisabledDeposit'); - }); - - it("can't receive ERC1155 safeBatchTransfer", async function () { - await expect( - this.token - .connect(this.owner) - .safeBatchTransferFrom(this.owner, this.mock, Object.keys(tokenIds), Object.values(tokenIds), '0x'), - ).to.be.revertedWithCustomError(this.mock, 'GovernorDisabledDeposit'); - }); - }); - }); - }); - - describe('cancel', function () { - it('cancel before queue prevents scheduling', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - - await expect(this.helper.cancel('internal')) - .to.emit(this.mock, 'ProposalCanceled') - .withArgs(this.proposal.id); - - expect(await this.mock.state(this.proposal.id)).to.equal(ProposalState.Canceled); - - await expect(this.helper.queue()) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Canceled, - GovernorHelper.proposalStatesToBitMap([ProposalState.Succeeded]), - ); - }); - - it('cancel after queue prevents executing', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - - await expect(this.helper.cancel('internal')) - .to.emit(this.mock, 'ProposalCanceled') - .withArgs(this.proposal.id); - - expect(await this.mock.state(this.proposal.id)).to.equal(ProposalState.Canceled); - - await expect(this.helper.execute()) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Canceled, - GovernorHelper.proposalStatesToBitMap([ProposalState.Succeeded, ProposalState.Queued]), - ); - }); - }); - - describe('onlyGovernance', function () { - describe('relay', function () { - beforeEach(async function () { - await this.token.$_mint(this.mock, 1); - }); - - it('is protected', async function () { - await expect( - this.mock - .connect(this.owner) - .relay(this.token, 0, this.token.interface.encodeFunctionData('transfer', [this.other.address, 1n])), - ) - .to.be.revertedWithCustomError(this.mock, 'GovernorOnlyExecutor') - .withArgs(this.owner); - }); - - it('can be executed through governance', async function () { - this.helper.setProposal( - [ - { - target: this.mock.target, - data: this.mock.interface.encodeFunctionData('relay', [ - this.token.target, - 0n, - this.token.interface.encodeFunctionData('transfer', [this.other.address, 1n]), - ]), - }, - ], - '', - ); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - - const txExecute = this.helper.execute(); - - await expect(txExecute).to.changeTokenBalances(this.token, [this.mock, this.other], [-1n, 1n]); - - await expect(txExecute).to.emit(this.token, 'Transfer').withArgs(this.mock, this.other, 1n); - }); - }); - - describe('updateTimelock', function () { - beforeEach(async function () { - this.newTimelock = await ethers.deployContract('CompTimelock', [this.mock, time.duration.days(7n)]); - }); - - it('is protected', async function () { - await expect(this.mock.connect(this.owner).updateTimelock(this.newTimelock)) - .to.be.revertedWithCustomError(this.mock, 'GovernorOnlyExecutor') - .withArgs(this.owner); - }); - - it('can be executed through governance to', async function () { - this.helper.setProposal( - [ - { - target: this.timelock.target, - data: this.timelock.interface.encodeFunctionData('setPendingAdmin', [this.owner.address]), - }, - { - target: this.mock.target, - data: this.mock.interface.encodeFunctionData('updateTimelock', [this.newTimelock.target]), - }, - ], - '', - ); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - - await expect(this.helper.execute()) - .to.emit(this.mock, 'TimelockChange') - .withArgs(this.timelock, this.newTimelock); - - expect(await this.mock.timelock()).to.equal(this.newTimelock); - }); - }); - - it('can transfer timelock to new governor', async function () { - const newGovernor = await ethers.deployContract('$GovernorTimelockCompoundMock', [ - name, - 8n, - 32n, - 0n, - this.timelock, - this.token, - 0n, - ]); - - this.helper.setProposal( - [ - { - target: this.timelock.target, - data: this.timelock.interface.encodeFunctionData('setPendingAdmin', [newGovernor.target]), - }, - ], - '', - ); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - - await expect(this.helper.execute()).to.emit(this.timelock, 'NewPendingAdmin').withArgs(newGovernor); - - await newGovernor.__acceptAdmin(); - expect(await this.timelock.admin()).to.equal(newGovernor); - }); - }); - }); - } -}); diff --git a/lib/openzeppelin-contracts/test/governance/extensions/GovernorTimelockControl.test.js b/lib/openzeppelin-contracts/test/governance/extensions/GovernorTimelockControl.test.js deleted file mode 100644 index c1156a5..0000000 --- a/lib/openzeppelin-contracts/test/governance/extensions/GovernorTimelockControl.test.js +++ /dev/null @@ -1,504 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { anyValue } = require('@nomicfoundation/hardhat-chai-matchers/withArgs'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); - -const { GovernorHelper, timelockSalt } = require('../../helpers/governance'); -const { OperationState, ProposalState, VoteType } = require('../../helpers/enums'); -const time = require('../../helpers/time'); - -const TOKENS = [ - { Token: '$ERC20Votes', mode: 'blocknumber' }, - { Token: '$ERC20VotesTimestampMock', mode: 'timestamp' }, -]; - -const DEFAULT_ADMIN_ROLE = ethers.ZeroHash; -const PROPOSER_ROLE = ethers.id('PROPOSER_ROLE'); -const EXECUTOR_ROLE = ethers.id('EXECUTOR_ROLE'); -const CANCELLER_ROLE = ethers.id('CANCELLER_ROLE'); - -const name = 'OZ-Governor'; -const version = '1'; -const tokenName = 'MockToken'; -const tokenSymbol = 'MTKN'; -const tokenSupply = ethers.parseEther('100'); -const votingDelay = 4n; -const votingPeriod = 16n; -const value = ethers.parseEther('1'); -const delay = time.duration.hours(1n); - -describe('GovernorTimelockControl', function () { - for (const { Token, mode } of TOKENS) { - const fixture = async () => { - const [deployer, owner, voter1, voter2, voter3, voter4, other] = await ethers.getSigners(); - const receiver = await ethers.deployContract('CallReceiverMock'); - - const token = await ethers.deployContract(Token, [tokenName, tokenSymbol, version]); - const timelock = await ethers.deployContract('TimelockController', [delay, [], [], deployer]); - const mock = await ethers.deployContract('$GovernorTimelockControlMock', [ - name, - votingDelay, - votingPeriod, - 0n, - timelock, - token, - 0n, - ]); - - await owner.sendTransaction({ to: timelock, value }); - await token.$_mint(owner, tokenSupply); - await timelock.grantRole(PROPOSER_ROLE, mock); - await timelock.grantRole(PROPOSER_ROLE, owner); - await timelock.grantRole(CANCELLER_ROLE, mock); - await timelock.grantRole(CANCELLER_ROLE, owner); - await timelock.grantRole(EXECUTOR_ROLE, ethers.ZeroAddress); - await timelock.revokeRole(DEFAULT_ADMIN_ROLE, deployer); - - const helper = new GovernorHelper(mock, mode); - await helper.connect(owner).delegate({ token, to: voter1, value: ethers.parseEther('10') }); - await helper.connect(owner).delegate({ token, to: voter2, value: ethers.parseEther('7') }); - await helper.connect(owner).delegate({ token, to: voter3, value: ethers.parseEther('5') }); - await helper.connect(owner).delegate({ token, to: voter4, value: ethers.parseEther('2') }); - - return { deployer, owner, voter1, voter2, voter3, voter4, other, receiver, token, mock, timelock, helper }; - }; - - describe(`using ${Token}`, function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - - // default proposal - this.proposal = this.helper.setProposal( - [ - { - target: this.receiver.target, - value, - data: this.receiver.interface.encodeFunctionData('mockFunction'), - }, - ], - '', - ); - - this.proposal.timelockid = await this.timelock.hashOperationBatch( - ...this.proposal.shortProposal.slice(0, 3), - ethers.ZeroHash, - timelockSalt(this.mock.target, this.proposal.shortProposal[3]), - ); - }); - - it("doesn't accept ether transfers", async function () { - await expect(this.owner.sendTransaction({ to: this.mock, value: 1n })).to.be.revertedWithCustomError( - this.mock, - 'GovernorDisabledDeposit', - ); - }); - - it('post deployment check', async function () { - expect(await this.mock.name()).to.equal(name); - expect(await this.mock.token()).to.equal(this.token); - expect(await this.mock.votingDelay()).to.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.equal(votingPeriod); - expect(await this.mock.quorum(0n)).to.equal(0n); - - expect(await this.mock.timelock()).to.equal(this.timelock); - }); - - it('nominal', async function () { - expect(await this.mock.proposalEta(this.proposal.id)).to.equal(0n); - expect(await this.mock.proposalNeedsQueuing(this.proposal.id)).to.be.true; - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.connect(this.voter2).vote({ support: VoteType.For }); - await this.helper.connect(this.voter3).vote({ support: VoteType.Against }); - await this.helper.connect(this.voter4).vote({ support: VoteType.Abstain }); - await this.helper.waitForDeadline(); - - expect(await this.mock.proposalNeedsQueuing(this.proposal.id)).to.be.true; - const txQueue = await this.helper.queue(); - - const eta = (await time.clockFromReceipt.timestamp(txQueue)) + delay; - expect(await this.mock.proposalEta(this.proposal.id)).to.equal(eta); - await this.helper.waitForEta(); - - const txExecute = this.helper.execute(); - - await expect(txQueue) - .to.emit(this.mock, 'ProposalQueued') - .withArgs(this.proposal.id, anyValue) - .to.emit(this.timelock, 'CallScheduled') - .withArgs(this.proposal.timelockid, ...Array(6).fill(anyValue)) - .to.emit(this.timelock, 'CallSalt') - .withArgs(this.proposal.timelockid, anyValue); - - await expect(txExecute) - .to.emit(this.mock, 'ProposalExecuted') - .withArgs(this.proposal.id) - .to.emit(this.timelock, 'CallExecuted') - .withArgs(this.proposal.timelockid, ...Array(4).fill(anyValue)) - .to.emit(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.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await expect(this.helper.queue()) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Queued, - GovernorHelper.proposalStatesToBitMap([ProposalState.Succeeded]), - ); - }); - }); - - describe('on execute', function () { - it('if not queued', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(1n); - - expect(await this.mock.state(this.proposal.id)).to.equal(ProposalState.Succeeded); - - await expect(this.helper.execute()) - .to.be.revertedWithCustomError(this.timelock, 'TimelockUnexpectedOperationState') - .withArgs(this.proposal.timelockid, GovernorHelper.proposalStatesToBitMap(OperationState.Ready)); - }); - - it('if too early', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - - expect(await this.mock.state(this.proposal.id)).to.equal(ProposalState.Queued); - - await expect(this.helper.execute()) - .to.be.revertedWithCustomError(this.timelock, 'TimelockUnexpectedOperationState') - .withArgs(this.proposal.timelockid, GovernorHelper.proposalStatesToBitMap(OperationState.Ready)); - }); - - it('if already executed', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - await this.helper.execute(); - - await expect(this.helper.execute()) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Executed, - GovernorHelper.proposalStatesToBitMap([ProposalState.Succeeded, ProposalState.Queued]), - ); - }); - - it('if already executed by another proposer', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - - await this.timelock.executeBatch( - ...this.proposal.shortProposal.slice(0, 3), - ethers.ZeroHash, - timelockSalt(this.mock.target, this.proposal.shortProposal[3]), - ); - - await expect(this.helper.execute()) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Executed, - GovernorHelper.proposalStatesToBitMap([ProposalState.Succeeded, ProposalState.Queued]), - ); - }); - }); - }); - - describe('cancel', function () { - it('cancel before queue prevents scheduling', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - - await expect(this.helper.cancel('internal')) - .to.emit(this.mock, 'ProposalCanceled') - .withArgs(this.proposal.id); - - expect(await this.mock.state(this.proposal.id)).to.equal(ProposalState.Canceled); - - await expect(this.helper.queue()) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Canceled, - GovernorHelper.proposalStatesToBitMap([ProposalState.Succeeded]), - ); - }); - - it('cancel after queue prevents executing', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - - await expect(this.helper.cancel('internal')) - .to.emit(this.mock, 'ProposalCanceled') - .withArgs(this.proposal.id); - - expect(await this.mock.state(this.proposal.id)).to.equal(ProposalState.Canceled); - - await expect(this.helper.execute()) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Canceled, - GovernorHelper.proposalStatesToBitMap([ProposalState.Succeeded, ProposalState.Queued]), - ); - }); - - it('cancel on timelock is reflected on governor', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - - expect(await this.mock.state(this.proposal.id)).to.equal(ProposalState.Queued); - - await expect(this.timelock.connect(this.owner).cancel(this.proposal.timelockid)) - .to.emit(this.timelock, 'Cancelled') - .withArgs(this.proposal.timelockid); - - expect(await this.mock.state(this.proposal.id)).to.equal(ProposalState.Canceled); - }); - }); - - describe('onlyGovernance', function () { - describe('relay', function () { - beforeEach(async function () { - await this.token.$_mint(this.mock, 1); - }); - - it('is protected', async function () { - await expect( - this.mock - .connect(this.owner) - .relay(this.token, 0n, this.token.interface.encodeFunctionData('transfer', [this.other.address, 1n])), - ) - .to.be.revertedWithCustomError(this.mock, 'GovernorOnlyExecutor') - .withArgs(this.owner); - }); - - it('can be executed through governance', async function () { - this.helper.setProposal( - [ - { - target: this.mock.target, - data: this.mock.interface.encodeFunctionData('relay', [ - this.token.target, - 0n, - this.token.interface.encodeFunctionData('transfer', [this.other.address, 1n]), - ]), - }, - ], - '', - ); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - - const txExecute = await this.helper.execute(); - - await expect(txExecute).to.changeTokenBalances(this.token, [this.mock, this.other], [-1n, 1n]); - - await expect(txExecute).to.emit(this.token, 'Transfer').withArgs(this.mock, this.other, 1n); - }); - - it('is payable and can transfer eth to EOA', async function () { - const t2g = 128n; // timelock to governor - const g2o = 100n; // governor to eoa (other) - - this.helper.setProposal( - [ - { - target: this.mock.target, - value: t2g, - data: this.mock.interface.encodeFunctionData('relay', [this.other.address, g2o, '0x']), - }, - ], - '', - ); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - - await expect(this.helper.execute()).to.changeEtherBalances( - [this.timelock, this.mock, this.other], - [-t2g, t2g - g2o, g2o], - ); - }); - - it('protected against other proposers', async function () { - const call = [ - this.mock, - 0n, - this.mock.interface.encodeFunctionData('relay', [ethers.ZeroAddress, 0n, '0x']), - ethers.ZeroHash, - ethers.ZeroHash, - ]; - - await this.timelock.connect(this.owner).schedule(...call, delay); - - await time.increaseBy.timestamp(delay); - - // Error bubbled up from Governor - await expect(this.timelock.connect(this.owner).execute(...call)).to.be.revertedWithPanic( - PANIC_CODES.POP_ON_EMPTY_ARRAY, - ); - }); - }); - - describe('updateTimelock', function () { - beforeEach(async function () { - this.newTimelock = await ethers.deployContract('TimelockController', [ - delay, - [this.mock], - [this.mock], - ethers.ZeroAddress, - ]); - }); - - it('is protected', async function () { - await expect(this.mock.connect(this.owner).updateTimelock(this.newTimelock)) - .to.be.revertedWithCustomError(this.mock, 'GovernorOnlyExecutor') - .withArgs(this.owner); - }); - - it('can be executed through governance to', async function () { - this.helper.setProposal( - [ - { - target: this.mock.target, - data: this.mock.interface.encodeFunctionData('updateTimelock', [this.newTimelock.target]), - }, - ], - '', - ); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - - await expect(this.helper.execute()) - .to.emit(this.mock, 'TimelockChange') - .withArgs(this.timelock, this.newTimelock); - - expect(await this.mock.timelock()).to.equal(this.newTimelock); - }); - }); - - describe('on safe receive', function () { - describe('ERC721', function () { - const tokenId = 1n; - - beforeEach(async function () { - this.token = await ethers.deployContract('$ERC721', ['Non Fungible Token', 'NFT']); - await this.token.$_mint(this.owner, tokenId); - }); - - it("can't receive an ERC721 safeTransfer", async function () { - await expect( - this.token.connect(this.owner).safeTransferFrom(this.owner, this.mock, tokenId), - ).to.be.revertedWithCustomError(this.mock, 'GovernorDisabledDeposit'); - }); - }); - - describe('ERC1155', function () { - const tokenIds = { - 1: 1000n, - 2: 2000n, - 3: 3000n, - }; - - beforeEach(async function () { - this.token = await ethers.deployContract('$ERC1155', ['https://token-cdn-domain/{id}.json']); - await this.token.$_mintBatch(this.owner, Object.keys(tokenIds), Object.values(tokenIds), '0x'); - }); - - it("can't receive ERC1155 safeTransfer", async function () { - await expect( - this.token.connect(this.owner).safeTransferFrom( - this.owner, - this.mock, - ...Object.entries(tokenIds)[0], // id + amount - '0x', - ), - ).to.be.revertedWithCustomError(this.mock, 'GovernorDisabledDeposit'); - }); - - it("can't receive ERC1155 safeBatchTransfer", async function () { - await expect( - this.token - .connect(this.owner) - .safeBatchTransferFrom(this.owner, this.mock, Object.keys(tokenIds), Object.values(tokenIds), '0x'), - ).to.be.revertedWithCustomError(this.mock, 'GovernorDisabledDeposit'); - }); - }); - }); - }); - - it('clear queue of pending governor calls', async function () { - this.helper.setProposal( - [ - { - target: this.mock.target, - data: this.mock.interface.encodeFunctionData('nonGovernanceFunction'), - }, - ], - '', - ); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - 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/openzeppelin-contracts/test/governance/extensions/GovernorVotesQuorumFraction.test.js b/lib/openzeppelin-contracts/test/governance/extensions/GovernorVotesQuorumFraction.test.js deleted file mode 100644 index 368e396..0000000 --- a/lib/openzeppelin-contracts/test/governance/extensions/GovernorVotesQuorumFraction.test.js +++ /dev/null @@ -1,165 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture, mine } = require('@nomicfoundation/hardhat-network-helpers'); - -const { GovernorHelper } = require('../../helpers/governance'); -const { ProposalState, VoteType } = require('../../helpers/enums'); -const time = require('../../helpers/time'); - -const TOKENS = [ - { Token: '$ERC20Votes', mode: 'blocknumber' }, - { Token: '$ERC20VotesTimestampMock', mode: 'timestamp' }, -]; - -const name = 'OZ-Governor'; -const version = '1'; -const tokenName = 'MockToken'; -const tokenSymbol = 'MTKN'; -const tokenSupply = ethers.parseEther('100'); -const ratio = 8n; // percents -const newRatio = 6n; // percents -const votingDelay = 4n; -const votingPeriod = 16n; -const value = ethers.parseEther('1'); - -describe('GovernorVotesQuorumFraction', function () { - for (const { Token, mode } of TOKENS) { - const fixture = async () => { - const [owner, voter1, voter2, voter3, voter4] = await ethers.getSigners(); - - const receiver = await ethers.deployContract('CallReceiverMock'); - - const token = await ethers.deployContract(Token, [tokenName, tokenSymbol, version]); - const mock = await ethers.deployContract('$GovernorMock', [name, votingDelay, votingPeriod, 0n, token, ratio]); - - await owner.sendTransaction({ to: mock, value }); - await token.$_mint(owner, tokenSupply); - - const helper = new GovernorHelper(mock, mode); - await helper.connect(owner).delegate({ token, to: voter1, value: ethers.parseEther('10') }); - await helper.connect(owner).delegate({ token, to: voter2, value: ethers.parseEther('7') }); - await helper.connect(owner).delegate({ token, to: voter3, value: ethers.parseEther('5') }); - await helper.connect(owner).delegate({ token, to: voter4, value: ethers.parseEther('2') }); - - return { owner, voter1, voter2, voter3, voter4, receiver, token, mock, helper }; - }; - - describe(`using ${Token}`, function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - - // default proposal - this.proposal = this.helper.setProposal( - [ - { - target: this.receiver.target, - value, - data: this.receiver.interface.encodeFunctionData('mockFunction'), - }, - ], - '', - ); - }); - - it('deployment check', async function () { - expect(await this.mock.name()).to.equal(name); - expect(await this.mock.token()).to.equal(this.token); - expect(await this.mock.votingDelay()).to.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.equal(votingPeriod); - expect(await this.mock.quorum(0)).to.equal(0n); - expect(await this.mock.quorumNumerator()).to.equal(ratio); - expect(await this.mock.quorumDenominator()).to.equal(100n); - expect(await time.clock[mode]().then(clock => this.mock.quorum(clock - 1n))).to.equal( - (tokenSupply * ratio) / 100n, - ); - }); - - it('quorum reached', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await this.helper.execute(); - }); - - it('quorum not reached', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter2).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - await expect(this.helper.execute()) - .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') - .withArgs( - this.proposal.id, - ProposalState.Defeated, - GovernorHelper.proposalStatesToBitMap([ProposalState.Succeeded, ProposalState.Queued]), - ); - }); - - describe('onlyGovernance updates', function () { - it('updateQuorumNumerator is protected', async function () { - await expect(this.mock.connect(this.owner).updateQuorumNumerator(newRatio)) - .to.be.revertedWithCustomError(this.mock, 'GovernorOnlyExecutor') - .withArgs(this.owner); - }); - - it('can updateQuorumNumerator through governance', async function () { - this.helper.setProposal( - [ - { - target: this.mock.target, - data: this.mock.interface.encodeFunctionData('updateQuorumNumerator', [newRatio]), - }, - ], - '', - ); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - - await expect(this.helper.execute()).to.emit(this.mock, 'QuorumNumeratorUpdated').withArgs(ratio, newRatio); - - expect(await this.mock.quorumNumerator()).to.equal(newRatio); - expect(await this.mock.quorumDenominator()).to.equal(100n); - - // it takes one block for the new quorum to take effect - expect(await time.clock[mode]().then(blockNumber => this.mock.quorum(blockNumber - 1n))).to.equal( - (tokenSupply * ratio) / 100n, - ); - - await mine(); - - expect(await time.clock[mode]().then(blockNumber => this.mock.quorum(blockNumber - 1n))).to.equal( - (tokenSupply * newRatio) / 100n, - ); - }); - - it('cannot updateQuorumNumerator over the maximum', async function () { - const quorumNumerator = 101n; - this.helper.setProposal( - [ - { - target: this.mock.target, - data: this.mock.interface.encodeFunctionData('updateQuorumNumerator', [quorumNumerator]), - }, - ], - '', - ); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For }); - await this.helper.waitForDeadline(); - - const quorumDenominator = await this.mock.quorumDenominator(); - - await expect(this.helper.execute()) - .to.be.revertedWithCustomError(this.mock, 'GovernorInvalidQuorumFraction') - .withArgs(quorumNumerator, quorumDenominator); - }); - }); - }); - } -}); diff --git a/lib/openzeppelin-contracts/test/governance/extensions/GovernorWithParams.test.js b/lib/openzeppelin-contracts/test/governance/extensions/GovernorWithParams.test.js deleted file mode 100644 index 37e15f5..0000000 --- a/lib/openzeppelin-contracts/test/governance/extensions/GovernorWithParams.test.js +++ /dev/null @@ -1,245 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { GovernorHelper } = require('../../helpers/governance'); -const { VoteType } = require('../../helpers/enums'); -const { getDomain, ExtendedBallot } = require('../../helpers/eip712'); - -const TOKENS = [ - { Token: '$ERC20Votes', mode: 'blocknumber' }, - { Token: '$ERC20VotesTimestampMock', mode: 'timestamp' }, -]; - -const name = 'OZ-Governor'; -const version = '1'; -const tokenName = 'MockToken'; -const tokenSymbol = 'MTKN'; -const tokenSupply = ethers.parseEther('100'); -const votingDelay = 4n; -const votingPeriod = 16n; -const value = ethers.parseEther('1'); - -const params = { - decoded: [42n, 'These are my params'], - encoded: ethers.AbiCoder.defaultAbiCoder().encode(['uint256', 'string'], [42n, 'These are my params']), -}; - -describe('GovernorWithParams', function () { - for (const { Token, mode } of TOKENS) { - const fixture = async () => { - const [owner, proposer, voter1, voter2, voter3, voter4, other] = await ethers.getSigners(); - const receiver = await ethers.deployContract('CallReceiverMock'); - - const token = await ethers.deployContract(Token, [tokenName, tokenSymbol, version]); - const mock = await ethers.deployContract('$GovernorWithParamsMock', [name, token]); - - await owner.sendTransaction({ to: mock, value }); - await token.$_mint(owner, tokenSupply); - - const helper = new GovernorHelper(mock, mode); - await helper.connect(owner).delegate({ token, to: voter1, value: ethers.parseEther('10') }); - await helper.connect(owner).delegate({ token, to: voter2, value: ethers.parseEther('7') }); - await helper.connect(owner).delegate({ token, to: voter3, value: ethers.parseEther('5') }); - await helper.connect(owner).delegate({ token, to: voter4, value: ethers.parseEther('2') }); - - return { owner, proposer, voter1, voter2, voter3, voter4, other, receiver, token, mock, helper }; - }; - - describe(`using ${Token}`, function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - - // default proposal - this.proposal = this.helper.setProposal( - [ - { - target: this.receiver.target, - value, - data: this.receiver.interface.encodeFunctionData('mockFunction'), - }, - ], - '', - ); - }); - - it('deployment check', async function () { - expect(await this.mock.name()).to.equal(name); - expect(await this.mock.token()).to.equal(this.token); - expect(await this.mock.votingDelay()).to.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.equal(votingPeriod); - }); - - it('nominal is unaffected', async function () { - await this.helper.connect(this.proposer).propose(); - await this.helper.waitForSnapshot(); - await this.helper.connect(this.voter1).vote({ support: VoteType.For, reason: 'This is nice' }); - await this.helper.connect(this.voter2).vote({ support: VoteType.For }); - await this.helper.connect(this.voter3).vote({ support: VoteType.Against }); - await this.helper.connect(this.voter4).vote({ support: VoteType.Abstain }); - await this.helper.waitForDeadline(); - await this.helper.execute(); - - expect(await this.mock.hasVoted(this.proposal.id, this.owner)).to.be.false; - expect(await this.mock.hasVoted(this.proposal.id, this.voter1)).to.be.true; - expect(await this.mock.hasVoted(this.proposal.id, this.voter2)).to.be.true; - expect(await ethers.provider.getBalance(this.mock)).to.equal(0n); - expect(await ethers.provider.getBalance(this.receiver)).to.equal(value); - }); - - it('Voting with params is properly supported', async function () { - await this.helper.connect(this.proposer).propose(); - await this.helper.waitForSnapshot(); - - const weight = ethers.parseEther('7') - params.decoded[0]; - - await expect( - this.helper.connect(this.voter2).vote({ - support: VoteType.For, - reason: 'no particular reason', - params: params.encoded, - }), - ) - .to.emit(this.mock, 'CountParams') - .withArgs(...params.decoded) - .to.emit(this.mock, 'VoteCastWithParams') - .withArgs( - this.voter2.address, - this.proposal.id, - VoteType.For, - weight, - 'no particular reason', - params.encoded, - ); - - expect(await this.mock.proposalVotes(this.proposal.id)).to.deep.equal([0n, weight, 0n]); - }); - - describe('voting by signature', function () { - it('supports EOA signatures', async function () { - await this.token.connect(this.voter2).delegate(this.other); - - // Run proposal - await this.helper.propose(); - await this.helper.waitForSnapshot(); - - // Prepare vote - const weight = ethers.parseEther('7') - params.decoded[0]; - const nonce = await this.mock.nonces(this.other); - const data = { - proposalId: this.proposal.id, - support: VoteType.For, - voter: this.other.address, - nonce, - reason: 'no particular reason', - params: params.encoded, - signature: (contract, message) => - getDomain(contract).then(domain => this.other.signTypedData(domain, { ExtendedBallot }, message)), - }; - - // Vote - await expect(this.helper.vote(data)) - .to.emit(this.mock, 'CountParams') - .withArgs(...params.decoded) - .to.emit(this.mock, 'VoteCastWithParams') - .withArgs(data.voter, data.proposalId, data.support, weight, data.reason, data.params); - - expect(await this.mock.proposalVotes(this.proposal.id)).to.deep.equal([0n, weight, 0n]); - expect(await this.mock.nonces(this.other)).to.equal(nonce + 1n); - }); - - it('supports EIP-1271 signature signatures', async function () { - const wallet = await ethers.deployContract('ERC1271WalletMock', [this.other]); - await this.token.connect(this.voter2).delegate(wallet); - - // Run proposal - await this.helper.propose(); - await this.helper.waitForSnapshot(); - - // Prepare vote - const weight = ethers.parseEther('7') - params.decoded[0]; - const nonce = await this.mock.nonces(this.other); - const data = { - proposalId: this.proposal.id, - support: VoteType.For, - voter: wallet.target, - nonce, - reason: 'no particular reason', - params: params.encoded, - signature: (contract, message) => - getDomain(contract).then(domain => this.other.signTypedData(domain, { ExtendedBallot }, message)), - }; - - // Vote - await expect(this.helper.vote(data)) - .to.emit(this.mock, 'CountParams') - .withArgs(...params.decoded) - .to.emit(this.mock, 'VoteCastWithParams') - .withArgs(data.voter, data.proposalId, data.support, weight, data.reason, data.params); - - expect(await this.mock.proposalVotes(this.proposal.id)).to.deep.equal([0n, weight, 0n]); - expect(await this.mock.nonces(wallet)).to.equal(nonce + 1n); - }); - - it('reverts if signature does not match signer', async function () { - await this.token.connect(this.voter2).delegate(this.other); - - // Run proposal - await this.helper.propose(); - await this.helper.waitForSnapshot(); - - // Prepare vote - const nonce = await this.mock.nonces(this.other); - const data = { - proposalId: this.proposal.id, - support: VoteType.For, - voter: this.other.address, - nonce, - reason: 'no particular reason', - params: params.encoded, - // tampered signature - signature: (contract, message) => - getDomain(contract) - .then(domain => this.other.signTypedData(domain, { ExtendedBallot }, message)) - .then(signature => { - const tamperedSig = ethers.toBeArray(signature); - tamperedSig[42] ^= 0xff; - return ethers.hexlify(tamperedSig); - }), - }; - - // Vote - await expect(this.helper.vote(data)) - .to.be.revertedWithCustomError(this.mock, 'GovernorInvalidSignature') - .withArgs(data.voter); - }); - - it('reverts if vote nonce is incorrect', async function () { - await this.token.connect(this.voter2).delegate(this.other); - - // Run proposal - await this.helper.propose(); - await this.helper.waitForSnapshot(); - - // Prepare vote - const nonce = await this.mock.nonces(this.other); - const data = { - proposalId: this.proposal.id, - support: VoteType.For, - voter: this.other.address, - nonce: nonce + 1n, - reason: 'no particular reason', - params: params.encoded, - signature: (contract, message) => - getDomain(contract).then(domain => this.other.signTypedData(domain, { ExtendedBallot }, message)), - }; - - // Vote - await expect(this.helper.vote(data)) - .to.be.revertedWithCustomError(this.mock, 'GovernorInvalidSignature') - .withArgs(data.voter); - }); - }); - }); - } -}); diff --git a/lib/openzeppelin-contracts/test/governance/utils/ERC6372.behavior.js b/lib/openzeppelin-contracts/test/governance/utils/ERC6372.behavior.js deleted file mode 100644 index abcae43..0000000 --- a/lib/openzeppelin-contracts/test/governance/utils/ERC6372.behavior.js +++ /dev/null @@ -1,25 +0,0 @@ -const { expect } = require('chai'); - -const time = require('../../helpers/time'); - -function shouldBehaveLikeERC6372(mode = 'blocknumber') { - describe('should implement ERC-6372', function () { - beforeEach(async function () { - this.mock = this.mock ?? this.token ?? this.votes; - }); - - it('clock is correct', async function () { - expect(await this.mock.clock()).to.equal(await time.clock[mode]()); - }); - - it('CLOCK_MODE is correct', async function () { - const params = new URLSearchParams(await this.mock.CLOCK_MODE()); - expect(params.get('mode')).to.equal(mode); - expect(params.get('from')).to.equal(mode == 'blocknumber' ? 'default' : null); - }); - }); -} - -module.exports = { - shouldBehaveLikeERC6372, -}; diff --git a/lib/openzeppelin-contracts/test/governance/utils/Votes.behavior.js b/lib/openzeppelin-contracts/test/governance/utils/Votes.behavior.js deleted file mode 100644 index 0997701..0000000 --- a/lib/openzeppelin-contracts/test/governance/utils/Votes.behavior.js +++ /dev/null @@ -1,325 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { mine } = require('@nomicfoundation/hardhat-network-helpers'); - -const { getDomain, Delegation } = require('../../helpers/eip712'); -const time = require('../../helpers/time'); - -const { shouldBehaveLikeERC6372 } = require('./ERC6372.behavior'); - -function shouldBehaveLikeVotes(tokens, { mode = 'blocknumber', fungible = true }) { - beforeEach(async function () { - [this.delegator, this.delegatee, this.alice, this.bob, this.other] = this.accounts; - this.domain = await getDomain(this.votes); - }); - - shouldBehaveLikeERC6372(mode); - - const getWeight = token => (fungible ? token : 1n); - - describe('run votes workflow', function () { - it('initial nonce is 0', async function () { - expect(await this.votes.nonces(this.alice)).to.equal(0n); - }); - - describe('delegation with signature', function () { - const token = tokens[0]; - - it('delegation without tokens', async function () { - expect(await this.votes.delegates(this.alice)).to.equal(ethers.ZeroAddress); - - await expect(this.votes.connect(this.alice).delegate(this.alice)) - .to.emit(this.votes, 'DelegateChanged') - .withArgs(this.alice, ethers.ZeroAddress, this.alice) - .to.not.emit(this.votes, 'DelegateVotesChanged'); - - expect(await this.votes.delegates(this.alice)).to.equal(this.alice); - }); - - it('delegation with tokens', async function () { - await this.votes.$_mint(this.alice, token); - const weight = getWeight(token); - - expect(await this.votes.delegates(this.alice)).to.equal(ethers.ZeroAddress); - - const tx = await this.votes.connect(this.alice).delegate(this.alice); - const timepoint = await time.clockFromReceipt[mode](tx); - - await expect(tx) - .to.emit(this.votes, 'DelegateChanged') - .withArgs(this.alice, ethers.ZeroAddress, this.alice) - .to.emit(this.votes, 'DelegateVotesChanged') - .withArgs(this.alice, 0n, weight); - - expect(await this.votes.delegates(this.alice)).to.equal(this.alice); - expect(await this.votes.getVotes(this.alice)).to.equal(weight); - expect(await this.votes.getPastVotes(this.alice, timepoint - 1n)).to.equal(0n); - await mine(); - expect(await this.votes.getPastVotes(this.alice, timepoint)).to.equal(weight); - }); - - it('delegation update', async function () { - await this.votes.connect(this.alice).delegate(this.alice); - await this.votes.$_mint(this.alice, token); - const weight = getWeight(token); - - expect(await this.votes.delegates(this.alice)).to.equal(this.alice); - expect(await this.votes.getVotes(this.alice)).to.equal(weight); - expect(await this.votes.getVotes(this.bob)).to.equal(0); - - const tx = await this.votes.connect(this.alice).delegate(this.bob); - const timepoint = await time.clockFromReceipt[mode](tx); - - await expect(tx) - .to.emit(this.votes, 'DelegateChanged') - .withArgs(this.alice, this.alice, this.bob) - .to.emit(this.votes, 'DelegateVotesChanged') - .withArgs(this.alice, weight, 0) - .to.emit(this.votes, 'DelegateVotesChanged') - .withArgs(this.bob, 0, weight); - - expect(await this.votes.delegates(this.alice)).to.equal(this.bob); - expect(await this.votes.getVotes(this.alice)).to.equal(0n); - expect(await this.votes.getVotes(this.bob)).to.equal(weight); - - expect(await this.votes.getPastVotes(this.alice, timepoint - 1n)).to.equal(weight); - expect(await this.votes.getPastVotes(this.bob, timepoint - 1n)).to.equal(0n); - await mine(); - expect(await this.votes.getPastVotes(this.alice, timepoint)).to.equal(0n); - expect(await this.votes.getPastVotes(this.bob, timepoint)).to.equal(weight); - }); - - describe('with signature', function () { - const nonce = 0n; - - it('accept signed delegation', async function () { - await this.votes.$_mint(this.delegator, token); - const weight = getWeight(token); - - const { r, s, v } = await this.delegator - .signTypedData( - this.domain, - { Delegation }, - { - delegatee: this.delegatee.address, - nonce, - expiry: ethers.MaxUint256, - }, - ) - .then(ethers.Signature.from); - - expect(await this.votes.delegates(this.delegator)).to.equal(ethers.ZeroAddress); - - const tx = await this.votes.delegateBySig(this.delegatee, nonce, ethers.MaxUint256, v, r, s); - const timepoint = await time.clockFromReceipt[mode](tx); - - await expect(tx) - .to.emit(this.votes, 'DelegateChanged') - .withArgs(this.delegator, ethers.ZeroAddress, this.delegatee) - .to.emit(this.votes, 'DelegateVotesChanged') - .withArgs(this.delegatee, 0, weight); - - expect(await this.votes.delegates(this.delegator.address)).to.equal(this.delegatee); - expect(await this.votes.getVotes(this.delegator.address)).to.equal(0n); - expect(await this.votes.getVotes(this.delegatee)).to.equal(weight); - expect(await this.votes.getPastVotes(this.delegatee, timepoint - 1n)).to.equal(0n); - await mine(); - expect(await this.votes.getPastVotes(this.delegatee, timepoint)).to.equal(weight); - }); - - it('rejects reused signature', async function () { - const { r, s, v } = await this.delegator - .signTypedData( - this.domain, - { Delegation }, - { - delegatee: this.delegatee.address, - nonce, - expiry: ethers.MaxUint256, - }, - ) - .then(ethers.Signature.from); - - await this.votes.delegateBySig(this.delegatee, nonce, ethers.MaxUint256, v, r, s); - - await expect(this.votes.delegateBySig(this.delegatee, nonce, ethers.MaxUint256, v, r, s)) - .to.be.revertedWithCustomError(this.votes, 'InvalidAccountNonce') - .withArgs(this.delegator, nonce + 1n); - }); - - it('rejects bad delegatee', async function () { - const { r, s, v } = await this.delegator - .signTypedData( - this.domain, - { Delegation }, - { - delegatee: this.delegatee.address, - nonce, - expiry: ethers.MaxUint256, - }, - ) - .then(ethers.Signature.from); - - const tx = await this.votes.delegateBySig(this.other, nonce, ethers.MaxUint256, v, r, s); - const receipt = await tx.wait(); - - const [delegateChanged] = receipt.logs.filter( - log => this.votes.interface.parseLog(log)?.name === 'DelegateChanged', - ); - const { args } = this.votes.interface.parseLog(delegateChanged); - expect(args.delegator).to.not.be.equal(this.delegator); - expect(args.fromDelegate).to.equal(ethers.ZeroAddress); - expect(args.toDelegate).to.equal(this.other); - }); - - it('rejects bad nonce', async function () { - const { r, s, v } = await this.delegator - .signTypedData( - this.domain, - { Delegation }, - { - delegatee: this.delegatee.address, - nonce: nonce + 1n, - expiry: ethers.MaxUint256, - }, - ) - .then(ethers.Signature.from); - - await expect(this.votes.delegateBySig(this.delegatee, nonce + 1n, ethers.MaxUint256, v, r, s)) - .to.be.revertedWithCustomError(this.votes, 'InvalidAccountNonce') - .withArgs(this.delegator, 0); - }); - - it('rejects expired permit', async function () { - const expiry = (await time.clock.timestamp()) - 1n; - const { r, s, v } = await this.delegator - .signTypedData( - this.domain, - { Delegation }, - { - delegatee: this.delegatee.address, - nonce, - expiry, - }, - ) - .then(ethers.Signature.from); - - await expect(this.votes.delegateBySig(this.delegatee, nonce, expiry, v, r, s)) - .to.be.revertedWithCustomError(this.votes, 'VotesExpiredSignature') - .withArgs(expiry); - }); - }); - }); - - describe('getPastTotalSupply', function () { - beforeEach(async function () { - await this.votes.connect(this.alice).delegate(this.alice); - }); - - it('reverts if block number >= current block', async function () { - const timepoint = 5e10; - const clock = await this.votes.clock(); - await expect(this.votes.getPastTotalSupply(timepoint)) - .to.be.revertedWithCustomError(this.votes, 'ERC5805FutureLookup') - .withArgs(timepoint, clock); - }); - - it('returns 0 if there are no checkpoints', async function () { - expect(await this.votes.getPastTotalSupply(0n)).to.equal(0n); - }); - - it('returns the correct checkpointed total supply', async function () { - const weight = tokens.map(token => getWeight(token)); - - // t0 = mint #0 - const t0 = await this.votes.$_mint(this.alice, tokens[0]); - await mine(); - // t1 = mint #1 - const t1 = await this.votes.$_mint(this.alice, tokens[1]); - await mine(); - // t2 = burn #1 - const t2 = await this.votes.$_burn(...(fungible ? [this.alice] : []), tokens[1]); - await mine(); - // t3 = mint #2 - const t3 = await this.votes.$_mint(this.alice, tokens[2]); - await mine(); - // t4 = burn #0 - const t4 = await this.votes.$_burn(...(fungible ? [this.alice] : []), tokens[0]); - await mine(); - // t5 = burn #2 - const t5 = await this.votes.$_burn(...(fungible ? [this.alice] : []), tokens[2]); - await mine(); - - t0.timepoint = await time.clockFromReceipt[mode](t0); - t1.timepoint = await time.clockFromReceipt[mode](t1); - t2.timepoint = await time.clockFromReceipt[mode](t2); - t3.timepoint = await time.clockFromReceipt[mode](t3); - t4.timepoint = await time.clockFromReceipt[mode](t4); - t5.timepoint = await time.clockFromReceipt[mode](t5); - - expect(await this.votes.getPastTotalSupply(t0.timepoint - 1n)).to.equal(0); - expect(await this.votes.getPastTotalSupply(t0.timepoint)).to.equal(weight[0]); - expect(await this.votes.getPastTotalSupply(t0.timepoint + 1n)).to.equal(weight[0]); - expect(await this.votes.getPastTotalSupply(t1.timepoint)).to.equal(weight[0] + weight[1]); - expect(await this.votes.getPastTotalSupply(t1.timepoint + 1n)).to.equal(weight[0] + weight[1]); - expect(await this.votes.getPastTotalSupply(t2.timepoint)).to.equal(weight[0]); - expect(await this.votes.getPastTotalSupply(t2.timepoint + 1n)).to.equal(weight[0]); - expect(await this.votes.getPastTotalSupply(t3.timepoint)).to.equal(weight[0] + weight[2]); - expect(await this.votes.getPastTotalSupply(t3.timepoint + 1n)).to.equal(weight[0] + weight[2]); - expect(await this.votes.getPastTotalSupply(t4.timepoint)).to.equal(weight[2]); - expect(await this.votes.getPastTotalSupply(t4.timepoint + 1n)).to.equal(weight[2]); - expect(await this.votes.getPastTotalSupply(t5.timepoint)).to.equal(0); - await expect(this.votes.getPastTotalSupply(t5.timepoint + 1n)) - .to.be.revertedWithCustomError(this.votes, 'ERC5805FutureLookup') - .withArgs(t5.timepoint + 1n, t5.timepoint + 1n); - }); - }); - - // The following tests are an 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.alice, tokens[0]); - await this.votes.$_mint(this.alice, tokens[1]); - await this.votes.$_mint(this.alice, tokens[2]); - }); - - describe('getPastVotes', function () { - it('reverts if block number >= current block', async function () { - const clock = await this.votes.clock(); - const timepoint = 5e10; // far in the future - await expect(this.votes.getPastVotes(this.bob, timepoint)) - .to.be.revertedWithCustomError(this.votes, 'ERC5805FutureLookup') - .withArgs(timepoint, clock); - }); - - it('returns 0 if there are no checkpoints', async function () { - expect(await this.votes.getPastVotes(this.bob, 0n)).to.equal(0n); - }); - - it('returns the latest block if >= last checkpoint block', async function () { - const delegate = await this.votes.connect(this.alice).delegate(this.bob); - const timepoint = await time.clockFromReceipt[mode](delegate); - await mine(2); - - const latest = await this.votes.getVotes(this.bob); - expect(await this.votes.getPastVotes(this.bob, timepoint)).to.equal(latest); - expect(await this.votes.getPastVotes(this.bob, timepoint + 1n)).to.equal(latest); - }); - - it('returns zero if < first checkpoint block', async function () { - await mine(); - const delegate = await this.votes.connect(this.alice).delegate(this.bob); - const timepoint = await time.clockFromReceipt[mode](delegate); - await mine(2); - - expect(await this.votes.getPastVotes(this.bob, timepoint - 1n)).to.equal(0n); - }); - }); - }); - }); -} - -module.exports = { - shouldBehaveLikeVotes, -}; diff --git a/lib/openzeppelin-contracts/test/governance/utils/Votes.test.js b/lib/openzeppelin-contracts/test/governance/utils/Votes.test.js deleted file mode 100644 index 7acacfc..0000000 --- a/lib/openzeppelin-contracts/test/governance/utils/Votes.test.js +++ /dev/null @@ -1,102 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { sum } = require('../../helpers/math'); -const { zip } = require('../../helpers/iterate'); -const time = require('../../helpers/time'); - -const { shouldBehaveLikeVotes } = require('./Votes.behavior'); - -const MODES = { - blocknumber: '$VotesMock', - timestamp: '$VotesTimestampMock', -}; - -const AMOUNTS = [ethers.parseEther('10000000'), 10n, 20n]; - -describe('Votes', function () { - for (const [mode, artifact] of Object.entries(MODES)) { - const fixture = async () => { - const accounts = await ethers.getSigners(); - - const amounts = Object.fromEntries( - zip( - accounts.slice(0, AMOUNTS.length).map(({ address }) => address), - AMOUNTS, - ), - ); - - const name = 'My Vote'; - const version = '1'; - const votes = await ethers.deployContract(artifact, [name, version]); - - return { accounts, amounts, votes, name, version }; - }; - - describe(`vote with ${mode}`, function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - shouldBehaveLikeVotes(AMOUNTS, { mode, fungible: true }); - - it('starts with zero votes', async function () { - expect(await this.votes.getTotalSupply()).to.equal(0n); - }); - - describe('performs voting operations', function () { - beforeEach(async function () { - this.txs = []; - for (const [account, amount] of Object.entries(this.amounts)) { - this.txs.push(await this.votes.$_mint(account, amount)); - } - }); - - it('reverts if block number >= current block', async function () { - const lastTxTimepoint = await time.clockFromReceipt[mode](this.txs.at(-1)); - const clock = await this.votes.clock(); - await expect(this.votes.getPastTotalSupply(lastTxTimepoint)) - .to.be.revertedWithCustomError(this.votes, 'ERC5805FutureLookup') - .withArgs(lastTxTimepoint, clock); - }); - - it('delegates', async function () { - expect(await this.votes.getVotes(this.accounts[0])).to.equal(0n); - expect(await this.votes.getVotes(this.accounts[1])).to.equal(0n); - expect(await this.votes.delegates(this.accounts[0])).to.equal(ethers.ZeroAddress); - expect(await this.votes.delegates(this.accounts[1])).to.equal(ethers.ZeroAddress); - - await this.votes.delegate(this.accounts[0], ethers.Typed.address(this.accounts[0])); - - expect(await this.votes.getVotes(this.accounts[0])).to.equal(this.amounts[this.accounts[0].address]); - expect(await this.votes.getVotes(this.accounts[1])).to.equal(0n); - expect(await this.votes.delegates(this.accounts[0])).to.equal(this.accounts[0]); - expect(await this.votes.delegates(this.accounts[1])).to.equal(ethers.ZeroAddress); - - await this.votes.delegate(this.accounts[1], ethers.Typed.address(this.accounts[0])); - - expect(await this.votes.getVotes(this.accounts[0])).to.equal( - this.amounts[this.accounts[0].address] + this.amounts[this.accounts[1].address], - ); - expect(await this.votes.getVotes(this.accounts[1])).to.equal(0n); - expect(await this.votes.delegates(this.accounts[0])).to.equal(this.accounts[0]); - expect(await this.votes.delegates(this.accounts[1])).to.equal(this.accounts[0]); - }); - - it('cross delegates', async function () { - await this.votes.delegate(this.accounts[0], ethers.Typed.address(this.accounts[1])); - await this.votes.delegate(this.accounts[1], ethers.Typed.address(this.accounts[0])); - - expect(await this.votes.getVotes(this.accounts[0])).to.equal(this.amounts[this.accounts[1].address]); - expect(await this.votes.getVotes(this.accounts[1])).to.equal(this.amounts[this.accounts[0].address]); - }); - - it('returns total amount of votes', async function () { - const totalSupply = sum(...Object.values(this.amounts)); - expect(await this.votes.getTotalSupply()).to.equal(totalSupply); - }); - }); - }); - } -}); diff --git a/lib/openzeppelin-contracts/test/helpers/access-manager.js b/lib/openzeppelin-contracts/test/helpers/access-manager.js deleted file mode 100644 index 3b83430..0000000 --- a/lib/openzeppelin-contracts/test/helpers/access-manager.js +++ /dev/null @@ -1,85 +0,0 @@ -const { ethers } = require('hardhat'); - -const { MAX_UINT64 } = require('./constants'); -const time = require('./time'); -const { upgradeableSlot } = require('./storage'); - -function buildBaseRoles() { - const roles = { - ADMIN: { - id: 0n, - }, - SOME_ADMIN: { - id: 17n, - }, - SOME_GUARDIAN: { - id: 35n, - }, - SOME: { - id: 42n, - }, - PUBLIC: { - id: MAX_UINT64, - }, - }; - - // Names - Object.entries(roles).forEach(([name, role]) => (role.name = name)); - - // Defaults - for (const role of Object.keys(roles)) { - roles[role].admin = roles.ADMIN; - roles[role].guardian = roles.ADMIN; - } - - // Admins - roles.SOME.admin = roles.SOME_ADMIN; - - // Guardians - roles.SOME.guardian = roles.SOME_GUARDIAN; - - return roles; -} - -const formatAccess = access => [access[0], access[1].toString()]; - -const MINSETBACK = time.duration.days(5); -const EXPIRATION = time.duration.weeks(1); - -const EXECUTION_ID_STORAGE_SLOT = upgradeableSlot('AccessManager', 3n); -const CONSUMING_SCHEDULE_STORAGE_SLOT = upgradeableSlot('AccessManaged', 0n); - -/** - * @requires this.{manager, caller, target, calldata} - */ -async function prepareOperation(manager, { caller, target, calldata, delay }) { - const scheduledAt = (await time.clock.timestamp()) + 1n; - await time.increaseTo.timestamp(scheduledAt, false); // Fix next block timestamp for predictability - - return { - schedule: () => manager.connect(caller).schedule(target, calldata, scheduledAt + delay), - scheduledAt, - operationId: hashOperation(caller, target, calldata), - }; -} - -const lazyGetAddress = addressable => addressable.address ?? addressable.target ?? addressable; - -const hashOperation = (caller, target, data) => - ethers.keccak256( - ethers.AbiCoder.defaultAbiCoder().encode( - ['address', 'address', 'bytes'], - [lazyGetAddress(caller), lazyGetAddress(target), data], - ), - ); - -module.exports = { - buildBaseRoles, - formatAccess, - MINSETBACK, - EXPIRATION, - EXECUTION_ID_STORAGE_SLOT, - CONSUMING_SCHEDULE_STORAGE_SLOT, - prepareOperation, - hashOperation, -}; diff --git a/lib/openzeppelin-contracts/test/helpers/account.js b/lib/openzeppelin-contracts/test/helpers/account.js deleted file mode 100644 index 96874b1..0000000 --- a/lib/openzeppelin-contracts/test/helpers/account.js +++ /dev/null @@ -1,14 +0,0 @@ -const { ethers } = require('hardhat'); -const { impersonateAccount, setBalance } = require('@nomicfoundation/hardhat-network-helpers'); - -// Hardhat default balance -const DEFAULT_BALANCE = 10000n * ethers.WeiPerEther; - -const impersonate = (account, balance = DEFAULT_BALANCE) => - impersonateAccount(account) - .then(() => setBalance(account, balance)) - .then(() => ethers.getSigner(account)); - -module.exports = { - impersonate, -}; diff --git a/lib/openzeppelin-contracts/test/helpers/constants.js b/lib/openzeppelin-contracts/test/helpers/constants.js deleted file mode 100644 index 4dfda5e..0000000 --- a/lib/openzeppelin-contracts/test/helpers/constants.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - MAX_UINT48: 2n ** 48n - 1n, - MAX_UINT64: 2n ** 64n - 1n, -}; diff --git a/lib/openzeppelin-contracts/test/helpers/deploy.js b/lib/openzeppelin-contracts/test/helpers/deploy.js deleted file mode 100644 index 0d4b956..0000000 --- a/lib/openzeppelin-contracts/test/helpers/deploy.js +++ /dev/null @@ -1,14 +0,0 @@ -const { artifacts, ethers } = require('hardhat'); -const { setCode } = require('@nomicfoundation/hardhat-network-helpers'); -const { generators } = require('./random'); - -const forceDeployCode = (name, address = generators.address(), runner = ethers.provider) => - artifacts - .readArtifact(name) - .then(({ abi, deployedBytecode }) => - setCode(address, deployedBytecode).then(() => new ethers.Contract(address, abi, runner)), - ); - -module.exports = { - forceDeployCode, -}; diff --git a/lib/openzeppelin-contracts/test/helpers/eip712-types.js b/lib/openzeppelin-contracts/test/helpers/eip712-types.js deleted file mode 100644 index b2b6ccf..0000000 --- a/lib/openzeppelin-contracts/test/helpers/eip712-types.js +++ /dev/null @@ -1,52 +0,0 @@ -const { mapValues } = require('./iterate'); - -const formatType = schema => Object.entries(schema).map(([name, type]) => ({ name, type })); - -module.exports = mapValues( - { - EIP712Domain: { - name: 'string', - version: 'string', - chainId: 'uint256', - verifyingContract: 'address', - salt: 'bytes32', - }, - Permit: { - owner: 'address', - spender: 'address', - value: 'uint256', - nonce: 'uint256', - deadline: 'uint256', - }, - Ballot: { - proposalId: 'uint256', - support: 'uint8', - voter: 'address', - nonce: 'uint256', - }, - ExtendedBallot: { - proposalId: 'uint256', - support: 'uint8', - voter: 'address', - nonce: 'uint256', - reason: 'string', - params: 'bytes', - }, - Delegation: { - delegatee: 'address', - nonce: 'uint256', - expiry: 'uint256', - }, - ForwardRequest: { - from: 'address', - to: 'address', - value: 'uint256', - gas: 'uint256', - nonce: 'uint256', - deadline: 'uint48', - data: 'bytes', - }, - }, - formatType, -); -module.exports.formatType = formatType; diff --git a/lib/openzeppelin-contracts/test/helpers/eip712.js b/lib/openzeppelin-contracts/test/helpers/eip712.js deleted file mode 100644 index 3843ac0..0000000 --- a/lib/openzeppelin-contracts/test/helpers/eip712.js +++ /dev/null @@ -1,45 +0,0 @@ -const { ethers } = require('hardhat'); -const types = require('./eip712-types'); - -async function getDomain(contract) { - const { fields, name, version, chainId, verifyingContract, salt, extensions } = await contract.eip712Domain(); - - if (extensions.length > 0) { - throw Error('Extensions not implemented'); - } - - const domain = { - name, - version, - chainId, - verifyingContract, - salt, - }; - - for (const [i, { name }] of types.EIP712Domain.entries()) { - if (!(fields & (1 << i))) { - delete domain[name]; - } - } - - return domain; -} - -function domainType(domain) { - return types.EIP712Domain.filter(({ name }) => domain[name] !== undefined); -} - -function hashTypedData(domain, structHash) { - return ethers.solidityPackedKeccak256( - ['bytes', 'bytes32', 'bytes32'], - ['0x1901', ethers.TypedDataEncoder.hashDomain(domain), structHash], - ); -} - -module.exports = { - getDomain, - domainType, - domainSeparator: ethers.TypedDataEncoder.hashDomain, - hashTypedData, - ...types, -}; diff --git a/lib/openzeppelin-contracts/test/helpers/enums.js b/lib/openzeppelin-contracts/test/helpers/enums.js deleted file mode 100644 index f95767a..0000000 --- a/lib/openzeppelin-contracts/test/helpers/enums.js +++ /dev/null @@ -1,12 +0,0 @@ -function Enum(...options) { - return Object.fromEntries(options.map((key, i) => [key, BigInt(i)])); -} - -module.exports = { - Enum, - ProposalState: Enum('Pending', 'Active', 'Canceled', 'Defeated', 'Succeeded', 'Queued', 'Expired', 'Executed'), - VoteType: Object.assign(Enum('Against', 'For', 'Abstain'), { Parameters: 255n }), - Rounding: Enum('Floor', 'Ceil', 'Trunc', 'Expand'), - OperationState: Enum('Unset', 'Waiting', 'Ready', 'Done'), - RevertType: Enum('None', 'RevertWithoutMessage', 'RevertWithMessage', 'RevertWithCustomError', 'Panic'), -}; diff --git a/lib/openzeppelin-contracts/test/helpers/governance.js b/lib/openzeppelin-contracts/test/helpers/governance.js deleted file mode 100644 index dce5927..0000000 --- a/lib/openzeppelin-contracts/test/helpers/governance.js +++ /dev/null @@ -1,198 +0,0 @@ -const { ethers } = require('hardhat'); -const { ProposalState } = require('./enums'); -const { unique } = require('./iterate'); -const time = require('./time'); - -const timelockSalt = (address, descriptionHash) => - ethers.toBeHex((ethers.toBigInt(address) << 96n) ^ ethers.toBigInt(descriptionHash), 32); - -class GovernorHelper { - constructor(governor, mode = 'blocknumber') { - this.governor = governor; - this.mode = mode; - } - - connect(account) { - this.governor = this.governor.connect(account); - return this; - } - - /// Setter and getters - /** - * Specify a proposal either as - * 1) an array of objects [{ target, value, data }] - * 2) an object of arrays { targets: [], values: [], data: [] } - */ - setProposal(actions, description) { - if (Array.isArray(actions)) { - this.targets = actions.map(a => a.target); - this.values = actions.map(a => a.value || 0n); - this.data = actions.map(a => a.data || '0x'); - } else { - ({ targets: this.targets, values: this.values, data: this.data } = actions); - } - this.description = description; - return this; - } - - get id() { - return ethers.keccak256( - ethers.AbiCoder.defaultAbiCoder().encode(['address[]', 'uint256[]', 'bytes[]', 'bytes32'], this.shortProposal), - ); - } - - // used for checking events - get signatures() { - return this.data.map(() => ''); - } - - get descriptionHash() { - return ethers.id(this.description); - } - - // condensed version for queueing end executing - get shortProposal() { - return [this.targets, this.values, this.data, this.descriptionHash]; - } - - // full version for proposing - get fullProposal() { - return [this.targets, this.values, this.data, this.description]; - } - - get currentProposal() { - return this; - } - - /// Proposal lifecycle - delegate(delegation) { - return Promise.all([ - delegation.token.connect(delegation.to).delegate(delegation.to), - delegation.value === undefined || - delegation.token.connect(this.governor.runner).transfer(delegation.to, delegation.value), - delegation.tokenId === undefined || - delegation.token - .ownerOf(delegation.tokenId) - .then(owner => - delegation.token.connect(this.governor.runner).transferFrom(owner, delegation.to, delegation.tokenId), - ), - ]); - } - - propose() { - return this.governor.propose(...this.fullProposal); - } - - queue() { - return this.governor.queue(...this.shortProposal); - } - - execute() { - return this.governor.execute(...this.shortProposal); - } - - cancel(visibility = 'external') { - switch (visibility) { - case 'external': - return this.governor.cancel(...this.shortProposal); - - case 'internal': - return this.governor.$_cancel(...this.shortProposal); - - default: - throw new Error(`unsupported visibility "${visibility}"`); - } - } - - async vote(vote = {}) { - let method = 'castVote'; // default - let args = [this.id, vote.support]; // base - - if (vote.signature) { - const sign = await vote.signature(this.governor, this.forgeMessage(vote)); - if (vote.params || vote.reason) { - method = 'castVoteWithReasonAndParamsBySig'; - args.push(vote.voter, vote.reason ?? '', vote.params ?? '0x', sign); - } else { - method = 'castVoteBySig'; - args.push(vote.voter, sign); - } - } else if (vote.params) { - method = 'castVoteWithReasonAndParams'; - args.push(vote.reason ?? '', vote.params); - } else if (vote.reason) { - method = 'castVoteWithReason'; - args.push(vote.reason); - } - - return await this.governor[method](...args); - } - - /// Clock helpers - async waitForSnapshot(offset = 0n) { - const timepoint = await this.governor.proposalSnapshot(this.id); - return time.increaseTo[this.mode](timepoint + offset); - } - - async waitForDeadline(offset = 0n) { - const timepoint = await this.governor.proposalDeadline(this.id); - return time.increaseTo[this.mode](timepoint + offset); - } - - async waitForEta(offset = 0n) { - const timestamp = await this.governor.proposalEta(this.id); - return time.increaseTo.timestamp(timestamp + offset); - } - - /// Other helpers - forgeMessage(vote = {}) { - const message = { proposalId: this.id, support: vote.support, voter: vote.voter, nonce: vote.nonce }; - - if (vote.params || vote.reason) { - message.reason = vote.reason ?? ''; - message.params = vote.params ?? '0x'; - } - - return message; - } - - /** - * Encodes a list ProposalStates into a bytes32 representation where each bit enabled corresponds to - * the underlying position in the `ProposalState` enum. For example: - * - * 0x000...10000 - * ^^^^^^------ ... - * ^----- Succeeded - * ^---- Defeated - * ^--- Canceled - * ^-- Active - * ^- Pending - */ - static proposalStatesToBitMap(proposalStates, options = {}) { - if (!Array.isArray(proposalStates)) { - proposalStates = [proposalStates]; - } - const statesCount = ethers.toBigInt(Object.keys(ProposalState).length); - let result = 0n; - - for (const state of unique(proposalStates)) { - if (state < 0n || state >= statesCount) { - expect.fail(`ProposalState ${state} out of possible states (0...${statesCount}-1)`); - } else { - result |= 1n << state; - } - } - - if (options.inverted) { - const mask = 2n ** statesCount - 1n; - result = result ^ mask; - } - - return ethers.toBeHex(result, 32); - } -} - -module.exports = { - GovernorHelper, - timelockSalt, -}; diff --git a/lib/openzeppelin-contracts/test/helpers/iterate.js b/lib/openzeppelin-contracts/test/helpers/iterate.js deleted file mode 100644 index ef4526e..0000000 --- a/lib/openzeppelin-contracts/test/helpers/iterate.js +++ /dev/null @@ -1,36 +0,0 @@ -module.exports = { - // ================================================= Array helpers ================================================= - - // Cut an array into an array of sized-length arrays - // Example: chunk([1,2,3,4,5,6,7,8], 3) → [[1,2,3],[4,5,6],[7,8]] - chunk: (array, size = 1) => - Array.from({ length: Math.ceil(array.length / size) }, (_, i) => array.slice(i * size, i * size + size)), - - // Cartesian cross product of an array of arrays - // Example: product([1,2],[a,b,c],[true]) → [[1,a,true],[1,b,true],[1,c,true],[2,a,true],[2,b,true],[2,c,true]] - product: (...arrays) => arrays.reduce((a, b) => a.flatMap(ai => b.map(bi => [...ai, bi])), [[]]), - - // Range from start to end in increment - // Example: range(17,42,7) → [17,24,31,38] - range: (start, stop = undefined, step = 1) => { - if (!stop) { - stop = start; - start = 0; - } - return start < stop ? Array.from({ length: Math.ceil((stop - start) / step) }, (_, i) => start + i * step) : []; - }, - - // Unique elements, with an optional getter function - // Example: unique([1,1,2,3,4,8,1,3,8,13,42]) → [1,2,3,4,8,13,42] - unique: (array, op = x => x) => array.filter((obj, i) => array.findIndex(entry => op(obj) === op(entry)) === i), - - // Zip arrays together. If some arrays are smaller, undefined is used as a filler. - // Example: zip([1,2],[a,b,c],[true]) → [[1,a,true],[2,b,undefined],[undefined,c,undefined]] - zip: (...args) => Array.from({ length: Math.max(...args.map(arg => arg.length)) }, (_, i) => args.map(arg => arg[i])), - - // ================================================ Object helpers ================================================= - - // Create a new object by mapping the values through a function, keeping the keys - // Example: mapValues({a:1,b:2,c:3}, x => x**2) → {a:1,b:4,c:9} - mapValues: (obj, fn) => Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, fn(v)])), -}; diff --git a/lib/openzeppelin-contracts/test/helpers/math.js b/lib/openzeppelin-contracts/test/helpers/math.js deleted file mode 100644 index 133254a..0000000 --- a/lib/openzeppelin-contracts/test/helpers/math.js +++ /dev/null @@ -1,33 +0,0 @@ -// Array of number or bigint -const max = (...values) => values.slice(1).reduce((x, y) => (x > y ? x : y), values.at(0)); -const min = (...values) => values.slice(1).reduce((x, y) => (x < y ? x : y), values.at(0)); -const sum = (...values) => values.slice(1).reduce((x, y) => x + y, values.at(0)); - -// Computes modexp without BigInt overflow for large numbers -function modExp(b, e, m) { - let result = 1n; - - // If e is a power of two, modexp can be calculated as: - // for (let result = b, i = 0; i < log2(e); i++) result = modexp(result, 2, m) - // - // Given any natural number can be written in terms of powers of 2 (i.e. binary) - // then modexp can be calculated for any e, by multiplying b**i for all i where - // binary(e)[i] is 1 (i.e. a power of two). - for (let base = b % m; e > 0n; base = base ** 2n % m) { - // Least significant bit is 1 - if (e % 2n == 1n) { - result = (result * base) % m; - } - - e /= 2n; // Binary pop - } - - return result; -} - -module.exports = { - min, - max, - sum, - modExp, -}; diff --git a/lib/openzeppelin-contracts/test/helpers/methods.js b/lib/openzeppelin-contracts/test/helpers/methods.js deleted file mode 100644 index a491897..0000000 --- a/lib/openzeppelin-contracts/test/helpers/methods.js +++ /dev/null @@ -1,14 +0,0 @@ -const { ethers } = require('hardhat'); - -const selector = signature => ethers.FunctionFragment.from(signature).selector; - -const interfaceId = signatures => - ethers.toBeHex( - signatures.reduce((acc, signature) => acc ^ ethers.toBigInt(selector(signature)), 0n), - 4, - ); - -module.exports = { - selector, - interfaceId, -}; diff --git a/lib/openzeppelin-contracts/test/helpers/random.js b/lib/openzeppelin-contracts/test/helpers/random.js deleted file mode 100644 index 3adeed0..0000000 --- a/lib/openzeppelin-contracts/test/helpers/random.js +++ /dev/null @@ -1,19 +0,0 @@ -const { ethers } = require('hardhat'); - -const generators = { - address: () => ethers.Wallet.createRandom().address, - bytes32: () => ethers.hexlify(ethers.randomBytes(32)), - uint256: () => ethers.toBigInt(ethers.randomBytes(32)), - int256: () => ethers.toBigInt(ethers.randomBytes(32)) + ethers.MinInt256, - hexBytes: length => ethers.hexlify(ethers.randomBytes(length)), -}; - -generators.address.zero = ethers.ZeroAddress; -generators.bytes32.zero = ethers.ZeroHash; -generators.uint256.zero = 0n; -generators.int256.zero = 0n; -generators.hexBytes.zero = '0x'; - -module.exports = { - generators, -}; diff --git a/lib/openzeppelin-contracts/test/helpers/storage.js b/lib/openzeppelin-contracts/test/helpers/storage.js deleted file mode 100644 index a75a306..0000000 --- a/lib/openzeppelin-contracts/test/helpers/storage.js +++ /dev/null @@ -1,48 +0,0 @@ -const { ethers } = require('hardhat'); -const { setStorageAt } = require('@nomicfoundation/hardhat-network-helpers'); - -const ImplementationLabel = 'eip1967.proxy.implementation'; -const AdminLabel = 'eip1967.proxy.admin'; -const BeaconLabel = 'eip1967.proxy.beacon'; - -const erc1967Slot = label => ethers.toBeHex(ethers.toBigInt(ethers.id(label)) - 1n); -const erc7201Slot = label => ethers.toBeHex(ethers.toBigInt(ethers.keccak256(erc1967Slot(label))) & ~0xffn); -const erc7201format = contractName => `openzeppelin.storage.${contractName}`; - -const getSlot = (address, slot) => - ethers.provider.getStorage(address, ethers.isBytesLike(slot) ? slot : erc1967Slot(slot)); - -const setSlot = (address, slot, value) => - Promise.all([ - ethers.isAddressable(address) ? address.getAddress() : Promise.resolve(address), - ethers.isAddressable(value) ? value.getAddress() : Promise.resolve(value), - ]).then(([address, value]) => setStorageAt(address, ethers.isBytesLike(slot) ? slot : erc1967Slot(slot), value)); - -const getAddressInSlot = (address, slot) => - getSlot(address, slot).then(slotValue => ethers.AbiCoder.defaultAbiCoder().decode(['address'], slotValue)[0]); - -const upgradeableSlot = (contractName, offset) => { - try { - // Try to get the artifact paths, will throw if it doesn't exist - artifacts._getArtifactPathSync(`${contractName}Upgradeable`); - return offset + ethers.toBigInt(erc7201Slot(erc7201format(contractName))); - } catch (_) { - return offset; - } -}; - -module.exports = { - ImplementationLabel, - AdminLabel, - BeaconLabel, - ImplementationSlot: erc1967Slot(ImplementationLabel), - AdminSlot: erc1967Slot(AdminLabel), - BeaconSlot: erc1967Slot(BeaconLabel), - erc1967Slot, - erc7201Slot, - erc7201format, - setSlot, - getSlot, - getAddressInSlot, - upgradeableSlot, -}; diff --git a/lib/openzeppelin-contracts/test/helpers/strings.js b/lib/openzeppelin-contracts/test/helpers/strings.js deleted file mode 100644 index 4f34099..0000000 --- a/lib/openzeppelin-contracts/test/helpers/strings.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - // Capitalize the first char of a string - // Example: capitalize('uint256') → 'Uint256' - capitalize: str => str.charAt(0).toUpperCase() + str.slice(1), -}; diff --git a/lib/openzeppelin-contracts/test/helpers/time.js b/lib/openzeppelin-contracts/test/helpers/time.js deleted file mode 100644 index f6ccc3c..0000000 --- a/lib/openzeppelin-contracts/test/helpers/time.js +++ /dev/null @@ -1,30 +0,0 @@ -const { ethers } = require('hardhat'); -const { time, mine, mineUpTo } = require('@nomicfoundation/hardhat-network-helpers'); -const { mapValues } = require('./iterate'); - -const clock = { - blocknumber: () => time.latestBlock().then(ethers.toBigInt), - timestamp: () => time.latest().then(ethers.toBigInt), -}; -const clockFromReceipt = { - blocknumber: receipt => Promise.resolve(ethers.toBigInt(receipt.blockNumber)), - timestamp: receipt => ethers.provider.getBlock(receipt.blockNumber).then(block => ethers.toBigInt(block.timestamp)), -}; -const increaseBy = { - blockNumber: mine, - timestamp: (delay, mine = true) => - time.latest().then(clock => increaseTo.timestamp(clock + ethers.toNumber(delay), mine)), -}; -const increaseTo = { - blocknumber: mineUpTo, - timestamp: (to, mine = true) => (mine ? time.increaseTo(to) : time.setNextBlockTimestamp(to)), -}; -const duration = mapValues(time.duration, fn => n => ethers.toBigInt(fn(ethers.toNumber(n)))); - -module.exports = { - clock, - clockFromReceipt, - increaseBy, - increaseTo, - duration, -}; diff --git a/lib/openzeppelin-contracts/test/helpers/txpool.js b/lib/openzeppelin-contracts/test/helpers/txpool.js deleted file mode 100644 index f01327b..0000000 --- a/lib/openzeppelin-contracts/test/helpers/txpool.js +++ /dev/null @@ -1,29 +0,0 @@ -const { network } = require('hardhat'); -const { expect } = require('chai'); -const { mine } = require('@nomicfoundation/hardhat-network-helpers'); - -const { unique } = require('./iterate'); - -async function batchInBlock(txs) { - try { - // disable auto-mining - await network.provider.send('evm_setAutomine', [false]); - // send all transactions - const responses = await Promise.all(txs.map(fn => fn())); - // mine one block - await mine(); - // fetch receipts - const receipts = await Promise.all(responses.map(response => response.wait())); - // Sanity check, all tx should be in the same block - expect(unique(receipts.map(receipt => receipt.blockNumber))).to.have.lengthOf(1); - // return responses - return receipts; - } finally { - // enable auto-mining - await network.provider.send('evm_setAutomine', [true]); - } -} - -module.exports = { - batchInBlock, -}; diff --git a/lib/openzeppelin-contracts/test/metatx/ERC2771Context.test.js b/lib/openzeppelin-contracts/test/metatx/ERC2771Context.test.js deleted file mode 100644 index 15da61d..0000000 --- a/lib/openzeppelin-contracts/test/metatx/ERC2771Context.test.js +++ /dev/null @@ -1,133 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { impersonate } = require('../helpers/account'); -const { getDomain, ForwardRequest } = require('../helpers/eip712'); -const { MAX_UINT48 } = require('../helpers/constants'); - -const { shouldBehaveLikeRegularContext } = require('../utils/Context.behavior'); - -async function fixture() { - const [sender, other] = await ethers.getSigners(); - - const forwarder = await ethers.deployContract('ERC2771Forwarder', []); - const forwarderAsSigner = await impersonate(forwarder.target); - const context = await ethers.deployContract('ERC2771ContextMock', [forwarder]); - const domain = await getDomain(forwarder); - const types = { ForwardRequest }; - - return { sender, other, forwarder, forwarderAsSigner, context, domain, types }; -} - -describe('ERC2771Context', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - it('recognize trusted forwarder', async function () { - expect(await this.context.isTrustedForwarder(this.forwarder)).to.be.true; - }); - - it('returns the trusted forwarder', async function () { - expect(await this.context.trustedForwarder()).to.equal(this.forwarder); - }); - - describe('when called directly', function () { - shouldBehaveLikeRegularContext(); - }); - - describe('when receiving a relayed call', function () { - describe('msgSender', function () { - it('returns the relayed transaction original sender', async function () { - const nonce = await this.forwarder.nonces(this.sender); - const data = this.context.interface.encodeFunctionData('msgSender'); - - const req = { - from: await this.sender.getAddress(), - to: await this.context.getAddress(), - value: 0n, - data, - gas: 100000n, - nonce, - deadline: MAX_UINT48, - }; - - req.signature = await this.sender.signTypedData(this.domain, this.types, req); - - expect(await this.forwarder.verify(req)).to.be.true; - - await expect(this.forwarder.execute(req)).to.emit(this.context, 'Sender').withArgs(this.sender); - }); - - it('returns the original sender when calldata length is less than 20 bytes (address length)', async function () { - // The forwarder doesn't produce calls with calldata length less than 20 bytes so `this.forwarderAsSigner` is used instead. - await expect(this.context.connect(this.forwarderAsSigner).msgSender()) - .to.emit(this.context, 'Sender') - .withArgs(this.forwarder); - }); - }); - - describe('msgData', function () { - it('returns the relayed transaction original data', async function () { - const args = [42n, 'OpenZeppelin']; - - const nonce = await this.forwarder.nonces(this.sender); - const data = this.context.interface.encodeFunctionData('msgData', args); - - const req = { - from: await this.sender.getAddress(), - to: await this.context.getAddress(), - value: 0n, - data, - gas: 100000n, - nonce, - deadline: MAX_UINT48, - }; - - req.signature = this.sender.signTypedData(this.domain, this.types, req); - - expect(await this.forwarder.verify(req)).to.be.true; - - await expect(this.forwarder.execute(req)) - .to.emit(this.context, 'Data') - .withArgs(data, ...args); - }); - }); - - it('returns the full original data when calldata length is less than 20 bytes (address length)', async function () { - const data = this.context.interface.encodeFunctionData('msgDataShort'); - - // The forwarder doesn't produce calls with calldata length less than 20 bytes so `this.forwarderAsSigner` is used instead. - await expect(await this.context.connect(this.forwarderAsSigner).msgDataShort()) - .to.emit(this.context, 'DataShort') - .withArgs(data); - }); - }); - - it('multicall poison attack', async function () { - const nonce = await this.forwarder.nonces(this.sender); - const data = this.context.interface.encodeFunctionData('multicall', [ - [ - // poisonned call to 'msgSender()' - ethers.concat([this.context.interface.encodeFunctionData('msgSender'), this.other.address]), - ], - ]); - - const req = { - from: await this.sender.getAddress(), - to: await this.context.getAddress(), - value: 0n, - data, - gas: 100000n, - nonce, - deadline: MAX_UINT48, - }; - - req.signature = await this.sender.signTypedData(this.domain, this.types, req); - - expect(await this.forwarder.verify(req)).to.be.true; - - await expect(this.forwarder.execute(req)).to.emit(this.context, 'Sender').withArgs(this.sender); - }); -}); diff --git a/lib/openzeppelin-contracts/test/metatx/ERC2771Forwarder.t.sol b/lib/openzeppelin-contracts/test/metatx/ERC2771Forwarder.t.sol deleted file mode 100644 index d69b475..0000000 --- a/lib/openzeppelin-contracts/test/metatx/ERC2771Forwarder.t.sol +++ /dev/null @@ -1,165 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {Test} from "forge-std/Test.sol"; -import {ERC2771Forwarder} from "@openzeppelin/contracts/metatx/ERC2771Forwarder.sol"; -import {CallReceiverMockTrustingForwarder, CallReceiverMock} from "@openzeppelin/contracts/mocks/CallReceiverMock.sol"; - -struct ForwardRequest { - address from; - address to; - uint256 value; - uint256 gas; - uint256 nonce; - uint48 deadline; - bytes data; -} - -contract ERC2771ForwarderMock is ERC2771Forwarder { - constructor(string memory name) ERC2771Forwarder(name) {} - - function structHash(ForwardRequest calldata request) external view returns (bytes32) { - return - _hashTypedDataV4( - keccak256( - abi.encode( - _FORWARD_REQUEST_TYPEHASH, - request.from, - request.to, - request.value, - request.gas, - request.nonce, - request.deadline, - keccak256(request.data) - ) - ) - ); - } -} - -contract ERC2771ForwarderTest is Test { - ERC2771ForwarderMock internal _erc2771Forwarder; - CallReceiverMockTrustingForwarder internal _receiver; - - uint256 internal _signerPrivateKey; - uint256 internal _relayerPrivateKey; - - address internal _signer; - address internal _relayer; - - uint256 internal constant _MAX_ETHER = 10_000_000; // To avoid overflow - - function setUp() public { - _erc2771Forwarder = new ERC2771ForwarderMock("ERC2771Forwarder"); - _receiver = new CallReceiverMockTrustingForwarder(address(_erc2771Forwarder)); - - _signerPrivateKey = 0xA11CE; - _relayerPrivateKey = 0xB0B; - - _signer = vm.addr(_signerPrivateKey); - _relayer = vm.addr(_relayerPrivateKey); - } - - function _forgeRequestData( - uint256 value, - uint256 nonce, - uint48 deadline, - bytes memory data - ) private view returns (ERC2771Forwarder.ForwardRequestData memory) { - ForwardRequest memory request = ForwardRequest({ - from: _signer, - to: address(_receiver), - value: value, - gas: 30000, - nonce: nonce, - deadline: deadline, - data: data - }); - - bytes32 digest = _erc2771Forwarder.structHash(request); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(_signerPrivateKey, digest); - bytes memory signature = abi.encodePacked(r, s, v); - - return - ERC2771Forwarder.ForwardRequestData({ - from: request.from, - to: request.to, - value: request.value, - gas: request.gas, - deadline: request.deadline, - data: request.data, - signature: signature - }); - } - - function testExecuteAvoidsETHStuck(uint256 initialBalance, uint256 value, bool targetReverts) public { - initialBalance = bound(initialBalance, 0, _MAX_ETHER); - value = bound(value, 0, _MAX_ETHER); - - vm.deal(address(_erc2771Forwarder), initialBalance); - - uint256 nonce = _erc2771Forwarder.nonces(_signer); - - vm.deal(address(this), value); - - ERC2771Forwarder.ForwardRequestData memory requestData = _forgeRequestData({ - value: value, - nonce: nonce, - deadline: uint48(block.timestamp + 1), - data: targetReverts - ? abi.encodeCall(CallReceiverMock.mockFunctionRevertsNoReason, ()) - : abi.encodeCall(CallReceiverMock.mockFunction, ()) - }); - - if (targetReverts) { - vm.expectRevert(); - } - - _erc2771Forwarder.execute{value: value}(requestData); - assertEq(address(_erc2771Forwarder).balance, initialBalance); - } - - function testExecuteBatchAvoidsETHStuck(uint256 initialBalance, uint256 batchSize, uint256 value) public { - batchSize = bound(batchSize, 1, 10); - initialBalance = bound(initialBalance, 0, _MAX_ETHER); - value = bound(value, 0, _MAX_ETHER); - - vm.deal(address(_erc2771Forwarder), initialBalance); - uint256 nonce = _erc2771Forwarder.nonces(_signer); - - ERC2771Forwarder.ForwardRequestData[] memory batchRequestDatas = new ERC2771Forwarder.ForwardRequestData[]( - batchSize - ); - - uint256 expectedRefund; - - for (uint256 i = 0; i < batchSize; ++i) { - bytes memory data; - bool succeed = uint256(keccak256(abi.encodePacked(initialBalance, i))) % 2 == 0; - - if (succeed) { - data = abi.encodeCall(CallReceiverMock.mockFunction, ()); - } else { - expectedRefund += value; - data = abi.encodeCall(CallReceiverMock.mockFunctionRevertsNoReason, ()); - } - - batchRequestDatas[i] = _forgeRequestData({ - value: value, - nonce: nonce + i, - deadline: uint48(block.timestamp + 1), - data: data - }); - } - - address payable refundReceiver = payable(address(0xebe)); - uint256 totalValue = value * batchSize; - - vm.deal(address(this), totalValue); - _erc2771Forwarder.executeBatch{value: totalValue}(batchRequestDatas, refundReceiver); - - assertEq(address(_erc2771Forwarder).balance, initialBalance); - assertEq(refundReceiver.balance, expectedRefund); - } -} diff --git a/lib/openzeppelin-contracts/test/metatx/ERC2771Forwarder.test.js b/lib/openzeppelin-contracts/test/metatx/ERC2771Forwarder.test.js deleted file mode 100644 index 8653ad7..0000000 --- a/lib/openzeppelin-contracts/test/metatx/ERC2771Forwarder.test.js +++ /dev/null @@ -1,461 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { getDomain, ForwardRequest } = require('../helpers/eip712'); -const { sum } = require('../helpers/math'); -const time = require('../helpers/time'); - -async function fixture() { - const [sender, refundReceiver, another, ...accounts] = await ethers.getSigners(); - - const forwarder = await ethers.deployContract('ERC2771Forwarder', ['ERC2771Forwarder']); - const receiver = await ethers.deployContract('CallReceiverMockTrustingForwarder', [forwarder]); - const domain = await getDomain(forwarder); - const types = { ForwardRequest }; - - const forgeRequest = async (override = {}, signer = sender) => { - const req = { - from: await signer.getAddress(), - to: await receiver.getAddress(), - value: 0n, - data: receiver.interface.encodeFunctionData('mockFunction'), - gas: 100000n, - deadline: (await time.clock.timestamp()) + 60n, - nonce: await forwarder.nonces(sender), - ...override, - }; - req.signature = await signer.signTypedData(domain, types, req); - return req; - }; - - const estimateRequest = request => - ethers.provider.estimateGas({ - from: forwarder, - to: request.to, - data: ethers.solidityPacked(['bytes', 'address'], [request.data, request.from]), - value: request.value, - gasLimit: request.gas, - }); - - return { - sender, - refundReceiver, - another, - accounts, - forwarder, - receiver, - forgeRequest, - estimateRequest, - domain, - types, - }; -} - -// values or function to tamper with a signed request. -const tamperedValues = { - from: ethers.Wallet.createRandom().address, - to: ethers.Wallet.createRandom().address, - value: ethers.parseEther('0.5'), - data: '0x1742', - signature: s => { - const t = ethers.toBeArray(s); - t[42] ^= 0xff; - return ethers.hexlify(t); - }, -}; - -describe('ERC2771Forwarder', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('verify', function () { - describe('with valid signature', function () { - it('returns true without altering the nonce', async function () { - const request = await this.forgeRequest(); - expect(await this.forwarder.nonces(request.from)).to.equal(request.nonce); - expect(await this.forwarder.verify(request)).to.be.true; - expect(await this.forwarder.nonces(request.from)).to.equal(request.nonce); - }); - }); - - describe('with tampered values', function () { - for (const [key, value] of Object.entries(tamperedValues)) { - it(`returns false with tampered ${key}`, async function () { - const request = await this.forgeRequest(); - request[key] = typeof value == 'function' ? value(request[key]) : value; - - expect(await this.forwarder.verify(request)).to.be.false; - }); - } - - it('returns false with valid signature for non-current nonce', async function () { - const request = await this.forgeRequest({ nonce: 1337n }); - expect(await this.forwarder.verify(request)).to.be.false; - }); - - it('returns false with valid signature for expired deadline', async function () { - const request = await this.forgeRequest({ deadline: (await time.clock.timestamp()) - 1n }); - expect(await this.forwarder.verify(request)).to.be.false; - }); - }); - }); - - describe('execute', function () { - describe('with valid requests', function () { - it('emits an event and consumes nonce for a successful request', async function () { - const request = await this.forgeRequest(); - - expect(await this.forwarder.nonces(request.from)).to.equal(request.nonce); - - await expect(this.forwarder.execute(request)) - .to.emit(this.receiver, 'MockFunctionCalled') - .to.emit(this.forwarder, 'ExecutedForwardRequest') - .withArgs(request.from, request.nonce, true); - - expect(await this.forwarder.nonces(request.from)).to.equal(request.nonce + 1n); - }); - - it('reverts with an unsuccessful request', async function () { - const request = await this.forgeRequest({ - data: this.receiver.interface.encodeFunctionData('mockFunctionRevertsNoReason'), - }); - - await expect(this.forwarder.execute(request)).to.be.revertedWithCustomError(this.forwarder, 'FailedCall'); - }); - }); - - describe('with tampered request', function () { - for (const [key, value] of Object.entries(tamperedValues)) { - it(`reverts with tampered ${key}`, async function () { - const request = await this.forgeRequest(); - request[key] = typeof value == 'function' ? value(request[key]) : value; - - const promise = this.forwarder.execute(request, { value: key == 'value' ? value : 0 }); - if (key != 'to') { - await expect(promise) - .to.be.revertedWithCustomError(this.forwarder, 'ERC2771ForwarderInvalidSigner') - .withArgs(ethers.verifyTypedData(this.domain, this.types, request, request.signature), request.from); - } else { - await expect(promise) - .to.be.revertedWithCustomError(this.forwarder, 'ERC2771UntrustfulTarget') - .withArgs(request.to, this.forwarder); - } - }); - } - - it('reverts with valid signature for non-current nonce', async function () { - const request = await this.forgeRequest(); - - // consume nonce - await this.forwarder.execute(request); - - // nonce has changed - await expect(this.forwarder.execute(request)) - .to.be.revertedWithCustomError(this.forwarder, 'ERC2771ForwarderInvalidSigner') - .withArgs( - ethers.verifyTypedData( - this.domain, - this.types, - { ...request, nonce: request.nonce + 1n }, - request.signature, - ), - request.from, - ); - }); - - it('reverts with valid signature for expired deadline', async function () { - const request = await this.forgeRequest({ deadline: (await time.clock.timestamp()) - 1n }); - - await expect(this.forwarder.execute(request)) - .to.be.revertedWithCustomError(this.forwarder, 'ERC2771ForwarderExpiredRequest') - .withArgs(request.deadline); - }); - - it('reverts with valid signature but mismatched value', async function () { - const request = await this.forgeRequest({ value: 100n }); - - await expect(this.forwarder.execute(request)) - .to.be.revertedWithCustomError(this.forwarder, 'ERC2771ForwarderMismatchedValue') - .withArgs(request.value, 0n); - }); - }); - - it('bubbles out of gas', async function () { - const request = await this.forgeRequest({ - data: this.receiver.interface.encodeFunctionData('mockFunctionOutOfGas'), - gas: 1_000_000n, - }); - - const gasLimit = 100_000n; - await expect(this.forwarder.execute(request, { gasLimit })).to.be.revertedWithoutReason(); - - const { gasUsed } = await ethers.provider - .getBlock('latest') - .then(block => block.getTransaction(0)) - .then(tx => ethers.provider.getTransactionReceipt(tx.hash)); - - expect(gasUsed).to.equal(gasLimit); - }); - - it('bubbles out of gas forced by the relayer', async function () { - const request = await this.forgeRequest(); - - // If there's an incentive behind executing requests, a malicious relayer could grief - // the forwarder by executing requests and providing a top-level call gas limit that - // is too low to successfully finish the request after the 63/64 rule. - - // We set the baseline to the gas limit consumed by a successful request if it was executed - // normally. Note this includes the 21000 buffer that also the relayer will be charged to - // start a request execution. - const estimate = await this.estimateRequest(request); - - // Because the relayer call consumes gas until the `CALL` opcode, the gas left after failing - // the subcall won't enough to finish the top level call (after testing), so we add a - // moderated buffer. - const gasLimit = estimate + 2_000n; - - // The subcall out of gas should be caught by the contract and then bubbled up consuming - // the available gas with an `invalid` opcode. - await expect(this.forwarder.execute(request, { gasLimit })).to.be.revertedWithoutReason(); - - const { gasUsed } = await ethers.provider - .getBlock('latest') - .then(block => block.getTransaction(0)) - .then(tx => ethers.provider.getTransactionReceipt(tx.hash)); - - // We assert that indeed the gas was totally consumed. - expect(gasUsed).to.equal(gasLimit); - }); - }); - - describe('executeBatch', function () { - const requestsValue = requests => sum(...requests.map(request => request.value)); - const requestCount = 3; - const idx = 1; // index that will be tampered with - - beforeEach(async function () { - this.forgeRequests = override => - Promise.all(this.accounts.slice(0, requestCount).map(signer => this.forgeRequest(override, signer))); - this.requests = await this.forgeRequests({ value: 10n }); - this.value = requestsValue(this.requests); - }); - - describe('with valid requests', function () { - it('sanity', async function () { - for (const request of this.requests) { - expect(await this.forwarder.verify(request)).to.be.true; - } - }); - - it('emits events', async function () { - const receipt = this.forwarder.executeBatch(this.requests, this.another, { value: this.value }); - - for (const request of this.requests) { - await expect(receipt) - .to.emit(this.receiver, 'MockFunctionCalled') - .to.emit(this.forwarder, 'ExecutedForwardRequest') - .withArgs(request.from, request.nonce, true); - } - }); - - it('increase nonces', async function () { - await this.forwarder.executeBatch(this.requests, this.another, { value: this.value }); - - for (const request of this.requests) { - expect(await this.forwarder.nonces(request.from)).to.equal(request.nonce + 1n); - } - }); - }); - - describe('with tampered requests', function () { - it('reverts with mismatched value', async function () { - // tamper value of one of the request + resign - this.requests[idx] = await this.forgeRequest({ value: 100n }, this.accounts[1]); - - await expect(this.forwarder.executeBatch(this.requests, this.another, { value: this.value })) - .to.be.revertedWithCustomError(this.forwarder, 'ERC2771ForwarderMismatchedValue') - .withArgs(requestsValue(this.requests), this.value); - }); - - describe('when the refund receiver is the zero address', function () { - beforeEach(function () { - this.refundReceiver = ethers.ZeroAddress; - }); - - for (const [key, value] of Object.entries(tamperedValues)) { - it(`reverts with at least one tampered request ${key}`, async function () { - this.requests[idx][key] = typeof value == 'function' ? value(this.requests[idx][key]) : value; - - const promise = this.forwarder.executeBatch(this.requests, this.refundReceiver, { value: this.value }); - if (key != 'to') { - await expect(promise) - .to.be.revertedWithCustomError(this.forwarder, 'ERC2771ForwarderInvalidSigner') - .withArgs( - ethers.verifyTypedData(this.domain, this.types, this.requests[idx], this.requests[idx].signature), - this.requests[idx].from, - ); - } else { - await expect(promise) - .to.be.revertedWithCustomError(this.forwarder, 'ERC2771UntrustfulTarget') - .withArgs(this.requests[idx].to, this.forwarder); - } - }); - } - - it('reverts with at least one valid signature for non-current nonce', async function () { - // Execute first a request - await this.forwarder.execute(this.requests[idx], { value: this.requests[idx].value }); - - // And then fail due to an already used nonce - await expect(this.forwarder.executeBatch(this.requests, this.refundReceiver, { value: this.value })) - .to.be.revertedWithCustomError(this.forwarder, 'ERC2771ForwarderInvalidSigner') - .withArgs( - ethers.verifyTypedData( - this.domain, - this.types, - { ...this.requests[idx], nonce: this.requests[idx].nonce + 1n }, - this.requests[idx].signature, - ), - this.requests[idx].from, - ); - }); - - it('reverts with at least one valid signature for expired deadline', async function () { - this.requests[idx] = await this.forgeRequest( - { ...this.requests[idx], deadline: (await time.clock.timestamp()) - 1n }, - this.accounts[1], - ); - - await expect(this.forwarder.executeBatch(this.requests, this.refundReceiver, { value: this.amount })) - .to.be.revertedWithCustomError(this.forwarder, 'ERC2771ForwarderExpiredRequest') - .withArgs(this.requests[idx].deadline); - }); - }); - - describe('when the refund receiver is a known address', function () { - beforeEach(async function () { - this.initialRefundReceiverBalance = await ethers.provider.getBalance(this.refundReceiver); - this.initialTamperedRequestNonce = await this.forwarder.nonces(this.requests[idx].from); - }); - - for (const [key, value] of Object.entries(tamperedValues)) { - it(`ignores a request with tampered ${key} and refunds its value`, async function () { - this.requests[idx][key] = typeof value == 'function' ? value(this.requests[idx][key]) : value; - - const events = await this.forwarder - .executeBatch(this.requests, this.refundReceiver, { value: requestsValue(this.requests) }) - .then(tx => tx.wait()) - .then(receipt => - receipt.logs.filter( - log => log?.fragment?.type == 'event' && log?.fragment?.name == 'ExecutedForwardRequest', - ), - ); - - expect(events).to.have.lengthOf(this.requests.length - 1); - }); - } - - it('ignores a request with a valid signature for non-current nonce', async function () { - // Execute first a request - await this.forwarder.execute(this.requests[idx], { value: this.requests[idx].value }); - this.initialTamperedRequestNonce++; // Should be already incremented by the individual `execute` - - // And then ignore the same request in a batch due to an already used nonce - const events = await this.forwarder - .executeBatch(this.requests, this.refundReceiver, { value: this.value }) - .then(tx => tx.wait()) - .then(receipt => - receipt.logs.filter( - log => log?.fragment?.type == 'event' && log?.fragment?.name == 'ExecutedForwardRequest', - ), - ); - - expect(events).to.have.lengthOf(this.requests.length - 1); - }); - - it('ignores a request with a valid signature for expired deadline', async function () { - this.requests[idx] = await this.forgeRequest( - { ...this.requests[idx], deadline: (await time.clock.timestamp()) - 1n }, - this.accounts[1], - ); - - const events = await this.forwarder - .executeBatch(this.requests, this.refundReceiver, { value: this.value }) - .then(tx => tx.wait()) - .then(receipt => - receipt.logs.filter( - log => log?.fragment?.type == 'event' && log?.fragment?.name == 'ExecutedForwardRequest', - ), - ); - - expect(events).to.have.lengthOf(this.requests.length - 1); - }); - - afterEach(async function () { - // The invalid request value was refunded - expect(await ethers.provider.getBalance(this.refundReceiver)).to.equal( - this.initialRefundReceiverBalance + this.requests[idx].value, - ); - - // The invalid request from's nonce was not incremented - expect(await this.forwarder.nonces(this.requests[idx].from)).to.equal(this.initialTamperedRequestNonce); - }); - }); - - it('bubbles out of gas', async function () { - this.requests[idx] = await this.forgeRequest({ - data: this.receiver.interface.encodeFunctionData('mockFunctionOutOfGas'), - gas: 1_000_000n, - }); - - const gasLimit = 300_000n; - await expect( - this.forwarder.executeBatch(this.requests, ethers.ZeroAddress, { - gasLimit, - value: requestsValue(this.requests), - }), - ).to.be.revertedWithoutReason(); - - const { gasUsed } = await ethers.provider - .getBlock('latest') - .then(block => block.getTransaction(0)) - .then(tx => ethers.provider.getTransactionReceipt(tx.hash)); - - expect(gasUsed).to.equal(gasLimit); - }); - - it('bubbles out of gas forced by the relayer', async function () { - // Similarly to the single execute, a malicious relayer could grief requests. - - // We estimate until the selected request as if they were executed normally - const estimate = await Promise.all(this.requests.slice(0, idx + 1).map(this.estimateRequest)).then(gas => - sum(...gas), - ); - - // We add a Buffer to account for all the gas that's used before the selected call. - // Note is slightly bigger because the selected request is not the index 0 and it affects - // the buffer needed. - const gasLimit = estimate + 10_000n; - - // The subcall out of gas should be caught by the contract and then bubbled up consuming - // the available gas with an `invalid` opcode. - await expect( - this.forwarder.executeBatch(this.requests, ethers.ZeroAddress, { - gasLimit, - value: requestsValue(this.requests), - }), - ).to.be.revertedWithoutReason(); - - const { gasUsed } = await ethers.provider - .getBlock('latest') - .then(block => block.getTransaction(0)) - .then(tx => ethers.provider.getTransactionReceipt(tx.hash)); - - // We assert that indeed the gas was totally consumed. - expect(gasUsed).to.equal(gasLimit); - }); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/proxy/Clones.behaviour.js b/lib/openzeppelin-contracts/test/proxy/Clones.behaviour.js deleted file mode 100644 index dcc6206..0000000 --- a/lib/openzeppelin-contracts/test/proxy/Clones.behaviour.js +++ /dev/null @@ -1,160 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); - -module.exports = function shouldBehaveLikeClone() { - const assertProxyInitialization = function ({ value, balance }) { - it('initializes the proxy', async function () { - const dummy = await ethers.getContractAt('DummyImplementation', this.proxy); - expect(await dummy.value()).to.equal(value); - }); - - it('has expected balance', async function () { - expect(await ethers.provider.getBalance(this.proxy)).to.equal(balance); - }); - }; - - describe('construct with value', function () { - const value = 10n; - - it('factory has enough balance', async function () { - await this.deployer.sendTransaction({ to: this.factory, value }); - - const instance = await this.createClone({ deployValue: value }); - await expect(instance.deploymentTransaction()).to.changeEtherBalances([this.factory, instance], [-value, value]); - - expect(await ethers.provider.getBalance(instance)).to.equal(value); - }); - - it('factory does not have enough balance', async function () { - await expect(this.createClone({ deployValue: value })) - .to.be.revertedWithCustomError(this.factory, 'InsufficientBalance') - .withArgs(0n, value); - }); - }); - - describe('initialization without parameters', function () { - describe('non payable', function () { - const expectedInitializedValue = 10n; - - beforeEach(async function () { - this.initializeData = await this.implementation.interface.encodeFunctionData('initializeNonPayable'); - }); - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = await this.createClone({ initData: this.initializeData }); - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: 0, - }); - }); - - describe('when sending some balance', function () { - const value = 10n ** 6n; - - it('reverts', async function () { - await expect(this.createClone({ initData: this.initializeData, initValue: value })).to.be.reverted; - }); - }); - }); - - describe('payable', function () { - const expectedInitializedValue = 100n; - - beforeEach(async function () { - this.initializeData = await this.implementation.interface.encodeFunctionData('initializePayable'); - }); - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = await this.createClone({ initData: this.initializeData }); - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: 0, - }); - }); - - describe('when sending some balance', function () { - const value = 10n ** 6n; - - beforeEach('creating proxy', async function () { - this.proxy = await this.createClone({ initData: this.initializeData, initValue: value }); - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: value, - }); - }); - }); - }); - - describe('initialization with parameters', function () { - describe('non payable', function () { - const expectedInitializedValue = 10n; - - beforeEach(async function () { - this.initializeData = await this.implementation.interface.encodeFunctionData('initializeNonPayableWithValue', [ - expectedInitializedValue, - ]); - }); - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = await this.createClone({ initData: this.initializeData }); - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: 0, - }); - }); - - describe('when sending some balance', function () { - const value = 10n ** 6n; - - it('reverts', async function () { - await expect(this.createClone({ initData: this.initializeData, initValue: value })).to.be.reverted; - }); - }); - }); - - describe('payable', function () { - const expectedInitializedValue = 42n; - - beforeEach(function () { - this.initializeData = this.implementation.interface.encodeFunctionData('initializePayableWithValue', [ - expectedInitializedValue, - ]); - }); - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = await this.createClone({ initData: this.initializeData }); - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: 0, - }); - }); - - describe('when sending some balance', function () { - const value = 10n ** 6n; - - beforeEach('creating proxy', async function () { - this.proxy = await this.createClone({ initData: this.initializeData, initValue: value }); - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: value, - }); - }); - }); - }); -}; diff --git a/lib/openzeppelin-contracts/test/proxy/Clones.t.sol b/lib/openzeppelin-contracts/test/proxy/Clones.t.sol deleted file mode 100644 index 4301e10..0000000 --- a/lib/openzeppelin-contracts/test/proxy/Clones.t.sol +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {Test} from "forge-std/Test.sol"; -import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol"; - -contract ClonesTest is Test { - function getNumber() external pure returns (uint256) { - return 42; - } - - function testSymbolicPredictDeterministicAddressSpillage(address implementation, bytes32 salt) public { - address predicted = Clones.predictDeterministicAddress(implementation, salt); - bytes32 spillage; - /// @solidity memory-safe-assembly - assembly { - spillage := and(predicted, 0xffffffffffffffffffffffff0000000000000000000000000000000000000000) - } - assertEq(spillage, bytes32(0)); - } - - function testCloneDirty() external { - address cloneClean = Clones.clone(address(this)); - address cloneDirty = Clones.clone(_dirty(address(this))); - - // both clones have the same code - assertEq(keccak256(cloneClean.code), keccak256(cloneDirty.code)); - - // both clones behave as expected - assertEq(ClonesTest(cloneClean).getNumber(), this.getNumber()); - assertEq(ClonesTest(cloneDirty).getNumber(), this.getNumber()); - } - - function testCloneDeterministicDirty(bytes32 salt) external { - address cloneClean = Clones.cloneDeterministic(address(this), salt); - address cloneDirty = Clones.cloneDeterministic(_dirty(address(this)), ~salt); - - // both clones have the same code - assertEq(keccak256(cloneClean.code), keccak256(cloneDirty.code)); - - // both clones behave as expected - assertEq(ClonesTest(cloneClean).getNumber(), this.getNumber()); - assertEq(ClonesTest(cloneDirty).getNumber(), this.getNumber()); - } - - function testPredictDeterministicAddressDirty(bytes32 salt) external { - address predictClean = Clones.predictDeterministicAddress(address(this), salt); - address predictDirty = Clones.predictDeterministicAddress(_dirty(address(this)), salt); - - //prediction should be similar - assertEq(predictClean, predictDirty); - } - - function _dirty(address input) private pure returns (address output) { - assembly ("memory-safe") { - output := or(input, shl(160, not(0))) - } - } -} diff --git a/lib/openzeppelin-contracts/test/proxy/Clones.test.js b/lib/openzeppelin-contracts/test/proxy/Clones.test.js deleted file mode 100644 index 70220fb..0000000 --- a/lib/openzeppelin-contracts/test/proxy/Clones.test.js +++ /dev/null @@ -1,95 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const shouldBehaveLikeClone = require('./Clones.behaviour'); - -async function fixture() { - const [deployer] = await ethers.getSigners(); - - const factory = await ethers.deployContract('$Clones'); - const implementation = await ethers.deployContract('DummyImplementation'); - - const newClone = async (opts = {}) => { - const clone = await factory.$clone.staticCall(implementation).then(address => implementation.attach(address)); - const tx = await (opts.deployValue - ? factory.$clone(implementation, ethers.Typed.uint256(opts.deployValue)) - : factory.$clone(implementation)); - if (opts.initData || opts.initValue) { - await deployer.sendTransaction({ to: clone, value: opts.initValue ?? 0n, data: opts.initData ?? '0x' }); - } - return Object.assign(clone, { deploymentTransaction: () => tx }); - }; - - const newCloneDeterministic = async (opts = {}) => { - const salt = opts.salt ?? ethers.randomBytes(32); - const clone = await factory.$cloneDeterministic - .staticCall(implementation, salt) - .then(address => implementation.attach(address)); - const tx = await (opts.deployValue - ? factory.$cloneDeterministic(implementation, salt, ethers.Typed.uint256(opts.deployValue)) - : factory.$cloneDeterministic(implementation, salt)); - if (opts.initData || opts.initValue) { - await deployer.sendTransaction({ to: clone, value: opts.initValue ?? 0n, data: opts.initData ?? '0x' }); - } - return Object.assign(clone, { deploymentTransaction: () => tx }); - }; - - return { deployer, factory, implementation, newClone, newCloneDeterministic }; -} - -describe('Clones', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('clone', function () { - beforeEach(async function () { - this.createClone = this.newClone; - }); - - shouldBehaveLikeClone(); - }); - - describe('cloneDeterministic', function () { - beforeEach(async function () { - this.createClone = this.newCloneDeterministic; - }); - - shouldBehaveLikeClone(); - - it('revert if address already used', async function () { - const salt = ethers.randomBytes(32); - - // deploy once - await expect(this.factory.$cloneDeterministic(this.implementation, salt)).to.emit( - this.factory, - 'return$cloneDeterministic_address_bytes32', - ); - - // deploy twice - await expect(this.factory.$cloneDeterministic(this.implementation, salt)).to.be.revertedWithCustomError( - this.factory, - 'FailedDeployment', - ); - }); - - it('address prediction', async function () { - const salt = ethers.randomBytes(32); - - const creationCode = ethers.concat([ - '0x3d602d80600a3d3981f3363d3d373d3d3d363d73', - this.implementation.target, - '0x5af43d82803e903d91602b57fd5bf3', - ]); - - const predicted = await this.factory.$predictDeterministicAddress(this.implementation, salt); - const expected = ethers.getCreate2Address(this.factory.target, salt, ethers.keccak256(creationCode)); - expect(predicted).to.equal(expected); - - await expect(this.factory.$cloneDeterministic(this.implementation, salt)) - .to.emit(this.factory, 'return$cloneDeterministic_address_bytes32') - .withArgs(predicted); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/proxy/ERC1967/ERC1967Proxy.test.js b/lib/openzeppelin-contracts/test/proxy/ERC1967/ERC1967Proxy.test.js deleted file mode 100644 index b222800..0000000 --- a/lib/openzeppelin-contracts/test/proxy/ERC1967/ERC1967Proxy.test.js +++ /dev/null @@ -1,23 +0,0 @@ -const { ethers } = require('hardhat'); - -const shouldBehaveLikeProxy = require('../Proxy.behaviour'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const fixture = async () => { - const [nonContractAddress] = await ethers.getSigners(); - - const implementation = await ethers.deployContract('DummyImplementation'); - - const createProxy = (implementation, initData, opts) => - ethers.deployContract('ERC1967Proxy', [implementation, initData], opts); - - return { nonContractAddress, implementation, createProxy }; -}; - -describe('ERC1967Proxy', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - shouldBehaveLikeProxy(); -}); diff --git a/lib/openzeppelin-contracts/test/proxy/ERC1967/ERC1967Utils.test.js b/lib/openzeppelin-contracts/test/proxy/ERC1967/ERC1967Utils.test.js deleted file mode 100644 index 0890324..0000000 --- a/lib/openzeppelin-contracts/test/proxy/ERC1967/ERC1967Utils.test.js +++ /dev/null @@ -1,162 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { getAddressInSlot, setSlot, ImplementationSlot, AdminSlot, BeaconSlot } = require('../../helpers/storage'); - -async function fixture() { - const [, admin, anotherAccount] = await ethers.getSigners(); - - const utils = await ethers.deployContract('$ERC1967Utils'); - const v1 = await ethers.deployContract('DummyImplementation'); - const v2 = await ethers.deployContract('CallReceiverMock'); - - return { admin, anotherAccount, utils, v1, v2 }; -} - -describe('ERC1967Utils', function () { - beforeEach('setup', async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('IMPLEMENTATION_SLOT', function () { - beforeEach('set v1 implementation', async function () { - await setSlot(this.utils, ImplementationSlot, this.v1); - }); - - describe('getImplementation', function () { - it('returns current implementation and matches implementation slot value', async function () { - expect(await this.utils.$getImplementation()).to.equal(this.v1); - expect(await getAddressInSlot(this.utils, ImplementationSlot)).to.equal(this.v1); - }); - }); - - describe('upgradeToAndCall', function () { - it('sets implementation in storage and emits event', async function () { - const newImplementation = this.v2; - const tx = await this.utils.$upgradeToAndCall(newImplementation, '0x'); - - expect(await getAddressInSlot(this.utils, ImplementationSlot)).to.equal(newImplementation); - await expect(tx).to.emit(this.utils, 'Upgraded').withArgs(newImplementation); - }); - - it('reverts when implementation does not contain code', async function () { - await expect(this.utils.$upgradeToAndCall(this.anotherAccount, '0x')) - .to.be.revertedWithCustomError(this.utils, 'ERC1967InvalidImplementation') - .withArgs(this.anotherAccount); - }); - - describe('when data is empty', function () { - it('reverts when value is sent', async function () { - await expect(this.utils.$upgradeToAndCall(this.v2, '0x', { value: 1 })).to.be.revertedWithCustomError( - this.utils, - 'ERC1967NonPayable', - ); - }); - }); - - describe('when data is not empty', function () { - it('delegates a call to the new implementation', async function () { - const initializeData = this.v2.interface.encodeFunctionData('mockFunction'); - const tx = await this.utils.$upgradeToAndCall(this.v2, initializeData); - await expect(tx).to.emit(await ethers.getContractAt('CallReceiverMock', this.utils), 'MockFunctionCalled'); - }); - }); - }); - }); - - describe('ADMIN_SLOT', function () { - beforeEach('set admin', async function () { - await setSlot(this.utils, AdminSlot, this.admin); - }); - - describe('getAdmin', function () { - it('returns current admin and matches admin slot value', async function () { - expect(await this.utils.$getAdmin()).to.equal(this.admin); - expect(await getAddressInSlot(this.utils, AdminSlot)).to.equal(this.admin); - }); - }); - - describe('changeAdmin', function () { - it('sets admin in storage and emits event', async function () { - const newAdmin = this.anotherAccount; - const tx = await this.utils.$changeAdmin(newAdmin); - - expect(await getAddressInSlot(this.utils, AdminSlot)).to.equal(newAdmin); - await expect(tx).to.emit(this.utils, 'AdminChanged').withArgs(this.admin, newAdmin); - }); - - it('reverts when setting the address zero as admin', async function () { - await expect(this.utils.$changeAdmin(ethers.ZeroAddress)) - .to.be.revertedWithCustomError(this.utils, 'ERC1967InvalidAdmin') - .withArgs(ethers.ZeroAddress); - }); - }); - }); - - describe('BEACON_SLOT', function () { - beforeEach('set beacon', async function () { - this.beacon = await ethers.deployContract('UpgradeableBeaconMock', [this.v1]); - await setSlot(this.utils, BeaconSlot, this.beacon); - }); - - describe('getBeacon', function () { - it('returns current beacon and matches beacon slot value', async function () { - expect(await this.utils.$getBeacon()).to.equal(this.beacon); - expect(await getAddressInSlot(this.utils, BeaconSlot)).to.equal(this.beacon); - }); - }); - - describe('upgradeBeaconToAndCall', function () { - it('sets beacon in storage and emits event', async function () { - const newBeacon = await ethers.deployContract('UpgradeableBeaconMock', [this.v2]); - const tx = await this.utils.$upgradeBeaconToAndCall(newBeacon, '0x'); - - expect(await getAddressInSlot(this.utils, BeaconSlot)).to.equal(newBeacon); - await expect(tx).to.emit(this.utils, 'BeaconUpgraded').withArgs(newBeacon); - }); - - it('reverts when beacon does not contain code', async function () { - await expect(this.utils.$upgradeBeaconToAndCall(this.anotherAccount, '0x')) - .to.be.revertedWithCustomError(this.utils, 'ERC1967InvalidBeacon') - .withArgs(this.anotherAccount); - }); - - it("reverts when beacon's implementation does not contain code", async function () { - const newBeacon = await ethers.deployContract('UpgradeableBeaconMock', [this.anotherAccount]); - - await expect(this.utils.$upgradeBeaconToAndCall(newBeacon, '0x')) - .to.be.revertedWithCustomError(this.utils, 'ERC1967InvalidImplementation') - .withArgs(this.anotherAccount); - }); - - describe('when data is empty', function () { - it('reverts when value is sent', async function () { - const newBeacon = await ethers.deployContract('UpgradeableBeaconMock', [this.v2]); - await expect(this.utils.$upgradeBeaconToAndCall(newBeacon, '0x', { value: 1 })).to.be.revertedWithCustomError( - this.utils, - 'ERC1967NonPayable', - ); - }); - }); - - describe('when data is not empty', function () { - it('delegates a call to the new implementation', async function () { - const initializeData = this.v2.interface.encodeFunctionData('mockFunction'); - const newBeacon = await ethers.deployContract('UpgradeableBeaconMock', [this.v2]); - const tx = await this.utils.$upgradeBeaconToAndCall(newBeacon, initializeData); - await expect(tx).to.emit(await ethers.getContractAt('CallReceiverMock', this.utils), 'MockFunctionCalled'); - }); - }); - - describe('reentrant beacon implementation() call', function () { - it('sees the new beacon implementation', async function () { - const newBeacon = await ethers.deployContract('UpgradeableBeaconReentrantMock'); - await expect(this.utils.$upgradeBeaconToAndCall(newBeacon, '0x')) - .to.be.revertedWithCustomError(newBeacon, 'BeaconProxyBeaconSlotAddress') - .withArgs(newBeacon); - }); - }); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/proxy/Proxy.behaviour.js b/lib/openzeppelin-contracts/test/proxy/Proxy.behaviour.js deleted file mode 100644 index f459c09..0000000 --- a/lib/openzeppelin-contracts/test/proxy/Proxy.behaviour.js +++ /dev/null @@ -1,185 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); - -const { getAddressInSlot, ImplementationSlot } = require('../helpers/storage'); - -module.exports = function shouldBehaveLikeProxy() { - it('cannot be initialized with a non-contract address', async function () { - const initializeData = '0x'; - const contractFactory = await ethers.getContractFactory('ERC1967Proxy'); - await expect(this.createProxy(this.nonContractAddress, initializeData)) - .to.be.revertedWithCustomError(contractFactory, 'ERC1967InvalidImplementation') - .withArgs(this.nonContractAddress); - }); - - const assertProxyInitialization = function ({ value, balance }) { - it('sets the implementation address', async function () { - expect(await getAddressInSlot(this.proxy, ImplementationSlot)).to.equal(this.implementation); - }); - - it('initializes the proxy', async function () { - const dummy = this.implementation.attach(this.proxy); - expect(await dummy.value()).to.equal(value); - }); - - it('has expected balance', async function () { - expect(await ethers.provider.getBalance(this.proxy)).to.equal(balance); - }); - }; - - describe('without initialization', function () { - const initializeData = '0x'; - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = await this.createProxy(this.implementation, initializeData); - }); - - assertProxyInitialization({ value: 0n, balance: 0n }); - }); - - describe('when sending some balance', function () { - const value = 10n ** 5n; - - it('reverts', async function () { - await expect(this.createProxy(this.implementation, initializeData, { value })).to.be.reverted; - }); - }); - }); - - describe('initialization without parameters', function () { - describe('non payable', function () { - const expectedInitializedValue = 10n; - - beforeEach(function () { - this.initializeData = this.implementation.interface.encodeFunctionData('initializeNonPayable'); - }); - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = await this.createProxy(this.implementation, this.initializeData); - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: 0n, - }); - }); - - describe('when sending some balance', function () { - const value = 10n ** 5n; - - it('reverts', async function () { - await expect(this.createProxy(this.implementation, this.initializeData, { value })).to.be.reverted; - }); - }); - }); - - describe('payable', function () { - const expectedInitializedValue = 100n; - - beforeEach(function () { - this.initializeData = this.implementation.interface.encodeFunctionData('initializePayable'); - }); - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = await this.createProxy(this.implementation, this.initializeData); - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: 0n, - }); - }); - - describe('when sending some balance', function () { - const value = 10e5; - - beforeEach('creating proxy', async function () { - this.proxy = await this.createProxy(this.implementation, this.initializeData, { value }); - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: value, - }); - }); - }); - }); - - describe('initialization with parameters', function () { - describe('non payable', function () { - const expectedInitializedValue = 10n; - - beforeEach(function () { - this.initializeData = this.implementation.interface.encodeFunctionData('initializeNonPayableWithValue', [ - expectedInitializedValue, - ]); - }); - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = await this.createProxy(this.implementation, this.initializeData); - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: 0, - }); - }); - - describe('when sending some balance', function () { - const value = 10e5; - - it('reverts', async function () { - await expect(this.createProxy(this.implementation, this.initializeData, { value })).to.be.reverted; - }); - }); - }); - - describe('payable', function () { - const expectedInitializedValue = 42n; - - beforeEach(function () { - this.initializeData = this.implementation.interface.encodeFunctionData('initializePayableWithValue', [ - expectedInitializedValue, - ]); - }); - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = await this.createProxy(this.implementation, this.initializeData); - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: 0n, - }); - }); - - describe('when sending some balance', function () { - const value = 10n ** 5n; - - beforeEach('creating proxy', async function () { - this.proxy = await this.createProxy(this.implementation, this.initializeData, { value }); - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: value, - }); - }); - }); - - describe('reverting initialization', function () { - beforeEach(function () { - this.initializeData = this.implementation.interface.encodeFunctionData('reverts'); - }); - - it('reverts', async function () { - await expect(this.createProxy(this.implementation, this.initializeData)).to.be.reverted; - }); - }); - }); -}; diff --git a/lib/openzeppelin-contracts/test/proxy/beacon/BeaconProxy.test.js b/lib/openzeppelin-contracts/test/proxy/beacon/BeaconProxy.test.js deleted file mode 100644 index 0a08784..0000000 --- a/lib/openzeppelin-contracts/test/proxy/beacon/BeaconProxy.test.js +++ /dev/null @@ -1,141 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { getAddressInSlot, BeaconSlot } = require('../../helpers/storage'); - -async function fixture() { - const [admin, other] = await ethers.getSigners(); - - const v1 = await ethers.deployContract('DummyImplementation'); - const v2 = await ethers.deployContract('DummyImplementationV2'); - const factory = await ethers.getContractFactory('BeaconProxy'); - const beacon = await ethers.deployContract('UpgradeableBeacon', [v1, admin]); - - const newBeaconProxy = (beacon, data, opts = {}) => factory.deploy(beacon, data, opts); - - return { admin, other, factory, beacon, v1, v2, newBeaconProxy }; -} - -describe('BeaconProxy', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('bad beacon is not accepted', function () { - it('non-contract beacon', async function () { - const notBeacon = this.other; - - await expect(this.newBeaconProxy(notBeacon, '0x')) - .to.be.revertedWithCustomError(this.factory, 'ERC1967InvalidBeacon') - .withArgs(notBeacon); - }); - - it('non-compliant beacon', async function () { - const badBeacon = await ethers.deployContract('BadBeaconNoImpl'); - - // BadBeaconNoImpl does not provide `implementation()` has no fallback. - // This causes ERC1967Utils._setBeacon to revert. - await expect(this.newBeaconProxy(badBeacon, '0x')).to.be.revertedWithoutReason(); - }); - - it('non-contract implementation', async function () { - const badBeacon = await ethers.deployContract('BadBeaconNotContract'); - - await expect(this.newBeaconProxy(badBeacon, '0x')) - .to.be.revertedWithCustomError(this.factory, 'ERC1967InvalidImplementation') - .withArgs(await badBeacon.implementation()); - }); - }); - - describe('initialization', function () { - async function assertInitialized({ value, balance }) { - const beaconAddress = await getAddressInSlot(this.proxy, BeaconSlot); - expect(beaconAddress).to.equal(this.beacon); - - const dummy = this.v1.attach(this.proxy); - expect(await dummy.value()).to.equal(value); - - expect(await ethers.provider.getBalance(this.proxy)).to.equal(balance); - } - - it('no initialization', async function () { - this.proxy = await this.newBeaconProxy(this.beacon, '0x'); - await assertInitialized.bind(this)({ value: 0n, balance: 0n }); - }); - - it('non-payable initialization', async function () { - const value = 55n; - const data = this.v1.interface.encodeFunctionData('initializeNonPayableWithValue', [value]); - - this.proxy = await this.newBeaconProxy(this.beacon, data); - await assertInitialized.bind(this)({ value, balance: 0n }); - }); - - it('payable initialization', async function () { - const value = 55n; - const data = this.v1.interface.encodeFunctionData('initializePayableWithValue', [value]); - const balance = 100n; - - this.proxy = await this.newBeaconProxy(this.beacon, data, { value: balance }); - await assertInitialized.bind(this)({ value, balance }); - }); - - it('reverting initialization due to value', async function () { - await expect(this.newBeaconProxy(this.beacon, '0x', { value: 1n })).to.be.revertedWithCustomError( - this.factory, - 'ERC1967NonPayable', - ); - }); - - it('reverting initialization function', async function () { - const data = this.v1.interface.encodeFunctionData('reverts'); - await expect(this.newBeaconProxy(this.beacon, data)).to.be.revertedWith('DummyImplementation reverted'); - }); - }); - - describe('upgrade', function () { - it('upgrade a proxy by upgrading its beacon', async function () { - const value = 10n; - const data = this.v1.interface.encodeFunctionData('initializeNonPayableWithValue', [value]); - const proxy = await this.newBeaconProxy(this.beacon, data).then(instance => this.v1.attach(instance)); - - // test initial values - expect(await proxy.value()).to.equal(value); - - // test initial version - expect(await proxy.version()).to.equal('V1'); - - // upgrade beacon - await this.beacon.connect(this.admin).upgradeTo(this.v2); - - // test upgraded version - expect(await proxy.version()).to.equal('V2'); - }); - - it('upgrade 2 proxies by upgrading shared beacon', async function () { - const value1 = 10n; - const data1 = this.v1.interface.encodeFunctionData('initializeNonPayableWithValue', [value1]); - const proxy1 = await this.newBeaconProxy(this.beacon, data1).then(instance => this.v1.attach(instance)); - - const value2 = 42n; - const data2 = this.v1.interface.encodeFunctionData('initializeNonPayableWithValue', [value2]); - const proxy2 = await this.newBeaconProxy(this.beacon, data2).then(instance => this.v1.attach(instance)); - - // test initial values - expect(await proxy1.value()).to.equal(value1); - expect(await proxy2.value()).to.equal(value2); - - // test initial version - expect(await proxy1.version()).to.equal('V1'); - expect(await proxy2.version()).to.equal('V1'); - - // upgrade beacon - await this.beacon.connect(this.admin).upgradeTo(this.v2); - - // test upgraded version - expect(await proxy1.version()).to.equal('V2'); - expect(await proxy2.version()).to.equal('V2'); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/proxy/beacon/UpgradeableBeacon.test.js b/lib/openzeppelin-contracts/test/proxy/beacon/UpgradeableBeacon.test.js deleted file mode 100644 index 2da7d0a..0000000 --- a/lib/openzeppelin-contracts/test/proxy/beacon/UpgradeableBeacon.test.js +++ /dev/null @@ -1,55 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -async function fixture() { - const [admin, other] = await ethers.getSigners(); - - const v1 = await ethers.deployContract('Implementation1'); - const v2 = await ethers.deployContract('Implementation2'); - const beacon = await ethers.deployContract('UpgradeableBeacon', [v1, admin]); - - return { admin, other, beacon, v1, v2 }; -} - -describe('UpgradeableBeacon', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - it('cannot be created with non-contract implementation', async function () { - await expect(ethers.deployContract('UpgradeableBeacon', [this.other, this.admin])) - .to.be.revertedWithCustomError(this.beacon, 'BeaconInvalidImplementation') - .withArgs(this.other); - }); - - describe('once deployed', function () { - it('emits Upgraded event to the first implementation', async function () { - await expect(this.beacon.deploymentTransaction()).to.emit(this.beacon, 'Upgraded').withArgs(this.v1); - }); - - it('returns implementation', async function () { - expect(await this.beacon.implementation()).to.equal(this.v1); - }); - - it('can be upgraded by the admin', async function () { - await expect(this.beacon.connect(this.admin).upgradeTo(this.v2)) - .to.emit(this.beacon, 'Upgraded') - .withArgs(this.v2); - - expect(await this.beacon.implementation()).to.equal(this.v2); - }); - - it('cannot be upgraded to a non-contract', async function () { - await expect(this.beacon.connect(this.admin).upgradeTo(this.other)) - .to.be.revertedWithCustomError(this.beacon, 'BeaconInvalidImplementation') - .withArgs(this.other); - }); - - it('cannot be upgraded by other account', async function () { - await expect(this.beacon.connect(this.other).upgradeTo(this.v2)) - .to.be.revertedWithCustomError(this.beacon, 'OwnableUnauthorizedAccount') - .withArgs(this.other); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/proxy/transparent/ProxyAdmin.test.js b/lib/openzeppelin-contracts/test/proxy/transparent/ProxyAdmin.test.js deleted file mode 100644 index df430d4..0000000 --- a/lib/openzeppelin-contracts/test/proxy/transparent/ProxyAdmin.test.js +++ /dev/null @@ -1,82 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { getAddressInSlot, ImplementationSlot } = require('../../helpers/storage'); - -async function fixture() { - const [admin, other] = await ethers.getSigners(); - - const v1 = await ethers.deployContract('DummyImplementation'); - const v2 = await ethers.deployContract('DummyImplementationV2'); - - const proxy = await ethers - .deployContract('TransparentUpgradeableProxy', [v1, admin, '0x']) - .then(instance => ethers.getContractAt('ITransparentUpgradeableProxy', instance)); - - const proxyAdmin = await ethers.getContractAt( - 'ProxyAdmin', - ethers.getCreateAddress({ from: proxy.target, nonce: 1n }), - ); - - return { admin, other, v1, v2, proxy, proxyAdmin }; -} - -describe('ProxyAdmin', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - it('has an owner', async function () { - expect(await this.proxyAdmin.owner()).to.equal(this.admin); - }); - - it('has an interface version', async function () { - expect(await this.proxyAdmin.UPGRADE_INTERFACE_VERSION()).to.equal('5.0.0'); - }); - - describe('without data', function () { - describe('with unauthorized account', function () { - it('fails to upgrade', async function () { - await expect(this.proxyAdmin.connect(this.other).upgradeAndCall(this.proxy, this.v2, '0x')) - .to.be.revertedWithCustomError(this.proxyAdmin, 'OwnableUnauthorizedAccount') - .withArgs(this.other); - }); - }); - - describe('with authorized account', function () { - it('upgrades implementation', async function () { - await this.proxyAdmin.connect(this.admin).upgradeAndCall(this.proxy, this.v2, '0x'); - expect(await getAddressInSlot(this.proxy, ImplementationSlot)).to.equal(this.v2); - }); - }); - }); - - describe('with data', function () { - describe('with unauthorized account', function () { - it('fails to upgrade', async function () { - const data = this.v1.interface.encodeFunctionData('initializeNonPayableWithValue', [1337n]); - await expect(this.proxyAdmin.connect(this.other).upgradeAndCall(this.proxy, this.v2, data)) - .to.be.revertedWithCustomError(this.proxyAdmin, 'OwnableUnauthorizedAccount') - .withArgs(this.other); - }); - }); - - describe('with authorized account', function () { - describe('with invalid callData', function () { - it('fails to upgrade', async function () { - const data = '0x12345678'; - await expect(this.proxyAdmin.connect(this.admin).upgradeAndCall(this.proxy, this.v2, data)).to.be.reverted; - }); - }); - - describe('with valid callData', function () { - it('upgrades implementation', async function () { - const data = this.v2.interface.encodeFunctionData('initializeNonPayableWithValue', [1337n]); - await this.proxyAdmin.connect(this.admin).upgradeAndCall(this.proxy, this.v2, data); - expect(await getAddressInSlot(this.proxy, ImplementationSlot)).to.equal(this.v2); - }); - }); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/proxy/transparent/TransparentUpgradeableProxy.behaviour.js b/lib/openzeppelin-contracts/test/proxy/transparent/TransparentUpgradeableProxy.behaviour.js deleted file mode 100644 index d90bd56..0000000 --- a/lib/openzeppelin-contracts/test/proxy/transparent/TransparentUpgradeableProxy.behaviour.js +++ /dev/null @@ -1,357 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); - -const { impersonate } = require('../../helpers/account'); -const { getAddressInSlot, ImplementationSlot, AdminSlot } = require('../../helpers/storage'); - -// createProxy, initialOwner, accounts -module.exports = function shouldBehaveLikeTransparentUpgradeableProxy() { - before(async function () { - const implementationV0 = await ethers.deployContract('DummyImplementation'); - const implementationV1 = await ethers.deployContract('DummyImplementation'); - - const createProxyWithImpersonatedProxyAdmin = async (logic, initData, opts = undefined) => { - const [proxy, tx] = await this.createProxy(logic, initData, opts).then(instance => - Promise.all([ethers.getContractAt('ITransparentUpgradeableProxy', instance), instance.deploymentTransaction()]), - ); - - const proxyAdmin = await ethers.getContractAt( - 'ProxyAdmin', - ethers.getCreateAddress({ from: proxy.target, nonce: 1n }), - ); - const proxyAdminAsSigner = await proxyAdmin.getAddress().then(impersonate); - - return { - instance: logic.attach(proxy.target), // attaching proxy directly works well for everything except for event resolution - proxy, - proxyAdmin, - proxyAdminAsSigner, - tx, - }; - }; - - Object.assign(this, { - implementationV0, - implementationV1, - createProxyWithImpersonatedProxyAdmin, - }); - }); - - beforeEach(async function () { - Object.assign(this, await this.createProxyWithImpersonatedProxyAdmin(this.implementationV0, '0x')); - }); - - describe('implementation', function () { - it('returns the current implementation address', async function () { - expect(await getAddressInSlot(this.proxy, ImplementationSlot)).to.equal(this.implementationV0); - }); - - it('delegates to the implementation', async function () { - expect(await this.instance.get()).to.be.true; - }); - }); - - describe('proxy admin', function () { - it('emits AdminChanged event during construction', async function () { - await expect(this.tx).to.emit(this.proxy, 'AdminChanged').withArgs(ethers.ZeroAddress, this.proxyAdmin); - }); - - it('sets the proxy admin in storage with the correct initial owner', async function () { - expect(await getAddressInSlot(this.proxy, AdminSlot)).to.equal(this.proxyAdmin); - - expect(await this.proxyAdmin.owner()).to.equal(this.owner); - }); - - it('can overwrite the admin by the implementation', async function () { - await this.instance.unsafeOverrideAdmin(this.other); - - const ERC1967AdminSlotValue = await getAddressInSlot(this.proxy, AdminSlot); - expect(ERC1967AdminSlotValue).to.equal(this.other); - expect(ERC1967AdminSlotValue).to.not.equal(this.proxyAdmin); - - // Still allows previous admin to execute admin operations - await expect(this.proxy.connect(this.proxyAdminAsSigner).upgradeToAndCall(this.implementationV1, '0x')) - .to.emit(this.proxy, 'Upgraded') - .withArgs(this.implementationV1); - }); - }); - - describe('upgradeToAndCall', function () { - describe('without migrations', function () { - beforeEach(async function () { - this.behavior = await ethers.deployContract('InitializableMock'); - }); - - describe('when the call does not fail', function () { - beforeEach(function () { - this.initializeData = this.behavior.interface.encodeFunctionData('initializeWithX', [42n]); - }); - - describe('when the sender is the admin', function () { - const value = 10n ** 5n; - - beforeEach(async function () { - this.tx = await this.proxy - .connect(this.proxyAdminAsSigner) - .upgradeToAndCall(this.behavior, this.initializeData, { - value, - }); - }); - - it('upgrades to the requested implementation', async function () { - expect(await getAddressInSlot(this.proxy, ImplementationSlot)).to.equal(this.behavior); - }); - - it('emits an event', async function () { - await expect(this.tx).to.emit(this.proxy, 'Upgraded').withArgs(this.behavior); - }); - - it('calls the initializer function', async function () { - expect(await this.behavior.attach(this.proxy).x()).to.equal(42n); - }); - - it('sends given value to the proxy', async function () { - expect(await ethers.provider.getBalance(this.proxy)).to.equal(value); - }); - - it('uses the storage of the proxy', async function () { - // storage layout should look as follows: - // - 0: Initializable storage ++ initializerRan ++ onlyInitializingRan - // - 1: x - expect(await ethers.provider.getStorage(this.proxy, 1n)).to.equal(42n); - }); - }); - - describe('when the sender is not the admin', function () { - it('reverts', async function () { - await expect(this.proxy.connect(this.other).upgradeToAndCall(this.behavior, this.initializeData)).to.be - .reverted; - }); - }); - }); - - describe('when the call does fail', function () { - beforeEach(function () { - this.initializeData = this.behavior.interface.encodeFunctionData('fail'); - }); - - it('reverts', async function () { - await expect(this.proxy.connect(this.proxyAdminAsSigner).upgradeToAndCall(this.behavior, this.initializeData)) - .to.be.reverted; - }); - }); - }); - - describe('with migrations', function () { - describe('when the sender is the admin', function () { - const value = 10n ** 5n; - - describe('when upgrading to V1', function () { - beforeEach(async function () { - this.behaviorV1 = await ethers.deployContract('MigratableMockV1'); - const v1MigrationData = this.behaviorV1.interface.encodeFunctionData('initialize', [42n]); - - this.balancePreviousV1 = await ethers.provider.getBalance(this.proxy); - this.tx = await this.proxy - .connect(this.proxyAdminAsSigner) - .upgradeToAndCall(this.behaviorV1, v1MigrationData, { - value, - }); - }); - - it('upgrades to the requested version and emits an event', async function () { - expect(await getAddressInSlot(this.proxy, ImplementationSlot)).to.equal(this.behaviorV1); - - await expect(this.tx).to.emit(this.proxy, 'Upgraded').withArgs(this.behaviorV1); - }); - - it("calls the 'initialize' function and sends given value to the proxy", async function () { - expect(await this.behaviorV1.attach(this.proxy).x()).to.equal(42n); - expect(await ethers.provider.getBalance(this.proxy)).to.equal(this.balancePreviousV1 + value); - }); - - describe('when upgrading to V2', function () { - beforeEach(async function () { - this.behaviorV2 = await ethers.deployContract('MigratableMockV2'); - const v2MigrationData = this.behaviorV2.interface.encodeFunctionData('migrate', [10n, 42n]); - - this.balancePreviousV2 = await ethers.provider.getBalance(this.proxy); - this.tx = await this.proxy - .connect(this.proxyAdminAsSigner) - .upgradeToAndCall(this.behaviorV2, v2MigrationData, { - value, - }); - }); - - it('upgrades to the requested version and emits an event', async function () { - expect(await getAddressInSlot(this.proxy, ImplementationSlot)).to.equal(this.behaviorV2); - - await expect(this.tx).to.emit(this.proxy, 'Upgraded').withArgs(this.behaviorV2); - }); - - it("calls the 'migrate' function and sends given value to the proxy", async function () { - expect(await this.behaviorV2.attach(this.proxy).x()).to.equal(10n); - expect(await this.behaviorV2.attach(this.proxy).y()).to.equal(42n); - expect(await ethers.provider.getBalance(this.proxy)).to.equal(this.balancePreviousV2 + value); - }); - - describe('when upgrading to V3', function () { - beforeEach(async function () { - this.behaviorV3 = await ethers.deployContract('MigratableMockV3'); - const v3MigrationData = this.behaviorV3.interface.encodeFunctionData('migrate()'); - - this.balancePreviousV3 = await ethers.provider.getBalance(this.proxy); - this.tx = await this.proxy - .connect(this.proxyAdminAsSigner) - .upgradeToAndCall(this.behaviorV3, v3MigrationData, { - value, - }); - }); - - it('upgrades to the requested version and emits an event', async function () { - expect(await getAddressInSlot(this.proxy, ImplementationSlot)).to.equal(this.behaviorV3); - - await expect(this.tx).to.emit(this.proxy, 'Upgraded').withArgs(this.behaviorV3); - }); - - it("calls the 'migrate' function and sends given value to the proxy", async function () { - expect(await this.behaviorV3.attach(this.proxy).x()).to.equal(42n); - expect(await this.behaviorV3.attach(this.proxy).y()).to.equal(10n); - expect(await ethers.provider.getBalance(this.proxy)).to.equal(this.balancePreviousV3 + value); - }); - }); - }); - }); - }); - - describe('when the sender is not the admin', function () { - it('reverts', async function () { - const behaviorV1 = await ethers.deployContract('MigratableMockV1'); - const v1MigrationData = behaviorV1.interface.encodeFunctionData('initialize', [42n]); - await expect(this.proxy.connect(this.other).upgradeToAndCall(behaviorV1, v1MigrationData)).to.be.reverted; - }); - }); - }); - }); - - describe('transparent proxy', function () { - beforeEach('creating proxy', async function () { - this.clashingImplV0 = await ethers.deployContract('ClashingImplementation'); - this.clashingImplV1 = await ethers.deployContract('ClashingImplementation'); - - Object.assign(this, await this.createProxyWithImpersonatedProxyAdmin(this.clashingImplV0, '0x')); - }); - - it('proxy admin cannot call delegated functions', async function () { - const interface = await ethers.getContractFactory('TransparentUpgradeableProxy'); - - await expect(this.instance.connect(this.proxyAdminAsSigner).delegatedFunction()).to.be.revertedWithCustomError( - interface, - 'ProxyDeniedAdminAccess', - ); - }); - - describe('when function names clash', function () { - it('executes the proxy function if the sender is the admin', async function () { - await expect(this.proxy.connect(this.proxyAdminAsSigner).upgradeToAndCall(this.clashingImplV1, '0x')) - .to.emit(this.proxy, 'Upgraded') - .withArgs(this.clashingImplV1); - }); - - it('delegates the call to implementation when sender is not the admin', async function () { - await expect(this.proxy.connect(this.other).upgradeToAndCall(this.clashingImplV1, '0x')) - .to.emit(this.instance, 'ClashingImplementationCall') - .to.not.emit(this.proxy, 'Upgraded'); - }); - }); - }); - - describe('regression', function () { - const initializeData = '0x'; - - it('should add new function', async function () { - const impl1 = await ethers.deployContract('Implementation1'); - const impl2 = await ethers.deployContract('Implementation2'); - const { instance, proxy, proxyAdminAsSigner } = await this.createProxyWithImpersonatedProxyAdmin( - impl1, - initializeData, - ); - - await instance.setValue(42n); - - // `getValue` is not available in impl1 - await expect(impl2.attach(instance).getValue()).to.be.reverted; - - // do upgrade - await proxy.connect(proxyAdminAsSigner).upgradeToAndCall(impl2, '0x'); - - // `getValue` is available in impl2 - expect(await impl2.attach(instance).getValue()).to.equal(42n); - }); - - it('should remove function', async function () { - const impl1 = await ethers.deployContract('Implementation1'); - const impl2 = await ethers.deployContract('Implementation2'); - const { instance, proxy, proxyAdminAsSigner } = await this.createProxyWithImpersonatedProxyAdmin( - impl2, - initializeData, - ); - - await instance.setValue(42n); - - // `getValue` is available in impl2 - expect(await impl2.attach(instance).getValue()).to.equal(42n); - - // do downgrade - await proxy.connect(proxyAdminAsSigner).upgradeToAndCall(impl1, '0x'); - - // `getValue` is not available in impl1 - await expect(impl2.attach(instance).getValue()).to.be.reverted; - }); - - it('should change function signature', async function () { - const impl1 = await ethers.deployContract('Implementation1'); - const impl3 = await ethers.deployContract('Implementation3'); - const { instance, proxy, proxyAdminAsSigner } = await this.createProxyWithImpersonatedProxyAdmin( - impl1, - initializeData, - ); - - await instance.setValue(42n); - - await proxy.connect(proxyAdminAsSigner).upgradeToAndCall(impl3, '0x'); - - expect(await impl3.attach(instance).getValue(8n)).to.equal(50n); - }); - - it('should add fallback function', async function () { - const impl1 = await ethers.deployContract('Implementation1'); - const impl4 = await ethers.deployContract('Implementation4'); - const { instance, proxy, proxyAdminAsSigner } = await this.createProxyWithImpersonatedProxyAdmin( - impl1, - initializeData, - ); - - await proxy.connect(proxyAdminAsSigner).upgradeToAndCall(impl4, '0x'); - - await this.other.sendTransaction({ to: proxy }); - - expect(await impl4.attach(instance).getValue()).to.equal(1n); - }); - - it('should remove fallback function', async function () { - const impl2 = await ethers.deployContract('Implementation2'); - const impl4 = await ethers.deployContract('Implementation4'); - const { instance, proxy, proxyAdminAsSigner } = await this.createProxyWithImpersonatedProxyAdmin( - impl4, - initializeData, - ); - - await proxy.connect(proxyAdminAsSigner).upgradeToAndCall(impl2, '0x'); - - await expect(this.other.sendTransaction({ to: proxy })).to.be.reverted; - - expect(await impl2.attach(instance).getValue()).to.equal(0n); - }); - }); -}; diff --git a/lib/openzeppelin-contracts/test/proxy/transparent/TransparentUpgradeableProxy.test.js b/lib/openzeppelin-contracts/test/proxy/transparent/TransparentUpgradeableProxy.test.js deleted file mode 100644 index 61e1801..0000000 --- a/lib/openzeppelin-contracts/test/proxy/transparent/TransparentUpgradeableProxy.test.js +++ /dev/null @@ -1,28 +0,0 @@ -const { ethers } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const shouldBehaveLikeProxy = require('../Proxy.behaviour'); -const shouldBehaveLikeTransparentUpgradeableProxy = require('./TransparentUpgradeableProxy.behaviour'); - -async function fixture() { - const [owner, other, ...accounts] = await ethers.getSigners(); - - const implementation = await ethers.deployContract('DummyImplementation'); - - const createProxy = function (logic, initData, opts = undefined) { - return ethers.deployContract('TransparentUpgradeableProxy', [logic, owner, initData], opts); - }; - - return { nonContractAddress: owner, owner, other, accounts, implementation, createProxy }; -} - -describe('TransparentUpgradeableProxy', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - shouldBehaveLikeProxy(); - - // createProxy, owner, otherAccounts - shouldBehaveLikeTransparentUpgradeableProxy(); -}); diff --git a/lib/openzeppelin-contracts/test/proxy/utils/Initializable.test.js b/lib/openzeppelin-contracts/test/proxy/utils/Initializable.test.js deleted file mode 100644 index 6bf213f..0000000 --- a/lib/openzeppelin-contracts/test/proxy/utils/Initializable.test.js +++ /dev/null @@ -1,216 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { MAX_UINT64 } = require('../../helpers/constants'); - -describe('Initializable', function () { - describe('basic testing without inheritance', function () { - beforeEach('deploying', async function () { - this.mock = await ethers.deployContract('InitializableMock'); - }); - - describe('before initialize', function () { - it('initializer has not run', async function () { - expect(await this.mock.initializerRan()).to.be.false; - }); - - it('_initializing returns false before initialization', async function () { - expect(await this.mock.isInitializing()).to.be.false; - }); - }); - - describe('after initialize', function () { - beforeEach('initializing', async function () { - await this.mock.initialize(); - }); - - it('initializer has run', async function () { - expect(await this.mock.initializerRan()).to.be.true; - }); - - it('_initializing returns false after initialization', async function () { - expect(await this.mock.isInitializing()).to.be.false; - }); - - it('initializer does not run again', async function () { - await expect(this.mock.initialize()).to.be.revertedWithCustomError(this.mock, 'InvalidInitialization'); - }); - }); - - describe('nested under an initializer', function () { - it('initializer modifier reverts', async function () { - await expect(this.mock.initializerNested()).to.be.revertedWithCustomError(this.mock, 'InvalidInitialization'); - }); - - it('onlyInitializing modifier succeeds', async function () { - await this.mock.onlyInitializingNested(); - expect(await this.mock.onlyInitializingRan()).to.be.true; - }); - }); - - it('cannot call onlyInitializable function outside the scope of an initializable function', async function () { - await expect(this.mock.initializeOnlyInitializing()).to.be.revertedWithCustomError(this.mock, 'NotInitializing'); - }); - }); - - it('nested initializer can run during construction', async function () { - const mock = await ethers.deployContract('ConstructorInitializableMock'); - expect(await mock.initializerRan()).to.be.true; - expect(await mock.onlyInitializingRan()).to.be.true; - }); - - it('multiple constructor levels can be initializers', async function () { - const mock = await ethers.deployContract('ChildConstructorInitializableMock'); - expect(await mock.initializerRan()).to.be.true; - expect(await mock.childInitializerRan()).to.be.true; - expect(await mock.onlyInitializingRan()).to.be.true; - }); - - describe('reinitialization', function () { - beforeEach('deploying', async function () { - this.mock = await ethers.deployContract('ReinitializerMock'); - }); - - it('can reinitialize', async function () { - expect(await this.mock.counter()).to.equal(0n); - await this.mock.initialize(); - expect(await this.mock.counter()).to.equal(1n); - await this.mock.reinitialize(2); - expect(await this.mock.counter()).to.equal(2n); - await this.mock.reinitialize(3); - expect(await this.mock.counter()).to.equal(3n); - }); - - it('can jump multiple steps', async function () { - expect(await this.mock.counter()).to.equal(0n); - await this.mock.initialize(); - expect(await this.mock.counter()).to.equal(1n); - await this.mock.reinitialize(128); - expect(await this.mock.counter()).to.equal(2n); - }); - - it('cannot nest reinitializers', async function () { - expect(await this.mock.counter()).to.equal(0n); - await expect(this.mock.nestedReinitialize(2, 2)).to.be.revertedWithCustomError( - this.mock, - 'InvalidInitialization', - ); - await expect(this.mock.nestedReinitialize(2, 3)).to.be.revertedWithCustomError( - this.mock, - 'InvalidInitialization', - ); - await expect(this.mock.nestedReinitialize(3, 2)).to.be.revertedWithCustomError( - this.mock, - 'InvalidInitialization', - ); - }); - - it('can chain reinitializers', async function () { - expect(await this.mock.counter()).to.equal(0n); - await this.mock.chainReinitialize(2, 3); - expect(await this.mock.counter()).to.equal(2n); - }); - - it('_getInitializedVersion returns right version', async function () { - await this.mock.initialize(); - expect(await this.mock.getInitializedVersion()).to.equal(1n); - await this.mock.reinitialize(12); - expect(await this.mock.getInitializedVersion()).to.equal(12n); - }); - - describe('contract locking', function () { - it('prevents initialization', async function () { - await this.mock.disableInitializers(); - await expect(this.mock.initialize()).to.be.revertedWithCustomError(this.mock, 'InvalidInitialization'); - }); - - it('prevents re-initialization', async function () { - await this.mock.disableInitializers(); - await expect(this.mock.reinitialize(255n)).to.be.revertedWithCustomError(this.mock, 'InvalidInitialization'); - }); - - it('can lock contract after initialization', async function () { - await this.mock.initialize(); - await this.mock.disableInitializers(); - await expect(this.mock.reinitialize(255n)).to.be.revertedWithCustomError(this.mock, 'InvalidInitialization'); - }); - }); - }); - - describe('events', function () { - it('constructor initialization emits event', async function () { - const mock = await ethers.deployContract('ConstructorInitializableMock'); - await expect(mock.deploymentTransaction()).to.emit(mock, 'Initialized').withArgs(1n); - }); - - it('initialization emits event', async function () { - const mock = await ethers.deployContract('ReinitializerMock'); - await expect(mock.initialize()).to.emit(mock, 'Initialized').withArgs(1n); - }); - - it('reinitialization emits event', async function () { - const mock = await ethers.deployContract('ReinitializerMock'); - await expect(mock.reinitialize(128)).to.emit(mock, 'Initialized').withArgs(128n); - }); - - it('chained reinitialization emits multiple events', async function () { - const mock = await ethers.deployContract('ReinitializerMock'); - - await expect(mock.chainReinitialize(2, 3)) - .to.emit(mock, 'Initialized') - .withArgs(2n) - .to.emit(mock, 'Initialized') - .withArgs(3n); - }); - }); - - describe('complex testing with inheritance', function () { - const mother = 12n; - const gramps = '56'; - const father = 34n; - const child = 78n; - - beforeEach('deploying', async function () { - this.mock = await ethers.deployContract('SampleChild'); - await this.mock.initialize(mother, gramps, father, child); - }); - - it('initializes human', async function () { - expect(await this.mock.isHuman()).to.be.true; - }); - - it('initializes mother', async function () { - expect(await this.mock.mother()).to.equal(mother); - }); - - it('initializes gramps', async function () { - expect(await this.mock.gramps()).to.equal(gramps); - }); - - it('initializes father', async function () { - expect(await this.mock.father()).to.equal(father); - }); - - it('initializes child', async function () { - expect(await this.mock.child()).to.equal(child); - }); - }); - - describe('disabling initialization', function () { - it('old and new patterns in bad sequence', async function () { - const DisableBad1 = await ethers.getContractFactory('DisableBad1'); - await expect(DisableBad1.deploy()).to.be.revertedWithCustomError(DisableBad1, 'InvalidInitialization'); - - const DisableBad2 = await ethers.getContractFactory('DisableBad2'); - await expect(DisableBad2.deploy()).to.be.revertedWithCustomError(DisableBad2, 'InvalidInitialization'); - }); - - it('old and new patterns in good sequence', async function () { - const ok = await ethers.deployContract('DisableOk'); - await expect(ok.deploymentTransaction()) - .to.emit(ok, 'Initialized') - .withArgs(1n) - .to.emit(ok, 'Initialized') - .withArgs(MAX_UINT64); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/proxy/utils/UUPSUpgradeable.test.js b/lib/openzeppelin-contracts/test/proxy/utils/UUPSUpgradeable.test.js deleted file mode 100644 index 17f8657..0000000 --- a/lib/openzeppelin-contracts/test/proxy/utils/UUPSUpgradeable.test.js +++ /dev/null @@ -1,120 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { getAddressInSlot, ImplementationSlot } = require('../../helpers/storage'); - -async function fixture() { - const implInitial = await ethers.deployContract('UUPSUpgradeableMock'); - const implUpgradeOk = await ethers.deployContract('UUPSUpgradeableMock'); - const implUpgradeUnsafe = await ethers.deployContract('UUPSUpgradeableUnsafeMock'); - const implUpgradeNonUUPS = await ethers.deployContract('NonUpgradeableMock'); - const implUnsupportedUUID = await ethers.deployContract('UUPSUnsupportedProxiableUUID'); - // Used for testing non ERC1967 compliant proxies (clones are proxies that don't use the ERC1967 implementation slot) - const cloneFactory = await ethers.deployContract('$Clones'); - - const instance = await ethers - .deployContract('ERC1967Proxy', [implInitial, '0x']) - .then(proxy => implInitial.attach(proxy.target)); - - return { - implInitial, - implUpgradeOk, - implUpgradeUnsafe, - implUpgradeNonUUPS, - implUnsupportedUUID, - cloneFactory, - instance, - }; -} - -describe('UUPSUpgradeable', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - it('has an interface version', async function () { - expect(await this.instance.UPGRADE_INTERFACE_VERSION()).to.equal('5.0.0'); - }); - - it('upgrade to upgradeable implementation', async function () { - await expect(this.instance.upgradeToAndCall(this.implUpgradeOk, '0x')) - .to.emit(this.instance, 'Upgraded') - .withArgs(this.implUpgradeOk); - - expect(await getAddressInSlot(this.instance, ImplementationSlot)).to.equal(this.implUpgradeOk); - }); - - it('upgrade to upgradeable implementation with call', async function () { - expect(await this.instance.current()).to.equal(0n); - - await expect( - this.instance.upgradeToAndCall(this.implUpgradeOk, this.implUpgradeOk.interface.encodeFunctionData('increment')), - ) - .to.emit(this.instance, 'Upgraded') - .withArgs(this.implUpgradeOk); - - expect(await getAddressInSlot(this.instance, ImplementationSlot)).to.equal(this.implUpgradeOk); - - expect(await this.instance.current()).to.equal(1n); - }); - - it('calling upgradeTo on the implementation reverts', async function () { - await expect(this.implInitial.upgradeToAndCall(this.implUpgradeOk, '0x')).to.be.revertedWithCustomError( - this.implInitial, - 'UUPSUnauthorizedCallContext', - ); - }); - - it('calling upgradeToAndCall on the implementation reverts', async function () { - await expect( - this.implInitial.upgradeToAndCall( - this.implUpgradeOk, - this.implUpgradeOk.interface.encodeFunctionData('increment'), - ), - ).to.be.revertedWithCustomError(this.implUpgradeOk, 'UUPSUnauthorizedCallContext'); - }); - - it('calling upgradeToAndCall from a contract that is not an ERC1967 proxy (with the right implementation) reverts', async function () { - const instance = await this.cloneFactory.$clone - .staticCall(this.implUpgradeOk) - .then(address => this.implInitial.attach(address)); - await this.cloneFactory.$clone(this.implUpgradeOk); - - await expect(instance.upgradeToAndCall(this.implUpgradeUnsafe, '0x')).to.be.revertedWithCustomError( - instance, - 'UUPSUnauthorizedCallContext', - ); - }); - - it('rejects upgrading to an unsupported UUID', async function () { - await expect(this.instance.upgradeToAndCall(this.implUnsupportedUUID, '0x')) - .to.be.revertedWithCustomError(this.instance, 'UUPSUnsupportedProxiableUUID') - .withArgs(ethers.id('invalid UUID')); - }); - - it('upgrade to and unsafe upgradeable implementation', async function () { - await expect(this.instance.upgradeToAndCall(this.implUpgradeUnsafe, '0x')) - .to.emit(this.instance, 'Upgraded') - .withArgs(this.implUpgradeUnsafe); - - expect(await getAddressInSlot(this.instance, ImplementationSlot)).to.equal(this.implUpgradeUnsafe); - }); - - // delegate to a non existing upgradeTo function causes a low level revert - it('reject upgrade to non uups implementation', async function () { - await expect(this.instance.upgradeToAndCall(this.implUpgradeNonUUPS, '0x')) - .to.be.revertedWithCustomError(this.instance, 'ERC1967InvalidImplementation') - .withArgs(this.implUpgradeNonUUPS); - }); - - it('reject proxy address as implementation', async function () { - const otherInstance = await ethers - .deployContract('ERC1967Proxy', [this.implInitial, '0x']) - .then(proxy => this.implInitial.attach(proxy.target)); - - await expect(this.instance.upgradeToAndCall(otherInstance, '0x')) - .to.be.revertedWithCustomError(this.instance, 'ERC1967InvalidImplementation') - .withArgs(otherInstance); - }); -}); diff --git a/lib/openzeppelin-contracts/test/sanity.test.js b/lib/openzeppelin-contracts/test/sanity.test.js deleted file mode 100644 index ea0175c..0000000 --- a/lib/openzeppelin-contracts/test/sanity.test.js +++ /dev/null @@ -1,27 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture, mine } = require('@nomicfoundation/hardhat-network-helpers'); - -async function fixture() { - return {}; -} - -describe('Environment sanity', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('snapshot', function () { - let blockNumberBefore; - - it('cache and mine', async function () { - blockNumberBefore = await ethers.provider.getBlockNumber(); - await mine(); - expect(await ethers.provider.getBlockNumber()).to.equal(blockNumberBefore + 1); - }); - - it('check snapshot', async function () { - expect(await ethers.provider.getBlockNumber()).to.equal(blockNumberBefore); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC1155/ERC1155.behavior.js b/lib/openzeppelin-contracts/test/token/ERC1155/ERC1155.behavior.js deleted file mode 100644 index d19b732..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC1155/ERC1155.behavior.js +++ /dev/null @@ -1,763 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { anyValue } = require('@nomicfoundation/hardhat-chai-matchers/withArgs'); - -const { RevertType } = require('../../helpers/enums'); -const { shouldSupportInterfaces } = require('../../utils/introspection/SupportsInterface.behavior'); - -function shouldBehaveLikeERC1155() { - const firstTokenId = 1n; - const secondTokenId = 2n; - const unknownTokenId = 3n; - - const firstTokenValue = 1000n; - const secondTokenValue = 2000n; - - const RECEIVER_SINGLE_MAGIC_VALUE = '0xf23a6e61'; - const RECEIVER_BATCH_MAGIC_VALUE = '0xbc197c81'; - - beforeEach(async function () { - [this.recipient, this.proxy, this.alice, this.bruce] = this.otherAccounts; - }); - - describe('like an ERC1155', function () { - describe('balanceOf', function () { - it('should return 0 when queried about the zero address', async function () { - expect(await this.token.balanceOf(ethers.ZeroAddress, firstTokenId)).to.equal(0n); - }); - - describe("when accounts don't own tokens", function () { - it('returns zero for given addresses', async function () { - expect(await this.token.balanceOf(this.alice, firstTokenId)).to.equal(0n); - expect(await this.token.balanceOf(this.bruce, secondTokenId)).to.equal(0n); - expect(await this.token.balanceOf(this.alice, unknownTokenId)).to.equal(0n); - }); - }); - - describe('when accounts own some tokens', function () { - beforeEach(async function () { - await this.token.$_mint(this.alice, firstTokenId, firstTokenValue, '0x'); - await this.token.$_mint(this.bruce, secondTokenId, secondTokenValue, '0x'); - }); - - it('returns the amount of tokens owned by the given addresses', async function () { - expect(await this.token.balanceOf(this.alice, firstTokenId)).to.equal(firstTokenValue); - expect(await this.token.balanceOf(this.bruce, secondTokenId)).to.equal(secondTokenValue); - expect(await this.token.balanceOf(this.alice, unknownTokenId)).to.equal(0n); - }); - }); - }); - - describe('balanceOfBatch', function () { - it("reverts when input arrays don't match up", async function () { - const accounts1 = [this.alice, this.bruce, this.alice, this.bruce]; - const ids1 = [firstTokenId, secondTokenId, unknownTokenId]; - - await expect(this.token.balanceOfBatch(accounts1, ids1)) - .to.be.revertedWithCustomError(this.token, 'ERC1155InvalidArrayLength') - .withArgs(ids1.length, accounts1.length); - - const accounts2 = [this.alice, this.bruce]; - const ids2 = [firstTokenId, secondTokenId, unknownTokenId]; - await expect(this.token.balanceOfBatch(accounts2, ids2)) - .to.be.revertedWithCustomError(this.token, 'ERC1155InvalidArrayLength') - .withArgs(ids2.length, accounts2.length); - }); - - it('should return 0 as the balance when one of the addresses is the zero address', async function () { - const result = await this.token.balanceOfBatch( - [this.alice, this.bruce, ethers.ZeroAddress], - [firstTokenId, secondTokenId, unknownTokenId], - ); - expect(result).to.deep.equal([0n, 0n, 0n]); - }); - - describe("when accounts don't own tokens", function () { - it('returns zeros for each account', async function () { - const result = await this.token.balanceOfBatch( - [this.alice, this.bruce, this.alice], - [firstTokenId, secondTokenId, unknownTokenId], - ); - expect(result).to.deep.equal([0n, 0n, 0n]); - }); - }); - - describe('when accounts own some tokens', function () { - beforeEach(async function () { - await this.token.$_mint(this.alice, firstTokenId, firstTokenValue, '0x'); - await this.token.$_mint(this.bruce, secondTokenId, secondTokenValue, '0x'); - }); - - it('returns amounts owned by each account in order passed', async function () { - const result = await this.token.balanceOfBatch( - [this.bruce, this.alice, this.alice], - [secondTokenId, firstTokenId, unknownTokenId], - ); - expect(result).to.deep.equal([secondTokenValue, firstTokenValue, 0n]); - }); - - it('returns multiple times the balance of the same address when asked', async function () { - const result = await this.token.balanceOfBatch( - [this.alice, this.bruce, this.alice], - [firstTokenId, secondTokenId, firstTokenId], - ); - expect(result).to.deep.equal([firstTokenValue, secondTokenValue, firstTokenValue]); - }); - }); - }); - - describe('setApprovalForAll', function () { - beforeEach(async function () { - this.tx = await this.token.connect(this.holder).setApprovalForAll(this.proxy, true); - }); - - it('sets approval status which can be queried via isApprovedForAll', async function () { - expect(await this.token.isApprovedForAll(this.holder, this.proxy)).to.be.true; - }); - - it('emits an ApprovalForAll log', async function () { - await expect(this.tx).to.emit(this.token, 'ApprovalForAll').withArgs(this.holder, this.proxy, true); - }); - - it('can unset approval for an operator', async function () { - await this.token.connect(this.holder).setApprovalForAll(this.proxy, false); - expect(await this.token.isApprovedForAll(this.holder, this.proxy)).to.be.false; - }); - - it('reverts if attempting to approve zero address as an operator', async function () { - await expect(this.token.connect(this.holder).setApprovalForAll(ethers.ZeroAddress, true)) - .to.be.revertedWithCustomError(this.token, 'ERC1155InvalidOperator') - .withArgs(ethers.ZeroAddress); - }); - }); - - describe('safeTransferFrom', function () { - beforeEach(async function () { - await this.token.$_mint(this.holder, firstTokenId, firstTokenValue, '0x'); - await this.token.$_mint(this.holder, secondTokenId, secondTokenValue, '0x'); - }); - - it('reverts when transferring more than balance', async function () { - await expect( - this.token - .connect(this.holder) - .safeTransferFrom(this.holder, this.recipient, firstTokenId, firstTokenValue + 1n, '0x'), - ) - .to.be.revertedWithCustomError(this.token, 'ERC1155InsufficientBalance') - .withArgs(this.holder, firstTokenValue, firstTokenValue + 1n, firstTokenId); - }); - - it('reverts when transferring to zero address', async function () { - await expect( - this.token - .connect(this.holder) - .safeTransferFrom(this.holder, ethers.ZeroAddress, firstTokenId, firstTokenValue, '0x'), - ) - .to.be.revertedWithCustomError(this.token, 'ERC1155InvalidReceiver') - .withArgs(ethers.ZeroAddress); - }); - - function transferWasSuccessful() { - it('debits transferred balance from sender', async function () { - expect(await this.token.balanceOf(this.args.from, this.args.id)).to.equal(0n); - }); - - it('credits transferred balance to receiver', async function () { - expect(await this.token.balanceOf(this.args.to, this.args.id)).to.equal(this.args.value); - }); - - it('emits a TransferSingle log', async function () { - await expect(this.tx) - .to.emit(this.token, 'TransferSingle') - .withArgs(this.args.operator, this.args.from, this.args.to, this.args.id, this.args.value); - }); - } - - describe('when called by the holder', function () { - beforeEach(async function () { - this.args = { - operator: this.holder, - from: this.holder, - to: this.recipient, - id: firstTokenId, - value: firstTokenValue, - data: '0x', - }; - this.tx = await this.token - .connect(this.args.operator) - .safeTransferFrom(this.args.from, this.args.to, this.args.id, this.args.value, this.args.data); - }); - - transferWasSuccessful(); - - it('preserves existing balances which are not transferred by holder', async function () { - expect(await this.token.balanceOf(this.holder, secondTokenId)).to.equal(secondTokenValue); - expect(await this.token.balanceOf(this.recipient, secondTokenId)).to.equal(0n); - }); - }); - - describe('when called by an operator on behalf of the holder', function () { - describe('when operator is not approved by holder', function () { - beforeEach(async function () { - await this.token.connect(this.holder).setApprovalForAll(this.proxy, false); - }); - - it('reverts', async function () { - await expect( - this.token - .connect(this.proxy) - .safeTransferFrom(this.holder, this.recipient, firstTokenId, firstTokenValue, '0x'), - ) - .to.be.revertedWithCustomError(this.token, 'ERC1155MissingApprovalForAll') - .withArgs(this.proxy, this.holder); - }); - }); - - describe('when operator is approved by holder', function () { - beforeEach(async function () { - await this.token.connect(this.holder).setApprovalForAll(this.proxy, true); - - this.args = { - operator: this.proxy, - from: this.holder, - to: this.recipient, - id: firstTokenId, - value: firstTokenValue, - data: '0x', - }; - this.tx = await this.token - .connect(this.args.operator) - .safeTransferFrom(this.args.from, this.args.to, this.args.id, this.args.value, this.args.data); - }); - - transferWasSuccessful(); - - it("preserves operator's balances not involved in the transfer", async function () { - expect(await this.token.balanceOf(this.proxy, firstTokenId)).to.equal(0n); - expect(await this.token.balanceOf(this.proxy, secondTokenId)).to.equal(0n); - }); - }); - }); - - describe('when sending to a valid receiver', function () { - beforeEach(async function () { - this.receiver = await ethers.deployContract('$ERC1155ReceiverMock', [ - RECEIVER_SINGLE_MAGIC_VALUE, - RECEIVER_BATCH_MAGIC_VALUE, - RevertType.None, - ]); - }); - - describe('without data', function () { - beforeEach(async function () { - this.args = { - operator: this.holder, - from: this.holder, - to: this.receiver, - id: firstTokenId, - value: firstTokenValue, - data: '0x', - }; - this.tx = await this.token - .connect(this.args.operator) - .safeTransferFrom(this.args.from, this.args.to, this.args.id, this.args.value, this.args.data); - }); - - transferWasSuccessful(); - - it('calls onERC1155Received', async function () { - await expect(this.tx) - .to.emit(this.receiver, 'Received') - .withArgs(this.args.operator, this.args.from, this.args.id, this.args.value, this.args.data, anyValue); - }); - }); - - describe('with data', function () { - beforeEach(async function () { - this.args = { - operator: this.holder, - from: this.holder, - to: this.receiver, - id: firstTokenId, - value: firstTokenValue, - data: '0xf00dd00d', - }; - this.tx = await this.token - .connect(this.args.operator) - .safeTransferFrom(this.args.from, this.args.to, this.args.id, this.args.value, this.args.data); - }); - - transferWasSuccessful(); - - it('calls onERC1155Received', async function () { - await expect(this.tx) - .to.emit(this.receiver, 'Received') - .withArgs(this.args.operator, this.args.from, this.args.id, this.args.value, this.args.data, anyValue); - }); - }); - }); - - describe('to a receiver contract returning unexpected value', function () { - it('reverts', async function () { - const receiver = await ethers.deployContract('$ERC1155ReceiverMock', [ - '0x00c0ffee', - RECEIVER_BATCH_MAGIC_VALUE, - RevertType.None, - ]); - - await expect( - this.token - .connect(this.holder) - .safeTransferFrom(this.holder, receiver, firstTokenId, firstTokenValue, '0x'), - ) - .to.be.revertedWithCustomError(this.token, 'ERC1155InvalidReceiver') - .withArgs(receiver); - }); - }); - - describe('to a receiver contract that reverts', function () { - describe('with a revert string', function () { - it('reverts', async function () { - const receiver = await ethers.deployContract('$ERC1155ReceiverMock', [ - RECEIVER_SINGLE_MAGIC_VALUE, - RECEIVER_BATCH_MAGIC_VALUE, - RevertType.RevertWithMessage, - ]); - - await expect( - this.token - .connect(this.holder) - .safeTransferFrom(this.holder, receiver, firstTokenId, firstTokenValue, '0x'), - ).to.be.revertedWith('ERC1155ReceiverMock: reverting on receive'); - }); - }); - - describe('without a revert string', function () { - it('reverts', async function () { - const receiver = await ethers.deployContract('$ERC1155ReceiverMock', [ - RECEIVER_SINGLE_MAGIC_VALUE, - RECEIVER_BATCH_MAGIC_VALUE, - RevertType.RevertWithoutMessage, - ]); - - await expect( - this.token - .connect(this.holder) - .safeTransferFrom(this.holder, receiver, firstTokenId, firstTokenValue, '0x'), - ) - .to.be.revertedWithCustomError(this.token, 'ERC1155InvalidReceiver') - .withArgs(receiver); - }); - }); - - describe('with a custom error', function () { - it('reverts', async function () { - const receiver = await ethers.deployContract('$ERC1155ReceiverMock', [ - RECEIVER_SINGLE_MAGIC_VALUE, - RECEIVER_BATCH_MAGIC_VALUE, - RevertType.RevertWithCustomError, - ]); - - await expect( - this.token - .connect(this.holder) - .safeTransferFrom(this.holder, receiver, firstTokenId, firstTokenValue, '0x'), - ) - .to.be.revertedWithCustomError(receiver, 'CustomError') - .withArgs(RECEIVER_SINGLE_MAGIC_VALUE); - }); - }); - - describe('with a panic', function () { - it('reverts', async function () { - const receiver = await ethers.deployContract('$ERC1155ReceiverMock', [ - RECEIVER_SINGLE_MAGIC_VALUE, - RECEIVER_BATCH_MAGIC_VALUE, - RevertType.Panic, - ]); - - await expect( - this.token - .connect(this.holder) - .safeTransferFrom(this.holder, receiver, firstTokenId, firstTokenValue, '0x'), - ).to.be.revertedWithPanic(); - }); - }); - }); - - describe('to a contract that does not implement the required function', function () { - it('reverts', async function () { - const invalidReceiver = this.token; - - await expect( - this.token - .connect(this.holder) - .safeTransferFrom(this.holder, invalidReceiver, firstTokenId, firstTokenValue, '0x'), - ) - .to.be.revertedWithCustomError(this.token, 'ERC1155InvalidReceiver') - .withArgs(invalidReceiver); - }); - }); - }); - - describe('safeBatchTransferFrom', function () { - beforeEach(async function () { - await this.token.$_mint(this.holder, firstTokenId, firstTokenValue, '0x'); - await this.token.$_mint(this.holder, secondTokenId, secondTokenValue, '0x'); - }); - - it('reverts when transferring value more than any of balances', async function () { - await expect( - this.token - .connect(this.holder) - .safeBatchTransferFrom( - this.holder, - this.recipient, - [firstTokenId, secondTokenId], - [firstTokenValue, secondTokenValue + 1n], - '0x', - ), - ) - .to.be.revertedWithCustomError(this.token, 'ERC1155InsufficientBalance') - .withArgs(this.holder, secondTokenValue, secondTokenValue + 1n, secondTokenId); - }); - - it("reverts when ids array length doesn't match values array length", async function () { - const ids1 = [firstTokenId]; - const tokenValues1 = [firstTokenValue, secondTokenValue]; - - await expect( - this.token.connect(this.holder).safeBatchTransferFrom(this.holder, this.recipient, ids1, tokenValues1, '0x'), - ) - .to.be.revertedWithCustomError(this.token, 'ERC1155InvalidArrayLength') - .withArgs(ids1.length, tokenValues1.length); - - const ids2 = [firstTokenId, secondTokenId]; - const tokenValues2 = [firstTokenValue]; - - await expect( - this.token.connect(this.holder).safeBatchTransferFrom(this.holder, this.recipient, ids2, tokenValues2, '0x'), - ) - .to.be.revertedWithCustomError(this.token, 'ERC1155InvalidArrayLength') - .withArgs(ids2.length, tokenValues2.length); - }); - - it('reverts when transferring to zero address', async function () { - await expect( - this.token - .connect(this.holder) - .safeBatchTransferFrom( - this.holder, - ethers.ZeroAddress, - [firstTokenId, secondTokenId], - [firstTokenValue, secondTokenValue], - '0x', - ), - ) - .to.be.revertedWithCustomError(this.token, 'ERC1155InvalidReceiver') - .withArgs(ethers.ZeroAddress); - }); - - it('reverts when transferring from zero address', async function () { - await expect( - this.token.$_safeBatchTransferFrom(ethers.ZeroAddress, this.holder, [firstTokenId], [firstTokenValue], '0x'), - ) - .to.be.revertedWithCustomError(this.token, 'ERC1155InvalidSender') - .withArgs(ethers.ZeroAddress); - }); - - function batchTransferWasSuccessful() { - it('debits transferred balances from sender', async function () { - const newBalances = await this.token.balanceOfBatch( - this.args.ids.map(() => this.args.from), - this.args.ids, - ); - expect(newBalances).to.deep.equal(this.args.ids.map(() => 0n)); - }); - - it('credits transferred balances to receiver', async function () { - const newBalances = await this.token.balanceOfBatch( - this.args.ids.map(() => this.args.to), - this.args.ids, - ); - expect(newBalances).to.deep.equal(this.args.values); - }); - - it('emits a TransferBatch log', async function () { - await expect(this.tx) - .to.emit(this.token, 'TransferBatch') - .withArgs(this.args.operator, this.args.from, this.args.to, this.args.ids, this.args.values); - }); - } - - describe('when called by the holder', function () { - beforeEach(async function () { - this.args = { - operator: this.holder, - from: this.holder, - to: this.recipient, - ids: [firstTokenId, secondTokenId], - values: [firstTokenValue, secondTokenValue], - data: '0x', - }; - this.tx = await this.token - .connect(this.args.operator) - .safeBatchTransferFrom(this.args.from, this.args.to, this.args.ids, this.args.values, this.args.data); - }); - - batchTransferWasSuccessful(); - }); - - describe('when called by an operator on behalf of the holder', function () { - describe('when operator is not approved by holder', function () { - beforeEach(async function () { - await this.token.connect(this.holder).setApprovalForAll(this.proxy, false); - }); - - it('reverts', async function () { - await expect( - this.token - .connect(this.proxy) - .safeBatchTransferFrom( - this.holder, - this.recipient, - [firstTokenId, secondTokenId], - [firstTokenValue, secondTokenValue], - '0x', - ), - ) - .to.be.revertedWithCustomError(this.token, 'ERC1155MissingApprovalForAll') - .withArgs(this.proxy, this.holder); - }); - }); - - describe('when operator is approved by holder', function () { - beforeEach(async function () { - await this.token.connect(this.holder).setApprovalForAll(this.proxy, true); - - this.args = { - operator: this.proxy, - from: this.holder, - to: this.recipient, - ids: [firstTokenId, secondTokenId], - values: [firstTokenValue, secondTokenValue], - data: '0x', - }; - this.tx = await this.token - .connect(this.args.operator) - .safeBatchTransferFrom(this.args.from, this.args.to, this.args.ids, this.args.values, this.args.data); - }); - - batchTransferWasSuccessful(); - - it("preserves operator's balances not involved in the transfer", async function () { - expect(await this.token.balanceOf(this.proxy, firstTokenId)).to.equal(0n); - expect(await this.token.balanceOf(this.proxy, secondTokenId)).to.equal(0n); - }); - }); - }); - - describe('when sending to a valid receiver', function () { - beforeEach(async function () { - this.receiver = await ethers.deployContract('$ERC1155ReceiverMock', [ - RECEIVER_SINGLE_MAGIC_VALUE, - RECEIVER_BATCH_MAGIC_VALUE, - RevertType.None, - ]); - }); - - describe('without data', function () { - beforeEach(async function () { - this.args = { - operator: this.holder, - from: this.holder, - to: this.receiver, - ids: [firstTokenId, secondTokenId], - values: [firstTokenValue, secondTokenValue], - data: '0x', - }; - this.tx = await this.token - .connect(this.args.operator) - .safeBatchTransferFrom(this.args.from, this.args.to, this.args.ids, this.args.values, this.args.data); - }); - - batchTransferWasSuccessful(); - - it('calls onERC1155BatchReceived', async function () { - await expect(this.tx) - .to.emit(this.receiver, 'BatchReceived') - .withArgs(this.holder, this.holder, this.args.ids, this.args.values, this.args.data, anyValue); - }); - }); - - describe('with data', function () { - beforeEach(async function () { - this.args = { - operator: this.holder, - from: this.holder, - to: this.receiver, - ids: [firstTokenId, secondTokenId], - values: [firstTokenValue, secondTokenValue], - data: '0xf00dd00d', - }; - this.tx = await this.token - .connect(this.args.operator) - .safeBatchTransferFrom(this.args.from, this.args.to, this.args.ids, this.args.values, this.args.data); - }); - - batchTransferWasSuccessful(); - - it('calls onERC1155Received', async function () { - await expect(this.tx) - .to.emit(this.receiver, 'BatchReceived') - .withArgs(this.holder, this.holder, this.args.ids, this.args.values, this.args.data, anyValue); - }); - }); - }); - - describe('to a receiver contract returning unexpected value', function () { - it('reverts', async function () { - const receiver = await ethers.deployContract('$ERC1155ReceiverMock', [ - RECEIVER_SINGLE_MAGIC_VALUE, - RECEIVER_SINGLE_MAGIC_VALUE, - RevertType.None, - ]); - - await expect( - this.token - .connect(this.holder) - .safeBatchTransferFrom( - this.holder, - receiver, - [firstTokenId, secondTokenId], - [firstTokenValue, secondTokenValue], - '0x', - ), - ) - .to.be.revertedWithCustomError(this.token, 'ERC1155InvalidReceiver') - .withArgs(receiver); - }); - }); - - describe('to a receiver contract that reverts', function () { - describe('with a revert string', function () { - it('reverts', async function () { - const receiver = await ethers.deployContract('$ERC1155ReceiverMock', [ - RECEIVER_SINGLE_MAGIC_VALUE, - RECEIVER_BATCH_MAGIC_VALUE, - RevertType.RevertWithMessage, - ]); - - await expect( - this.token - .connect(this.holder) - .safeBatchTransferFrom( - this.holder, - receiver, - [firstTokenId, secondTokenId], - [firstTokenValue, secondTokenValue], - '0x', - ), - ).to.be.revertedWith('ERC1155ReceiverMock: reverting on batch receive'); - }); - }); - - describe('without a revert string', function () { - it('reverts', async function () { - const receiver = await ethers.deployContract('$ERC1155ReceiverMock', [ - RECEIVER_SINGLE_MAGIC_VALUE, - RECEIVER_BATCH_MAGIC_VALUE, - RevertType.RevertWithoutMessage, - ]); - - await expect( - this.token - .connect(this.holder) - .safeBatchTransferFrom( - this.holder, - receiver, - [firstTokenId, secondTokenId], - [firstTokenValue, secondTokenValue], - '0x', - ), - ) - .to.be.revertedWithCustomError(this.token, 'ERC1155InvalidReceiver') - .withArgs(receiver); - }); - }); - - describe('with a custom error', function () { - it('reverts', async function () { - const receiver = await ethers.deployContract('$ERC1155ReceiverMock', [ - RECEIVER_SINGLE_MAGIC_VALUE, - RECEIVER_BATCH_MAGIC_VALUE, - RevertType.RevertWithCustomError, - ]); - - await expect( - this.token - .connect(this.holder) - .safeBatchTransferFrom( - this.holder, - receiver, - [firstTokenId, secondTokenId], - [firstTokenValue, secondTokenValue], - '0x', - ), - ) - .to.be.revertedWithCustomError(receiver, 'CustomError') - .withArgs(RECEIVER_SINGLE_MAGIC_VALUE); - }); - }); - - describe('with a panic', function () { - it('reverts', async function () { - const receiver = await ethers.deployContract('$ERC1155ReceiverMock', [ - RECEIVER_SINGLE_MAGIC_VALUE, - RECEIVER_BATCH_MAGIC_VALUE, - RevertType.Panic, - ]); - - await expect( - this.token - .connect(this.holder) - .safeBatchTransferFrom( - this.holder, - receiver, - [firstTokenId, secondTokenId], - [firstTokenValue, secondTokenValue], - '0x', - ), - ).to.be.revertedWithPanic(); - }); - }); - }); - - describe('to a contract that does not implement the required function', function () { - it('reverts', async function () { - const invalidReceiver = this.token; - - await expect( - this.token - .connect(this.holder) - .safeBatchTransferFrom( - this.holder, - invalidReceiver, - [firstTokenId, secondTokenId], - [firstTokenValue, secondTokenValue], - '0x', - ), - ) - .to.be.revertedWithCustomError(this.token, 'ERC1155InvalidReceiver') - .withArgs(invalidReceiver); - }); - }); - }); - - shouldSupportInterfaces(['ERC1155', 'ERC1155MetadataURI']); - }); -} - -module.exports = { - shouldBehaveLikeERC1155, -}; diff --git a/lib/openzeppelin-contracts/test/token/ERC1155/ERC1155.test.js b/lib/openzeppelin-contracts/test/token/ERC1155/ERC1155.test.js deleted file mode 100644 index 8b0a672..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC1155/ERC1155.test.js +++ /dev/null @@ -1,213 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { zip } = require('../../helpers/iterate'); -const { shouldBehaveLikeERC1155 } = require('./ERC1155.behavior'); - -const initialURI = 'https://token-cdn-domain/{id}.json'; - -async function fixture() { - const [operator, holder, ...otherAccounts] = await ethers.getSigners(); - const token = await ethers.deployContract('$ERC1155', [initialURI]); - return { token, operator, holder, otherAccounts }; -} - -describe('ERC1155', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - shouldBehaveLikeERC1155(); - - describe('internal functions', function () { - const tokenId = 1990n; - const mintValue = 9001n; - const burnValue = 3000n; - - const tokenBatchIds = [2000n, 2010n, 2020n]; - const mintValues = [5000n, 10000n, 42195n]; - const burnValues = [5000n, 9001n, 195n]; - - const data = '0x12345678'; - - describe('_mint', function () { - it('reverts with a zero destination address', async function () { - await expect(this.token.$_mint(ethers.ZeroAddress, tokenId, mintValue, data)) - .to.be.revertedWithCustomError(this.token, 'ERC1155InvalidReceiver') - .withArgs(ethers.ZeroAddress); - }); - - describe('with minted tokens', function () { - beforeEach(async function () { - this.tx = await this.token.connect(this.operator).$_mint(this.holder, tokenId, mintValue, data); - }); - - it('emits a TransferSingle event', async function () { - await expect(this.tx) - .to.emit(this.token, 'TransferSingle') - .withArgs(this.operator, ethers.ZeroAddress, this.holder, tokenId, mintValue); - }); - - it('credits the minted token value', async function () { - expect(await this.token.balanceOf(this.holder, tokenId)).to.equal(mintValue); - }); - }); - }); - - describe('_mintBatch', function () { - it('reverts with a zero destination address', async function () { - await expect(this.token.$_mintBatch(ethers.ZeroAddress, tokenBatchIds, mintValues, data)) - .to.be.revertedWithCustomError(this.token, 'ERC1155InvalidReceiver') - .withArgs(ethers.ZeroAddress); - }); - - it('reverts if length of inputs do not match', async function () { - await expect(this.token.$_mintBatch(this.holder, tokenBatchIds, mintValues.slice(1), data)) - .to.be.revertedWithCustomError(this.token, 'ERC1155InvalidArrayLength') - .withArgs(tokenBatchIds.length, mintValues.length - 1); - - await expect(this.token.$_mintBatch(this.holder, tokenBatchIds.slice(1), mintValues, data)) - .to.be.revertedWithCustomError(this.token, 'ERC1155InvalidArrayLength') - .withArgs(tokenBatchIds.length - 1, mintValues.length); - }); - - describe('with minted batch of tokens', function () { - beforeEach(async function () { - this.tx = await this.token.connect(this.operator).$_mintBatch(this.holder, tokenBatchIds, mintValues, data); - }); - - it('emits a TransferBatch event', async function () { - await expect(this.tx) - .to.emit(this.token, 'TransferBatch') - .withArgs(this.operator, ethers.ZeroAddress, this.holder, tokenBatchIds, mintValues); - }); - - it('credits the minted batch of tokens', async function () { - const holderBatchBalances = await this.token.balanceOfBatch( - tokenBatchIds.map(() => this.holder), - tokenBatchIds, - ); - - expect(holderBatchBalances).to.deep.equal(mintValues); - }); - }); - }); - - describe('_burn', function () { - it("reverts when burning the zero account's tokens", async function () { - await expect(this.token.$_burn(ethers.ZeroAddress, tokenId, mintValue)) - .to.be.revertedWithCustomError(this.token, 'ERC1155InvalidSender') - .withArgs(ethers.ZeroAddress); - }); - - it('reverts when burning a non-existent token id', async function () { - await expect(this.token.$_burn(this.holder, tokenId, mintValue)) - .to.be.revertedWithCustomError(this.token, 'ERC1155InsufficientBalance') - .withArgs(this.holder, 0, mintValue, tokenId); - }); - - it('reverts when burning more than available tokens', async function () { - await this.token.connect(this.operator).$_mint(this.holder, tokenId, mintValue, data); - - await expect(this.token.$_burn(this.holder, tokenId, mintValue + 1n)) - .to.be.revertedWithCustomError(this.token, 'ERC1155InsufficientBalance') - .withArgs(this.holder, mintValue, mintValue + 1n, tokenId); - }); - - describe('with minted-then-burnt tokens', function () { - beforeEach(async function () { - await this.token.$_mint(this.holder, tokenId, mintValue, data); - this.tx = await this.token.connect(this.operator).$_burn(this.holder, tokenId, burnValue); - }); - - it('emits a TransferSingle event', async function () { - await expect(this.tx) - .to.emit(this.token, 'TransferSingle') - .withArgs(this.operator, this.holder, ethers.ZeroAddress, tokenId, burnValue); - }); - - it('accounts for both minting and burning', async function () { - expect(await this.token.balanceOf(this.holder, tokenId)).to.equal(mintValue - burnValue); - }); - }); - }); - - describe('_burnBatch', function () { - it("reverts when burning the zero account's tokens", async function () { - await expect(this.token.$_burnBatch(ethers.ZeroAddress, tokenBatchIds, burnValues)) - .to.be.revertedWithCustomError(this.token, 'ERC1155InvalidSender') - .withArgs(ethers.ZeroAddress); - }); - - it('reverts if length of inputs do not match', async function () { - await expect(this.token.$_burnBatch(this.holder, tokenBatchIds, burnValues.slice(1))) - .to.be.revertedWithCustomError(this.token, 'ERC1155InvalidArrayLength') - .withArgs(tokenBatchIds.length, burnValues.length - 1); - - await expect(this.token.$_burnBatch(this.holder, tokenBatchIds.slice(1), burnValues)) - .to.be.revertedWithCustomError(this.token, 'ERC1155InvalidArrayLength') - .withArgs(tokenBatchIds.length - 1, burnValues.length); - }); - - it('reverts when burning a non-existent token id', async function () { - await expect(this.token.$_burnBatch(this.holder, tokenBatchIds, burnValues)) - .to.be.revertedWithCustomError(this.token, 'ERC1155InsufficientBalance') - .withArgs(this.holder, 0, burnValues[0], tokenBatchIds[0]); - }); - - describe('with minted-then-burnt tokens', function () { - beforeEach(async function () { - await this.token.$_mintBatch(this.holder, tokenBatchIds, mintValues, data); - this.tx = await this.token.connect(this.operator).$_burnBatch(this.holder, tokenBatchIds, burnValues); - }); - - it('emits a TransferBatch event', async function () { - await expect(this.tx) - .to.emit(this.token, 'TransferBatch') - .withArgs(this.operator, this.holder, ethers.ZeroAddress, tokenBatchIds, burnValues); - }); - - it('accounts for both minting and burning', async function () { - const holderBatchBalances = await this.token.balanceOfBatch( - tokenBatchIds.map(() => this.holder), - tokenBatchIds, - ); - - expect(holderBatchBalances).to.deep.equal( - zip(mintValues, burnValues).map(([mintValue, burnValue]) => mintValue - burnValue), - ); - }); - }); - }); - }); - - describe('ERC1155MetadataURI', function () { - const firstTokenID = 42n; - const secondTokenID = 1337n; - - it('emits no URI event in constructor', async function () { - await expect(this.token.deploymentTransaction()).to.not.emit(this.token, 'URI'); - }); - - it('sets the initial URI for all token types', async function () { - expect(await this.token.uri(firstTokenID)).to.equal(initialURI); - expect(await this.token.uri(secondTokenID)).to.equal(initialURI); - }); - - describe('_setURI', function () { - const newURI = 'https://token-cdn-domain/{locale}/{id}.json'; - - it('emits no URI event', async function () { - await expect(this.token.$_setURI(newURI)).to.not.emit(this.token, 'URI'); - }); - - it('sets the new URI for all token types', async function () { - await this.token.$_setURI(newURI); - - expect(await this.token.uri(firstTokenID)).to.equal(newURI); - expect(await this.token.uri(secondTokenID)).to.equal(newURI); - }); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Burnable.test.js b/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Burnable.test.js deleted file mode 100644 index 01e7ee2..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Burnable.test.js +++ /dev/null @@ -1,66 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const ids = [42n, 1137n]; -const values = [3000n, 9902n]; - -async function fixture() { - const [holder, operator, other] = await ethers.getSigners(); - - const token = await ethers.deployContract('$ERC1155Burnable', ['https://token-cdn-domain/{id}.json']); - await token.$_mint(holder, ids[0], values[0], '0x'); - await token.$_mint(holder, ids[1], values[1], '0x'); - - return { token, holder, operator, other }; -} - -describe('ERC1155Burnable', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('burn', function () { - it('holder can burn their tokens', async function () { - await this.token.connect(this.holder).burn(this.holder, ids[0], values[0] - 1n); - - expect(await this.token.balanceOf(this.holder, ids[0])).to.equal(1n); - }); - - it("approved operators can burn the holder's tokens", async function () { - await this.token.connect(this.holder).setApprovalForAll(this.operator, true); - await this.token.connect(this.operator).burn(this.holder, ids[0], values[0] - 1n); - - expect(await this.token.balanceOf(this.holder, ids[0])).to.equal(1n); - }); - - it("unapproved accounts cannot burn the holder's tokens", async function () { - await expect(this.token.connect(this.other).burn(this.holder, ids[0], values[0] - 1n)) - .to.be.revertedWithCustomError(this.token, 'ERC1155MissingApprovalForAll') - .withArgs(this.other, this.holder); - }); - }); - - describe('burnBatch', function () { - it('holder can burn their tokens', async function () { - await this.token.connect(this.holder).burnBatch(this.holder, ids, [values[0] - 1n, values[1] - 2n]); - - expect(await this.token.balanceOf(this.holder, ids[0])).to.equal(1n); - expect(await this.token.balanceOf(this.holder, ids[1])).to.equal(2n); - }); - - it("approved operators can burn the holder's tokens", async function () { - await this.token.connect(this.holder).setApprovalForAll(this.operator, true); - await this.token.connect(this.operator).burnBatch(this.holder, ids, [values[0] - 1n, values[1] - 2n]); - - expect(await this.token.balanceOf(this.holder, ids[0])).to.equal(1n); - expect(await this.token.balanceOf(this.holder, ids[1])).to.equal(2n); - }); - - it("unapproved accounts cannot burn the holder's tokens", async function () { - await expect(this.token.connect(this.other).burnBatch(this.holder, ids, [values[0] - 1n, values[1] - 2n])) - .to.be.revertedWithCustomError(this.token, 'ERC1155MissingApprovalForAll') - .withArgs(this.other, this.holder); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Pausable.test.js b/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Pausable.test.js deleted file mode 100644 index 81c4f69..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Pausable.test.js +++ /dev/null @@ -1,105 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -async function fixture() { - const [holder, operator, receiver, other] = await ethers.getSigners(); - const token = await ethers.deployContract('$ERC1155Pausable', ['https://token-cdn-domain/{id}.json']); - return { token, holder, operator, receiver, other }; -} - -describe('ERC1155Pausable', function () { - const firstTokenId = 37n; - const firstTokenValue = 42n; - const secondTokenId = 19842n; - const secondTokenValue = 23n; - - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('when token is paused', function () { - beforeEach(async function () { - await this.token.connect(this.holder).setApprovalForAll(this.operator, true); - await this.token.$_mint(this.holder, firstTokenId, firstTokenValue, '0x'); - await this.token.$_pause(); - }); - - it('reverts when trying to safeTransferFrom from holder', async function () { - await expect( - this.token - .connect(this.holder) - .safeTransferFrom(this.holder, this.receiver, firstTokenId, firstTokenValue, '0x'), - ).to.be.revertedWithCustomError(this.token, 'EnforcedPause'); - }); - - it('reverts when trying to safeTransferFrom from operator', async function () { - await expect( - this.token - .connect(this.operator) - .safeTransferFrom(this.holder, this.receiver, firstTokenId, firstTokenValue, '0x'), - ).to.be.revertedWithCustomError(this.token, 'EnforcedPause'); - }); - - it('reverts when trying to safeBatchTransferFrom from holder', async function () { - await expect( - this.token - .connect(this.holder) - .safeBatchTransferFrom(this.holder, this.receiver, [firstTokenId], [firstTokenValue], '0x'), - ).to.be.revertedWithCustomError(this.token, 'EnforcedPause'); - }); - - it('reverts when trying to safeBatchTransferFrom from operator', async function () { - await expect( - this.token - .connect(this.operator) - .safeBatchTransferFrom(this.holder, this.receiver, [firstTokenId], [firstTokenValue], '0x'), - ).to.be.revertedWithCustomError(this.token, 'EnforcedPause'); - }); - - it('reverts when trying to mint', async function () { - await expect(this.token.$_mint(this.holder, secondTokenId, secondTokenValue, '0x')).to.be.revertedWithCustomError( - this.token, - 'EnforcedPause', - ); - }); - - it('reverts when trying to mintBatch', async function () { - await expect( - this.token.$_mintBatch(this.holder, [secondTokenId], [secondTokenValue], '0x'), - ).to.be.revertedWithCustomError(this.token, 'EnforcedPause'); - }); - - it('reverts when trying to burn', async function () { - await expect(this.token.$_burn(this.holder, firstTokenId, firstTokenValue)).to.be.revertedWithCustomError( - this.token, - 'EnforcedPause', - ); - }); - - it('reverts when trying to burnBatch', async function () { - await expect( - this.token.$_burnBatch(this.holder, [firstTokenId], [firstTokenValue]), - ).to.be.revertedWithCustomError(this.token, 'EnforcedPause'); - }); - - describe('setApprovalForAll', function () { - it('approves an operator', async function () { - await this.token.connect(this.holder).setApprovalForAll(this.other, true); - expect(await this.token.isApprovedForAll(this.holder, this.other)).to.be.true; - }); - }); - - describe('balanceOf', function () { - it('returns the token value owned by the given address', async function () { - expect(await this.token.balanceOf(this.holder, firstTokenId)).to.equal(firstTokenValue); - }); - }); - - describe('isApprovedForAll', function () { - it('returns the approval of the operator', async function () { - expect(await this.token.isApprovedForAll(this.holder, this.operator)).to.be.true; - }); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Supply.test.js b/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Supply.test.js deleted file mode 100644 index cca36a0..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Supply.test.js +++ /dev/null @@ -1,119 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -async function fixture() { - const [holder] = await ethers.getSigners(); - const token = await ethers.deployContract('$ERC1155Supply', ['https://token-cdn-domain/{id}.json']); - return { token, holder }; -} - -describe('ERC1155Supply', function () { - const firstTokenId = 37n; - const firstTokenValue = 42n; - const secondTokenId = 19842n; - const secondTokenValue = 23n; - - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('before mint', function () { - it('exist', async function () { - expect(await this.token.exists(firstTokenId)).to.be.false; - }); - - it('totalSupply', async function () { - expect(await this.token.totalSupply(ethers.Typed.uint256(firstTokenId))).to.equal(0n); - expect(await this.token.totalSupply()).to.equal(0n); - }); - }); - - describe('after mint', function () { - describe('single', function () { - beforeEach(async function () { - await this.token.$_mint(this.holder, firstTokenId, firstTokenValue, '0x'); - }); - - it('exist', async function () { - expect(await this.token.exists(firstTokenId)).to.be.true; - }); - - it('totalSupply', async function () { - expect(await this.token.totalSupply(ethers.Typed.uint256(firstTokenId))).to.equal(firstTokenValue); - expect(await this.token.totalSupply()).to.equal(firstTokenValue); - }); - }); - - describe('batch', function () { - beforeEach(async function () { - await this.token.$_mintBatch( - this.holder, - [firstTokenId, secondTokenId], - [firstTokenValue, secondTokenValue], - '0x', - ); - }); - - it('exist', async function () { - expect(await this.token.exists(firstTokenId)).to.be.true; - expect(await this.token.exists(secondTokenId)).to.be.true; - }); - - it('totalSupply', async function () { - expect(await this.token.totalSupply(ethers.Typed.uint256(firstTokenId))).to.equal(firstTokenValue); - expect(await this.token.totalSupply(ethers.Typed.uint256(secondTokenId))).to.equal(secondTokenValue); - expect(await this.token.totalSupply()).to.equal(firstTokenValue + secondTokenValue); - }); - }); - }); - - describe('after burn', function () { - describe('single', function () { - beforeEach(async function () { - await this.token.$_mint(this.holder, firstTokenId, firstTokenValue, '0x'); - await this.token.$_burn(this.holder, firstTokenId, firstTokenValue); - }); - - it('exist', async function () { - expect(await this.token.exists(firstTokenId)).to.be.false; - }); - - it('totalSupply', async function () { - expect(await this.token.totalSupply(ethers.Typed.uint256(firstTokenId))).to.equal(0n); - expect(await this.token.totalSupply()).to.equal(0n); - }); - }); - - describe('batch', function () { - beforeEach(async function () { - await this.token.$_mintBatch( - this.holder, - [firstTokenId, secondTokenId], - [firstTokenValue, secondTokenValue], - '0x', - ); - await this.token.$_burnBatch(this.holder, [firstTokenId, secondTokenId], [firstTokenValue, secondTokenValue]); - }); - - it('exist', async function () { - expect(await this.token.exists(firstTokenId)).to.be.false; - expect(await this.token.exists(secondTokenId)).to.be.false; - }); - - it('totalSupply', async function () { - expect(await this.token.totalSupply(ethers.Typed.uint256(firstTokenId))).to.equal(0n); - expect(await this.token.totalSupply(ethers.Typed.uint256(secondTokenId))).to.equal(0n); - expect(await this.token.totalSupply()).to.equal(0n); - }); - }); - }); - - describe('other', function () { - it('supply unaffected by no-op', async function () { - await this.token.$_update(ethers.ZeroAddress, ethers.ZeroAddress, [firstTokenId], [firstTokenValue]); - expect(await this.token.totalSupply(ethers.Typed.uint256(firstTokenId))).to.equal(0n); - expect(await this.token.totalSupply()).to.equal(0n); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155URIStorage.test.js b/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155URIStorage.test.js deleted file mode 100644 index a0d9b57..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155URIStorage.test.js +++ /dev/null @@ -1,70 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const erc1155Uri = 'https://token.com/nfts/'; -const baseUri = 'https://token.com/'; -const tokenId = 1n; -const value = 3000n; - -describe('ERC1155URIStorage', function () { - describe('with base uri set', function () { - async function fixture() { - const [holder] = await ethers.getSigners(); - - const token = await ethers.deployContract('$ERC1155URIStorage', [erc1155Uri]); - await token.$_setBaseURI(baseUri); - await token.$_mint(holder, tokenId, value, '0x'); - - return { token, holder }; - } - - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - it('can request the token uri, returning the erc1155 uri if no token uri was set', async function () { - expect(await this.token.uri(tokenId)).to.equal(erc1155Uri); - }); - - it('can request the token uri, returning the concatenated uri if a token uri was set', async function () { - const tokenUri = '1234/'; - const expectedUri = `${baseUri}${tokenUri}`; - - await expect(this.token.$_setURI(ethers.Typed.uint256(tokenId), tokenUri)) - .to.emit(this.token, 'URI') - .withArgs(expectedUri, tokenId); - - expect(await this.token.uri(tokenId)).to.equal(expectedUri); - }); - }); - - describe('with base uri set to the empty string', function () { - async function fixture() { - const [holder] = await ethers.getSigners(); - - const token = await ethers.deployContract('$ERC1155URIStorage', ['']); - await token.$_mint(holder, tokenId, value, '0x'); - - return { token, holder }; - } - - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - it('can request the token uri, returning an empty string if no token uri was set', async function () { - expect(await this.token.uri(tokenId)).to.equal(''); - }); - - it('can request the token uri, returning the token uri if a token uri was set', async function () { - const tokenUri = 'ipfs://1234/'; - - await expect(this.token.$_setURI(ethers.Typed.uint256(tokenId), tokenUri)) - .to.emit(this.token, 'URI') - .withArgs(tokenUri, tokenId); - - expect(await this.token.uri(tokenId)).to.equal(tokenUri); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC1155/utils/ERC1155Holder.test.js b/lib/openzeppelin-contracts/test/token/ERC1155/utils/ERC1155Holder.test.js deleted file mode 100644 index 9bff487..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC1155/utils/ERC1155Holder.test.js +++ /dev/null @@ -1,56 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { shouldSupportInterfaces } = require('../../../utils/introspection/SupportsInterface.behavior'); - -const ids = [1n, 2n, 3n]; -const values = [1000n, 2000n, 3000n]; -const data = '0x12345678'; - -async function fixture() { - const [owner] = await ethers.getSigners(); - - const token = await ethers.deployContract('$ERC1155', ['https://token-cdn-domain/{id}.json']); - const mock = await ethers.deployContract('$ERC1155Holder'); - - await token.$_mintBatch(owner, ids, values, '0x'); - - return { owner, token, mock }; -} - -describe('ERC1155Holder', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - shouldSupportInterfaces(['ERC1155Receiver']); - - it('receives ERC1155 tokens from a single ID', async function () { - await this.token.connect(this.owner).safeTransferFrom(this.owner, this.mock, ids[0], values[0], data); - - expect(await this.token.balanceOf(this.mock, ids[0])).to.equal(values[0]); - - for (let i = 1; i < ids.length; i++) { - expect(await this.token.balanceOf(this.mock, ids[i])).to.equal(0n); - } - }); - - it('receives ERC1155 tokens from a multiple IDs', async function () { - expect( - await this.token.balanceOfBatch( - ids.map(() => this.mock), - ids, - ), - ).to.deep.equal(ids.map(() => 0n)); - - await this.token.connect(this.owner).safeBatchTransferFrom(this.owner, this.mock, ids, values, data); - - expect( - await this.token.balanceOfBatch( - ids.map(() => this.mock), - ids, - ), - ).to.deep.equal(values); - }); -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC1155/utils/ERC1155Utils.test.js b/lib/openzeppelin-contracts/test/token/ERC1155/utils/ERC1155Utils.test.js deleted file mode 100644 index 5687568..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC1155/utils/ERC1155Utils.test.js +++ /dev/null @@ -1,299 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { RevertType } = require('../../../helpers/enums'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); - -const firstTokenId = 1n; -const secondTokenId = 2n; -const firstTokenValue = 1000n; -const secondTokenValue = 1000n; - -const RECEIVER_SINGLE_MAGIC_VALUE = '0xf23a6e61'; -const RECEIVER_BATCH_MAGIC_VALUE = '0xbc197c81'; - -const deployReceiver = ( - revertType, - returnValueSingle = RECEIVER_SINGLE_MAGIC_VALUE, - returnValueBatched = RECEIVER_BATCH_MAGIC_VALUE, -) => ethers.deployContract('$ERC1155ReceiverMock', [returnValueSingle, returnValueBatched, revertType]); - -const fixture = async () => { - const [eoa, operator, owner] = await ethers.getSigners(); - const utils = await ethers.deployContract('$ERC1155Utils'); - - const receivers = { - correct: await deployReceiver(RevertType.None), - invalid: await deployReceiver(RevertType.None, '0xdeadbeef', '0xdeadbeef'), - message: await deployReceiver(RevertType.RevertWithMessage), - empty: await deployReceiver(RevertType.RevertWithoutMessage), - customError: await deployReceiver(RevertType.RevertWithCustomError), - panic: await deployReceiver(RevertType.Panic), - nonReceiver: await ethers.deployContract('CallReceiverMock'), - eoa, - }; - - return { operator, owner, utils, receivers }; -}; - -describe('ERC1155Utils', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('onERC1155Received', function () { - it('succeeds when called by an EOA', async function () { - await expect( - this.utils.$checkOnERC1155Received( - this.operator, - this.owner, - this.receivers.eoa, - firstTokenId, - firstTokenValue, - '0x', - ), - ).to.not.be.reverted; - }); - - it('succeeds when data is passed', async function () { - const data = '0x12345678'; - await expect( - this.utils.$checkOnERC1155Received( - this.operator, - this.owner, - this.receivers.correct, - firstTokenId, - firstTokenValue, - data, - ), - ).to.not.be.reverted; - }); - - it('succeeds when data is empty', async function () { - await expect( - this.utils.$checkOnERC1155Received( - this.operator, - this.owner, - this.receivers.correct, - firstTokenId, - firstTokenValue, - '0x', - ), - ).to.not.be.reverted; - }); - - it('reverts when receiver returns invalid value', async function () { - await expect( - this.utils.$checkOnERC1155Received( - this.operator, - this.owner, - this.receivers.invalid, - firstTokenId, - firstTokenValue, - '0x', - ), - ) - .to.be.revertedWithCustomError(this.utils, 'ERC1155InvalidReceiver') - .withArgs(this.receivers.invalid); - }); - - it('reverts when receiver reverts with message', async function () { - await expect( - this.utils.$checkOnERC1155Received( - this.operator, - this.owner, - this.receivers.message, - firstTokenId, - firstTokenValue, - '0x', - ), - ).to.be.revertedWith('ERC1155ReceiverMock: reverting on receive'); - }); - - it('reverts when receiver reverts without message', async function () { - await expect( - this.utils.$checkOnERC1155Received( - this.operator, - this.owner, - this.receivers.empty, - firstTokenId, - firstTokenValue, - '0x', - ), - ) - .to.be.revertedWithCustomError(this.utils, 'ERC1155InvalidReceiver') - .withArgs(this.receivers.empty); - }); - - it('reverts when receiver reverts with custom error', async function () { - await expect( - this.utils.$checkOnERC1155Received( - this.operator, - this.owner, - this.receivers.customError, - firstTokenId, - firstTokenValue, - '0x', - ), - ) - .to.be.revertedWithCustomError(this.receivers.customError, 'CustomError') - .withArgs(RECEIVER_SINGLE_MAGIC_VALUE); - }); - - it('reverts when receiver panics', async function () { - await expect( - this.utils.$checkOnERC1155Received( - this.operator, - this.owner, - this.receivers.panic, - firstTokenId, - firstTokenValue, - '0x', - ), - ).to.be.revertedWithPanic(PANIC_CODES.DIVISION_BY_ZERO); - }); - - it('reverts when receiver does not implement onERC1155Received', async function () { - await expect( - this.utils.$checkOnERC1155Received( - this.operator, - this.owner, - this.receivers.nonReceiver, - firstTokenId, - firstTokenValue, - '0x', - ), - ) - .to.be.revertedWithCustomError(this.utils, 'ERC1155InvalidReceiver') - .withArgs(this.receivers.nonReceiver); - }); - }); - - describe('onERC1155BatchReceived', function () { - it('succeeds when called by an EOA', async function () { - await expect( - this.utils.$checkOnERC1155BatchReceived( - this.operator, - this.owner, - this.receivers.eoa, - [firstTokenId, secondTokenId], - [firstTokenValue, secondTokenValue], - '0x', - ), - ).to.not.be.reverted; - }); - - it('succeeds when data is passed', async function () { - const data = '0x12345678'; - await expect( - this.utils.$checkOnERC1155BatchReceived( - this.operator, - this.owner, - this.receivers.correct, - [firstTokenId, secondTokenId], - [firstTokenValue, secondTokenValue], - data, - ), - ).to.not.be.reverted; - }); - - it('succeeds when data is empty', async function () { - await expect( - this.utils.$checkOnERC1155BatchReceived( - this.operator, - this.owner, - this.receivers.correct, - [firstTokenId, secondTokenId], - [firstTokenValue, secondTokenValue], - '0x', - ), - ).to.not.be.reverted; - }); - - it('reverts when receiver returns invalid value', async function () { - await expect( - this.utils.$checkOnERC1155BatchReceived( - this.operator, - this.owner, - this.receivers.invalid, - [firstTokenId, secondTokenId], - [firstTokenValue, secondTokenValue], - '0x', - ), - ) - .to.be.revertedWithCustomError(this.utils, 'ERC1155InvalidReceiver') - .withArgs(this.receivers.invalid); - }); - - it('reverts when receiver reverts with message', async function () { - await expect( - this.utils.$checkOnERC1155BatchReceived( - this.operator, - this.owner, - this.receivers.message, - [firstTokenId, secondTokenId], - [firstTokenValue, secondTokenValue], - '0x', - ), - ).to.be.revertedWith('ERC1155ReceiverMock: reverting on batch receive'); - }); - - it('reverts when receiver reverts without message', async function () { - await expect( - this.utils.$checkOnERC1155BatchReceived( - this.operator, - this.owner, - this.receivers.empty, - [firstTokenId, secondTokenId], - [firstTokenValue, secondTokenValue], - '0x', - ), - ) - .to.be.revertedWithCustomError(this.utils, 'ERC1155InvalidReceiver') - .withArgs(this.receivers.empty); - }); - - it('reverts when receiver reverts with custom error', async function () { - await expect( - this.utils.$checkOnERC1155BatchReceived( - this.operator, - this.owner, - this.receivers.customError, - [firstTokenId, secondTokenId], - [firstTokenValue, secondTokenValue], - '0x', - ), - ) - .to.be.revertedWithCustomError(this.receivers.customError, 'CustomError') - .withArgs(RECEIVER_SINGLE_MAGIC_VALUE); - }); - - it('reverts when receiver panics', async function () { - await expect( - this.utils.$checkOnERC1155BatchReceived( - this.operator, - this.owner, - this.receivers.panic, - [firstTokenId, secondTokenId], - [firstTokenValue, secondTokenValue], - '0x', - ), - ).to.be.revertedWithPanic(PANIC_CODES.DIVISION_BY_ZERO); - }); - - it('reverts when receiver does not implement onERC1155BatchReceived', async function () { - await expect( - this.utils.$checkOnERC1155BatchReceived( - this.operator, - this.owner, - this.receivers.nonReceiver, - [firstTokenId, secondTokenId], - [firstTokenValue, secondTokenValue], - '0x', - ), - ) - .to.be.revertedWithCustomError(this.utils, 'ERC1155InvalidReceiver') - .withArgs(this.receivers.nonReceiver); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC20/ERC20.behavior.js b/lib/openzeppelin-contracts/test/token/ERC20/ERC20.behavior.js deleted file mode 100644 index 6754bff..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC20/ERC20.behavior.js +++ /dev/null @@ -1,260 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); - -function shouldBehaveLikeERC20(initialSupply, opts = {}) { - const { forcedApproval } = opts; - - beforeEach(async function () { - [this.holder, this.recipient, this.other] = this.accounts; - }); - - it('total supply: returns the total token value', async function () { - expect(await this.token.totalSupply()).to.equal(initialSupply); - }); - - describe('balanceOf', function () { - it('returns zero when the requested account has no tokens', async function () { - expect(await this.token.balanceOf(this.other)).to.equal(0n); - }); - - it('returns the total token value when the requested account has some tokens', async function () { - expect(await this.token.balanceOf(this.holder)).to.equal(initialSupply); - }); - }); - - describe('transfer', function () { - beforeEach(function () { - this.transfer = (from, to, value) => this.token.connect(from).transfer(to, value); - }); - - shouldBehaveLikeERC20Transfer(initialSupply); - }); - - describe('transfer from', function () { - describe('when the token owner is not the zero address', function () { - describe('when the recipient is not the zero address', function () { - describe('when the spender has enough allowance', function () { - beforeEach(async function () { - await this.token.connect(this.holder).approve(this.recipient, initialSupply); - }); - - describe('when the token owner has enough balance', function () { - const value = initialSupply; - - beforeEach(async function () { - this.tx = await this.token.connect(this.recipient).transferFrom(this.holder, this.other, value); - }); - - it('transfers the requested value', async function () { - await expect(this.tx).to.changeTokenBalances(this.token, [this.holder, this.other], [-value, value]); - }); - - it('decreases the spender allowance', async function () { - expect(await this.token.allowance(this.holder, this.recipient)).to.equal(0n); - }); - - it('emits a transfer event', async function () { - await expect(this.tx).to.emit(this.token, 'Transfer').withArgs(this.holder, this.other, value); - }); - - if (forcedApproval) { - it('emits an approval event', async function () { - await expect(this.tx) - .to.emit(this.token, 'Approval') - .withArgs( - this.holder.address, - this.recipient.address, - await this.token.allowance(this.holder, this.recipient), - ); - }); - } else { - it('does not emit an approval event', async function () { - await expect(this.tx).to.not.emit(this.token, 'Approval'); - }); - } - }); - - it('reverts when the token owner does not have enough balance', async function () { - const value = initialSupply; - await this.token.connect(this.holder).transfer(this.other, 1n); - await expect(this.token.connect(this.recipient).transferFrom(this.holder, this.other, value)) - .to.revertedWithCustomError(this.token, 'ERC20InsufficientBalance') - .withArgs(this.holder, value - 1n, value); - }); - }); - - describe('when the spender does not have enough allowance', function () { - const allowance = initialSupply - 1n; - - beforeEach(async function () { - await this.token.connect(this.holder).approve(this.recipient, allowance); - }); - - it('reverts when the token owner has enough balance', async function () { - const value = initialSupply; - await expect(this.token.connect(this.recipient).transferFrom(this.holder, this.other, value)) - .to.be.revertedWithCustomError(this.token, 'ERC20InsufficientAllowance') - .withArgs(this.recipient, allowance, value); - }); - - it('reverts when the token owner does not have enough balance', async function () { - const value = allowance; - await this.token.connect(this.holder).transfer(this.other, 2); - await expect(this.token.connect(this.recipient).transferFrom(this.holder, this.other, value)) - .to.be.revertedWithCustomError(this.token, 'ERC20InsufficientBalance') - .withArgs(this.holder, value - 1n, value); - }); - }); - - describe('when the spender has unlimited allowance', function () { - beforeEach(async function () { - await this.token.connect(this.holder).approve(this.recipient, ethers.MaxUint256); - this.tx = await this.token.connect(this.recipient).transferFrom(this.holder, this.other, 1n); - }); - - it('does not decrease the spender allowance', async function () { - expect(await this.token.allowance(this.holder, this.recipient)).to.equal(ethers.MaxUint256); - }); - - it('does not emit an approval event', async function () { - await expect(this.tx).to.not.emit(this.token, 'Approval'); - }); - }); - }); - - it('reverts when the recipient is the zero address', async function () { - const value = initialSupply; - await this.token.connect(this.holder).approve(this.recipient, value); - await expect(this.token.connect(this.recipient).transferFrom(this.holder, ethers.ZeroAddress, value)) - .to.be.revertedWithCustomError(this.token, 'ERC20InvalidReceiver') - .withArgs(ethers.ZeroAddress); - }); - }); - - it('reverts when the token owner is the zero address', async function () { - const value = 0n; - await expect(this.token.connect(this.recipient).transferFrom(ethers.ZeroAddress, this.recipient, value)) - .to.be.revertedWithCustomError(this.token, 'ERC20InvalidApprover') - .withArgs(ethers.ZeroAddress); - }); - }); - - describe('approve', function () { - beforeEach(function () { - this.approve = (owner, spender, value) => this.token.connect(owner).approve(spender, value); - }); - - shouldBehaveLikeERC20Approve(initialSupply); - }); -} - -function shouldBehaveLikeERC20Transfer(balance) { - describe('when the recipient is not the zero address', function () { - it('reverts when the sender does not have enough balance', async function () { - const value = balance + 1n; - await expect(this.transfer(this.holder, this.recipient, value)) - .to.be.revertedWithCustomError(this.token, 'ERC20InsufficientBalance') - .withArgs(this.holder, balance, value); - }); - - describe('when the sender transfers all balance', function () { - const value = balance; - - beforeEach(async function () { - this.tx = await this.transfer(this.holder, this.recipient, value); - }); - - it('transfers the requested value', async function () { - await expect(this.tx).to.changeTokenBalances(this.token, [this.holder, this.recipient], [-value, value]); - }); - - it('emits a transfer event', async function () { - await expect(this.tx).to.emit(this.token, 'Transfer').withArgs(this.holder, this.recipient, value); - }); - }); - - describe('when the sender transfers zero tokens', function () { - const value = 0n; - - beforeEach(async function () { - this.tx = await this.transfer(this.holder, this.recipient, value); - }); - - it('transfers the requested value', async function () { - await expect(this.tx).to.changeTokenBalances(this.token, [this.holder, this.recipient], [0n, 0n]); - }); - - it('emits a transfer event', async function () { - await expect(this.tx).to.emit(this.token, 'Transfer').withArgs(this.holder, this.recipient, value); - }); - }); - }); - - it('reverts when the recipient is the zero address', async function () { - await expect(this.transfer(this.holder, ethers.ZeroAddress, balance)) - .to.be.revertedWithCustomError(this.token, 'ERC20InvalidReceiver') - .withArgs(ethers.ZeroAddress); - }); -} - -function shouldBehaveLikeERC20Approve(supply) { - describe('when the spender is not the zero address', function () { - describe('when the sender has enough balance', function () { - const value = supply; - - it('emits an approval event', async function () { - await expect(this.approve(this.holder, this.recipient, value)) - .to.emit(this.token, 'Approval') - .withArgs(this.holder, this.recipient, value); - }); - - it('approves the requested value when there was no approved value before', async function () { - await this.approve(this.holder, this.recipient, value); - - expect(await this.token.allowance(this.holder, this.recipient)).to.equal(value); - }); - - it('approves the requested value and replaces the previous one when the spender had an approved value', async function () { - await this.approve(this.holder, this.recipient, 1n); - await this.approve(this.holder, this.recipient, value); - - expect(await this.token.allowance(this.holder, this.recipient)).to.equal(value); - }); - }); - - describe('when the sender does not have enough balance', function () { - const value = supply + 1n; - - it('emits an approval event', async function () { - await expect(this.approve(this.holder, this.recipient, value)) - .to.emit(this.token, 'Approval') - .withArgs(this.holder, this.recipient, value); - }); - - it('approves the requested value when there was no approved value before', async function () { - await this.approve(this.holder, this.recipient, value); - - expect(await this.token.allowance(this.holder, this.recipient)).to.equal(value); - }); - - it('approves the requested value and replaces the previous one when the spender had an approved value', async function () { - await this.approve(this.holder, this.recipient, 1n); - await this.approve(this.holder, this.recipient, value); - - expect(await this.token.allowance(this.holder, this.recipient)).to.equal(value); - }); - }); - }); - - it('reverts when the spender is the zero address', async function () { - await expect(this.approve(this.holder, ethers.ZeroAddress, supply)) - .to.be.revertedWithCustomError(this.token, `ERC20InvalidSpender`) - .withArgs(ethers.ZeroAddress); - }); -} - -module.exports = { - shouldBehaveLikeERC20, - shouldBehaveLikeERC20Transfer, - shouldBehaveLikeERC20Approve, -}; diff --git a/lib/openzeppelin-contracts/test/token/ERC20/ERC20.test.js b/lib/openzeppelin-contracts/test/token/ERC20/ERC20.test.js deleted file mode 100644 index 2d9eefe..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC20/ERC20.test.js +++ /dev/null @@ -1,199 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); - -const { - shouldBehaveLikeERC20, - shouldBehaveLikeERC20Transfer, - shouldBehaveLikeERC20Approve, -} = require('./ERC20.behavior'); - -const TOKENS = [{ Token: '$ERC20' }, { Token: '$ERC20ApprovalMock', forcedApproval: true }]; - -const name = 'My Token'; -const symbol = 'MTKN'; -const initialSupply = 100n; - -describe('ERC20', function () { - for (const { Token, forcedApproval } of TOKENS) { - describe(Token, function () { - const fixture = async () => { - // this.accounts is used by shouldBehaveLikeERC20 - const accounts = await ethers.getSigners(); - const [holder, recipient] = accounts; - - const token = await ethers.deployContract(Token, [name, symbol]); - await token.$_mint(holder, initialSupply); - - return { accounts, holder, recipient, token }; - }; - - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - shouldBehaveLikeERC20(initialSupply, { forcedApproval }); - - 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.equal(18n); - }); - - describe('_mint', function () { - const value = 50n; - it('rejects a null account', async function () { - await expect(this.token.$_mint(ethers.ZeroAddress, value)) - .to.be.revertedWithCustomError(this.token, 'ERC20InvalidReceiver') - .withArgs(ethers.ZeroAddress); - }); - - it('rejects overflow', async function () { - await expect(this.token.$_mint(this.recipient, ethers.MaxUint256)).to.be.revertedWithPanic( - PANIC_CODES.ARITHMETIC_UNDER_OR_OVERFLOW, - ); - }); - - describe('for a non zero account', function () { - beforeEach('minting', async function () { - this.tx = await this.token.$_mint(this.recipient, value); - }); - - it('increments totalSupply', async function () { - await expect(await this.token.totalSupply()).to.equal(initialSupply + value); - }); - - it('increments recipient balance', async function () { - await expect(this.tx).to.changeTokenBalance(this.token, this.recipient, value); - }); - - it('emits Transfer event', async function () { - await expect(this.tx).to.emit(this.token, 'Transfer').withArgs(ethers.ZeroAddress, this.recipient, value); - }); - }); - }); - - describe('_burn', function () { - it('rejects a null account', async function () { - await expect(this.token.$_burn(ethers.ZeroAddress, 1n)) - .to.be.revertedWithCustomError(this.token, 'ERC20InvalidSender') - .withArgs(ethers.ZeroAddress); - }); - - describe('for a non zero account', function () { - it('rejects burning more than balance', async function () { - await expect(this.token.$_burn(this.holder, initialSupply + 1n)) - .to.be.revertedWithCustomError(this.token, 'ERC20InsufficientBalance') - .withArgs(this.holder, initialSupply, initialSupply + 1n); - }); - - const describeBurn = function (description, value) { - describe(description, function () { - beforeEach('burning', async function () { - this.tx = await this.token.$_burn(this.holder, value); - }); - - it('decrements totalSupply', async function () { - expect(await this.token.totalSupply()).to.equal(initialSupply - value); - }); - - it('decrements holder balance', async function () { - await expect(this.tx).to.changeTokenBalance(this.token, this.holder, -value); - }); - - it('emits Transfer event', async function () { - await expect(this.tx).to.emit(this.token, 'Transfer').withArgs(this.holder, ethers.ZeroAddress, value); - }); - }); - }; - - describeBurn('for entire balance', initialSupply); - describeBurn('for less value than balance', initialSupply - 1n); - }); - }); - - describe('_update', function () { - const value = 1n; - - beforeEach(async function () { - this.totalSupply = await this.token.totalSupply(); - }); - - it('from is the zero address', async function () { - const tx = await this.token.$_update(ethers.ZeroAddress, this.holder, value); - await expect(tx).to.emit(this.token, 'Transfer').withArgs(ethers.ZeroAddress, this.holder, value); - - expect(await this.token.totalSupply()).to.equal(this.totalSupply + value); - await expect(tx).to.changeTokenBalance(this.token, this.holder, value); - }); - - it('to is the zero address', async function () { - const tx = await this.token.$_update(this.holder, ethers.ZeroAddress, value); - await expect(tx).to.emit(this.token, 'Transfer').withArgs(this.holder, ethers.ZeroAddress, value); - - expect(await this.token.totalSupply()).to.equal(this.totalSupply - value); - await expect(tx).to.changeTokenBalance(this.token, this.holder, -value); - }); - - describe('from and to are the same address', function () { - it('zero address', async function () { - const tx = await this.token.$_update(ethers.ZeroAddress, ethers.ZeroAddress, value); - await expect(tx).to.emit(this.token, 'Transfer').withArgs(ethers.ZeroAddress, ethers.ZeroAddress, value); - - expect(await this.token.totalSupply()).to.equal(this.totalSupply); - await expect(tx).to.changeTokenBalance(this.token, ethers.ZeroAddress, 0n); - }); - - describe('non zero address', function () { - it('reverts without balance', async function () { - await expect(this.token.$_update(this.recipient, this.recipient, value)) - .to.be.revertedWithCustomError(this.token, 'ERC20InsufficientBalance') - .withArgs(this.recipient, 0n, value); - }); - - it('executes with balance', async function () { - const tx = await this.token.$_update(this.holder, this.holder, value); - await expect(tx).to.changeTokenBalance(this.token, this.holder, 0n); - await expect(tx).to.emit(this.token, 'Transfer').withArgs(this.holder, this.holder, value); - }); - }); - }); - }); - - describe('_transfer', function () { - beforeEach(function () { - this.transfer = this.token.$_transfer; - }); - - shouldBehaveLikeERC20Transfer(initialSupply); - - it('reverts when the sender is the zero address', async function () { - await expect(this.token.$_transfer(ethers.ZeroAddress, this.recipient, initialSupply)) - .to.be.revertedWithCustomError(this.token, 'ERC20InvalidSender') - .withArgs(ethers.ZeroAddress); - }); - }); - - describe('_approve', function () { - beforeEach(function () { - this.approve = this.token.$_approve; - }); - - shouldBehaveLikeERC20Approve(initialSupply); - - it('reverts when the owner is the zero address', async function () { - await expect(this.token.$_approve(ethers.ZeroAddress, this.recipient, initialSupply)) - .to.be.revertedWithCustomError(this.token, 'ERC20InvalidApprover') - .withArgs(ethers.ZeroAddress); - }); - }); - }); - } -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC1363.test.js b/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC1363.test.js deleted file mode 100644 index 3d1f4e5..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC1363.test.js +++ /dev/null @@ -1,370 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { - shouldBehaveLikeERC20, - shouldBehaveLikeERC20Transfer, - shouldBehaveLikeERC20Approve, -} = require('../ERC20.behavior.js'); -const { shouldSupportInterfaces } = require('../../../utils/introspection/SupportsInterface.behavior'); -const { RevertType } = require('../../../helpers/enums.js'); - -const name = 'My Token'; -const symbol = 'MTKN'; -const value = 1000n; -const data = '0x123456'; - -async function fixture() { - // this.accounts is used by shouldBehaveLikeERC20 - const accounts = await ethers.getSigners(); - const [holder, other] = accounts; - - const receiver = await ethers.deployContract('ERC1363ReceiverMock'); - const spender = await ethers.deployContract('ERC1363SpenderMock'); - const token = await ethers.deployContract('$ERC1363', [name, symbol]); - - await token.$_mint(holder, value); - - return { - accounts, - holder, - other, - token, - receiver, - spender, - selectors: { - onTransferReceived: receiver.interface.getFunction('onTransferReceived(address,address,uint256,bytes)').selector, - onApprovalReceived: spender.interface.getFunction('onApprovalReceived(address,uint256,bytes)').selector, - }, - }; -} - -describe('ERC1363', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - shouldSupportInterfaces(['ERC165', 'ERC1363']); - shouldBehaveLikeERC20(value); - - describe('transferAndCall', function () { - describe('as a transfer', function () { - beforeEach(async function () { - this.recipient = this.receiver; - this.transfer = (holder, ...rest) => - this.token.connect(holder).getFunction('transferAndCall(address,uint256)')(...rest); - }); - - shouldBehaveLikeERC20Transfer(value); - }); - - it('reverts transferring to an EOA', async function () { - await expect(this.token.connect(this.holder).getFunction('transferAndCall(address,uint256)')(this.other, value)) - .to.be.revertedWithCustomError(this.token, 'ERC1363InvalidReceiver') - .withArgs(this.other.address); - }); - - it('succeeds without data', async function () { - await expect( - this.token.connect(this.holder).getFunction('transferAndCall(address,uint256)')(this.receiver, value), - ) - .to.emit(this.token, 'Transfer') - .withArgs(this.holder.address, this.receiver.target, value) - .to.emit(this.receiver, 'Received') - .withArgs(this.holder.address, this.holder.address, value, '0x'); - }); - - it('succeeds with data', async function () { - await expect( - this.token.connect(this.holder).getFunction('transferAndCall(address,uint256,bytes)')( - this.receiver, - value, - data, - ), - ) - .to.emit(this.token, 'Transfer') - .withArgs(this.holder.address, this.receiver.target, value) - .to.emit(this.receiver, 'Received') - .withArgs(this.holder.address, this.holder.address, value, data); - }); - - it('reverts with reverting hook (without reason)', async function () { - await this.receiver.setUp(this.selectors.onTransferReceived, RevertType.RevertWithoutMessage); - - await expect( - this.token.connect(this.holder).getFunction('transferAndCall(address,uint256,bytes)')( - this.receiver, - value, - data, - ), - ) - .to.be.revertedWithCustomError(this.token, 'ERC1363InvalidReceiver') - .withArgs(this.receiver.target); - }); - - it('reverts with reverting hook (with reason)', async function () { - await this.receiver.setUp(this.selectors.onTransferReceived, RevertType.RevertWithMessage); - - await expect( - this.token.connect(this.holder).getFunction('transferAndCall(address,uint256,bytes)')( - this.receiver, - value, - data, - ), - ).to.be.revertedWith('ERC1363ReceiverMock: reverting'); - }); - - it('reverts with reverting hook (with custom error)', async function () { - const reason = '0x12345678'; - await this.receiver.setUp(reason, RevertType.RevertWithCustomError); - - await expect( - this.token.connect(this.holder).getFunction('transferAndCall(address,uint256,bytes)')( - this.receiver, - value, - data, - ), - ) - .to.be.revertedWithCustomError(this.receiver, 'CustomError') - .withArgs(reason); - }); - - it('panics with reverting hook (with panic)', async function () { - await this.receiver.setUp(this.selectors.onTransferReceived, RevertType.Panic); - - await expect( - this.token.connect(this.holder).getFunction('transferAndCall(address,uint256,bytes)')( - this.receiver, - value, - data, - ), - ).to.be.revertedWithPanic(); - }); - - it('reverts with bad return value', async function () { - await this.receiver.setUp('0x12345678', RevertType.None); - - await expect( - this.token.connect(this.holder).getFunction('transferAndCall(address,uint256,bytes)')( - this.receiver, - value, - data, - ), - ) - .to.be.revertedWithCustomError(this.token, 'ERC1363InvalidReceiver') - .withArgs(this.receiver.target); - }); - }); - - describe('transferFromAndCall', function () { - beforeEach(async function () { - await this.token.connect(this.holder).approve(this.other, ethers.MaxUint256); - }); - - describe('as a transfer', function () { - beforeEach(async function () { - this.recipient = this.receiver; - this.transfer = this.token.connect(this.other).getFunction('transferFromAndCall(address,address,uint256)'); - }); - - shouldBehaveLikeERC20Transfer(value); - }); - - it('reverts transferring to an EOA', async function () { - await expect( - this.token.connect(this.other).getFunction('transferFromAndCall(address,address,uint256)')( - this.holder, - this.other, - value, - ), - ) - .to.be.revertedWithCustomError(this.token, 'ERC1363InvalidReceiver') - .withArgs(this.other.address); - }); - - it('succeeds without data', async function () { - await expect( - this.token.connect(this.other).getFunction('transferFromAndCall(address,address,uint256)')( - this.holder, - this.receiver, - value, - ), - ) - .to.emit(this.token, 'Transfer') - .withArgs(this.holder.address, this.receiver.target, value) - .to.emit(this.receiver, 'Received') - .withArgs(this.other.address, this.holder.address, value, '0x'); - }); - - it('succeeds with data', async function () { - await expect( - this.token.connect(this.other).getFunction('transferFromAndCall(address,address,uint256,bytes)')( - this.holder, - this.receiver, - value, - data, - ), - ) - .to.emit(this.token, 'Transfer') - .withArgs(this.holder.address, this.receiver.target, value) - .to.emit(this.receiver, 'Received') - .withArgs(this.other.address, this.holder.address, value, data); - }); - - it('reverts with reverting hook (without reason)', async function () { - await this.receiver.setUp(this.selectors.onTransferReceived, RevertType.RevertWithoutMessage); - - await expect( - this.token.connect(this.other).getFunction('transferFromAndCall(address,address,uint256,bytes)')( - this.holder, - this.receiver, - value, - data, - ), - ) - .to.be.revertedWithCustomError(this.token, 'ERC1363InvalidReceiver') - .withArgs(this.receiver.target); - }); - - it('reverts with reverting hook (with reason)', async function () { - await this.receiver.setUp(this.selectors.onTransferReceived, RevertType.RevertWithMessage); - - await expect( - this.token.connect(this.other).getFunction('transferFromAndCall(address,address,uint256,bytes)')( - this.holder, - this.receiver, - value, - data, - ), - ).to.be.revertedWith('ERC1363ReceiverMock: reverting'); - }); - - it('reverts with reverting hook (with custom error)', async function () { - const reason = '0x12345678'; - await this.receiver.setUp(reason, RevertType.RevertWithCustomError); - - await expect( - this.token.connect(this.other).getFunction('transferFromAndCall(address,address,uint256,bytes)')( - this.holder, - this.receiver, - value, - data, - ), - ) - .to.be.revertedWithCustomError(this.receiver, 'CustomError') - .withArgs(reason); - }); - - it('panics with reverting hook (with panic)', async function () { - await this.receiver.setUp(this.selectors.onTransferReceived, RevertType.Panic); - - await expect( - this.token.connect(this.other).getFunction('transferFromAndCall(address,address,uint256,bytes)')( - this.holder, - this.receiver, - value, - data, - ), - ).to.be.revertedWithPanic(); - }); - - it('reverts with bad return value', async function () { - await this.receiver.setUp('0x12345678', RevertType.None); - - await expect( - this.token.connect(this.other).getFunction('transferFromAndCall(address,address,uint256,bytes)')( - this.holder, - this.receiver, - value, - data, - ), - ) - .to.be.revertedWithCustomError(this.token, 'ERC1363InvalidReceiver') - .withArgs(this.receiver.target); - }); - }); - - describe('approveAndCall', function () { - describe('as an approval', function () { - beforeEach(async function () { - this.recipient = this.spender; - this.approve = (holder, ...rest) => - this.token.connect(holder).getFunction('approveAndCall(address,uint256)')(...rest); - }); - - shouldBehaveLikeERC20Approve(value); - }); - - it('reverts approving an EOA', async function () { - await expect(this.token.connect(this.holder).getFunction('approveAndCall(address,uint256)')(this.other, value)) - .to.be.revertedWithCustomError(this.token, 'ERC1363InvalidSpender') - .withArgs(this.other.address); - }); - - it('succeeds without data', async function () { - await expect(this.token.connect(this.holder).getFunction('approveAndCall(address,uint256)')(this.spender, value)) - .to.emit(this.token, 'Approval') - .withArgs(this.holder.address, this.spender.target, value) - .to.emit(this.spender, 'Approved') - .withArgs(this.holder.address, value, '0x'); - }); - - it('succeeds with data', async function () { - await expect( - this.token.connect(this.holder).getFunction('approveAndCall(address,uint256,bytes)')(this.spender, value, data), - ) - .to.emit(this.token, 'Approval') - .withArgs(this.holder.address, this.spender.target, value) - .to.emit(this.spender, 'Approved') - .withArgs(this.holder.address, value, data); - }); - - it('with reverting hook (without reason)', async function () { - await this.spender.setUp(this.selectors.onApprovalReceived, RevertType.RevertWithoutMessage); - - await expect( - this.token.connect(this.holder).getFunction('approveAndCall(address,uint256,bytes)')(this.spender, value, data), - ) - .to.be.revertedWithCustomError(this.token, 'ERC1363InvalidSpender') - .withArgs(this.spender.target); - }); - - it('reverts with reverting hook (with reason)', async function () { - await this.spender.setUp(this.selectors.onApprovalReceived, RevertType.RevertWithMessage); - - await expect( - this.token.connect(this.holder).getFunction('approveAndCall(address,uint256,bytes)')(this.spender, value, data), - ).to.be.revertedWith('ERC1363SpenderMock: reverting'); - }); - - it('reverts with reverting hook (with custom error)', async function () { - const reason = '0x12345678'; - await this.spender.setUp(reason, RevertType.RevertWithCustomError); - - await expect( - this.token.connect(this.holder).getFunction('approveAndCall(address,uint256,bytes)')(this.spender, value, data), - ) - .to.be.revertedWithCustomError(this.spender, 'CustomError') - .withArgs(reason); - }); - - it('panics with reverting hook (with panic)', async function () { - await this.spender.setUp(this.selectors.onApprovalReceived, RevertType.Panic); - - await expect( - this.token.connect(this.holder).getFunction('approveAndCall(address,uint256,bytes)')(this.spender, value, data), - ).to.be.revertedWithPanic(); - }); - - it('reverts with bad return value', async function () { - await this.spender.setUp('0x12345678', RevertType.None); - - await expect( - this.token.connect(this.holder).getFunction('approveAndCall(address,uint256,bytes)')(this.spender, value, data), - ) - .to.be.revertedWithCustomError(this.token, 'ERC1363InvalidSpender') - .withArgs(this.spender.target); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Burnable.test.js b/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Burnable.test.js deleted file mode 100644 index dc40c79..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Burnable.test.js +++ /dev/null @@ -1,105 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const name = 'My Token'; -const symbol = 'MTKN'; -const initialBalance = 1000n; - -async function fixture() { - const [owner, burner] = await ethers.getSigners(); - - const token = await ethers.deployContract('$ERC20Burnable', [name, symbol], owner); - await token.$_mint(owner, initialBalance); - - return { owner, burner, token, initialBalance }; -} - -describe('ERC20Burnable', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('burn', function () { - it('reverts if not enough balance', async function () { - const value = this.initialBalance + 1n; - - await expect(this.token.connect(this.owner).burn(value)) - .to.be.revertedWithCustomError(this.token, 'ERC20InsufficientBalance') - .withArgs(this.owner, this.initialBalance, value); - }); - - describe('on success', function () { - for (const { title, value } of [ - { title: 'for a zero value', value: 0n }, - { title: 'for a non-zero value', value: 100n }, - ]) { - describe(title, function () { - beforeEach(async function () { - this.tx = await this.token.connect(this.owner).burn(value); - }); - - it('burns the requested value', async function () { - await expect(this.tx).to.changeTokenBalance(this.token, this.owner, -value); - }); - - it('emits a transfer event', async function () { - await expect(this.tx).to.emit(this.token, 'Transfer').withArgs(this.owner, ethers.ZeroAddress, value); - }); - }); - } - }); - }); - - describe('burnFrom', function () { - describe('reverts', function () { - it('if not enough balance', async function () { - const value = this.initialBalance + 1n; - - await this.token.connect(this.owner).approve(this.burner, value); - - await expect(this.token.connect(this.burner).burnFrom(this.owner, value)) - .to.be.revertedWithCustomError(this.token, 'ERC20InsufficientBalance') - .withArgs(this.owner, this.initialBalance, value); - }); - - it('if not enough allowance', async function () { - const allowance = 100n; - - await this.token.connect(this.owner).approve(this.burner, allowance); - - await expect(this.token.connect(this.burner).burnFrom(this.owner, allowance + 1n)) - .to.be.revertedWithCustomError(this.token, 'ERC20InsufficientAllowance') - .withArgs(this.burner, allowance, allowance + 1n); - }); - }); - - describe('on success', function () { - for (const { title, value } of [ - { title: 'for a zero value', value: 0n }, - { title: 'for a non-zero value', value: 100n }, - ]) { - describe(title, function () { - const originalAllowance = value * 3n; - - beforeEach(async function () { - await this.token.connect(this.owner).approve(this.burner, originalAllowance); - this.tx = await this.token.connect(this.burner).burnFrom(this.owner, value); - }); - - it('burns the requested value', async function () { - await expect(this.tx).to.changeTokenBalance(this.token, this.owner, -value); - }); - - it('decrements allowance', async function () { - expect(await this.token.allowance(this.owner, this.burner)).to.equal(originalAllowance - value); - }); - - it('emits a transfer event', async function () { - await expect(this.tx).to.emit(this.token, 'Transfer').withArgs(this.owner, ethers.ZeroAddress, value); - }); - }); - } - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Capped.test.js b/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Capped.test.js deleted file mode 100644 index a32ec43..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Capped.test.js +++ /dev/null @@ -1,55 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const name = 'My Token'; -const symbol = 'MTKN'; -const cap = 1000n; - -async function fixture() { - const [user] = await ethers.getSigners(); - - const token = await ethers.deployContract('$ERC20Capped', [name, symbol, cap]); - - return { user, token, cap }; -} - -describe('ERC20Capped', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - it('requires a non-zero cap', async function () { - const ERC20Capped = await ethers.getContractFactory('$ERC20Capped'); - - await expect(ERC20Capped.deploy(name, symbol, 0)) - .to.be.revertedWithCustomError(ERC20Capped, 'ERC20InvalidCap') - .withArgs(0); - }); - - describe('capped token', function () { - it('starts with the correct cap', async function () { - expect(await this.token.cap()).to.equal(this.cap); - }); - - it('mints when value is less than cap', async function () { - const value = this.cap - 1n; - await this.token.$_mint(this.user, value); - expect(await this.token.totalSupply()).to.equal(value); - }); - - it('fails to mint if the value exceeds the cap', async function () { - await this.token.$_mint(this.user, this.cap - 1n); - await expect(this.token.$_mint(this.user, 2)) - .to.be.revertedWithCustomError(this.token, 'ERC20ExceededCap') - .withArgs(this.cap + 1n, this.cap); - }); - - it('fails to mint after cap is reached', async function () { - await this.token.$_mint(this.user, this.cap); - await expect(this.token.$_mint(this.user, 1)) - .to.be.revertedWithCustomError(this.token, 'ERC20ExceededCap') - .withArgs(this.cap + 1n, this.cap); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20FlashMint.test.js b/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20FlashMint.test.js deleted file mode 100644 index 1c751f7..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20FlashMint.test.js +++ /dev/null @@ -1,164 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const name = 'My Token'; -const symbol = 'MTKN'; -const initialSupply = 100n; -const loanValue = 10_000_000_000_000n; - -async function fixture() { - const [holder, other] = await ethers.getSigners(); - - const token = await ethers.deployContract('$ERC20FlashMintMock', [name, symbol]); - await token.$_mint(holder, initialSupply); - - return { holder, other, token }; -} - -describe('ERC20FlashMint', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('maxFlashLoan', function () { - it('token match', async function () { - expect(await this.token.maxFlashLoan(this.token)).to.equal(ethers.MaxUint256 - initialSupply); - }); - - it('token mismatch', async function () { - expect(await this.token.maxFlashLoan(ethers.ZeroAddress)).to.equal(0n); - }); - }); - - describe('flashFee', function () { - it('token match', async function () { - expect(await this.token.flashFee(this.token, loanValue)).to.equal(0n); - }); - - it('token mismatch', async function () { - await expect(this.token.flashFee(ethers.ZeroAddress, loanValue)) - .to.be.revertedWithCustomError(this.token, 'ERC3156UnsupportedToken') - .withArgs(ethers.ZeroAddress); - }); - }); - - describe('flashFeeReceiver', function () { - it('default receiver', async function () { - expect(await this.token.$_flashFeeReceiver()).to.equal(ethers.ZeroAddress); - }); - }); - - describe('flashLoan', function () { - it('success', async function () { - const receiver = await ethers.deployContract('ERC3156FlashBorrowerMock', [true, true]); - - const tx = await this.token.flashLoan(receiver, this.token, loanValue, '0x'); - await expect(tx) - .to.emit(this.token, 'Transfer') - .withArgs(ethers.ZeroAddress, receiver, loanValue) - .to.emit(this.token, 'Transfer') - .withArgs(receiver, ethers.ZeroAddress, loanValue) - .to.emit(receiver, 'BalanceOf') - .withArgs(this.token, receiver, loanValue) - .to.emit(receiver, 'TotalSupply') - .withArgs(this.token, initialSupply + loanValue); - await expect(tx).to.changeTokenBalance(this.token, receiver, 0); - - expect(await this.token.totalSupply()).to.equal(initialSupply); - expect(await this.token.allowance(receiver, this.token)).to.equal(0n); - }); - - it('missing return value', async function () { - const receiver = await ethers.deployContract('ERC3156FlashBorrowerMock', [false, true]); - await expect(this.token.flashLoan(receiver, this.token, loanValue, '0x')) - .to.be.revertedWithCustomError(this.token, 'ERC3156InvalidReceiver') - .withArgs(receiver); - }); - - it('missing approval', async function () { - const receiver = await ethers.deployContract('ERC3156FlashBorrowerMock', [true, false]); - await expect(this.token.flashLoan(receiver, this.token, loanValue, '0x')) - .to.be.revertedWithCustomError(this.token, 'ERC20InsufficientAllowance') - .withArgs(this.token, 0, loanValue); - }); - - it('unavailable funds', async function () { - const receiver = await ethers.deployContract('ERC3156FlashBorrowerMock', [true, true]); - const data = this.token.interface.encodeFunctionData('transfer', [this.other.address, 10]); - await expect(this.token.flashLoan(receiver, this.token, loanValue, data)) - .to.be.revertedWithCustomError(this.token, 'ERC20InsufficientBalance') - .withArgs(receiver, loanValue - 10n, loanValue); - }); - - it('more than maxFlashLoan', async function () { - const receiver = await ethers.deployContract('ERC3156FlashBorrowerMock', [true, true]); - const data = this.token.interface.encodeFunctionData('transfer', [this.other.address, 10]); - await expect(this.token.flashLoan(receiver, this.token, ethers.MaxUint256, data)) - .to.be.revertedWithCustomError(this.token, 'ERC3156ExceededMaxLoan') - .withArgs(ethers.MaxUint256 - initialSupply); - }); - - describe('custom flash fee & custom fee receiver', function () { - const receiverInitialBalance = 200_000n; - const flashFee = 5_000n; - - beforeEach('init receiver balance & set flash fee', async function () { - this.receiver = await ethers.deployContract('ERC3156FlashBorrowerMock', [true, true]); - - const tx = await this.token.$_mint(this.receiver, receiverInitialBalance); - await expect(tx) - .to.emit(this.token, 'Transfer') - .withArgs(ethers.ZeroAddress, this.receiver, receiverInitialBalance); - await expect(tx).to.changeTokenBalance(this.token, this.receiver, receiverInitialBalance); - - await this.token.setFlashFee(flashFee); - expect(await this.token.flashFee(this.token, loanValue)).to.equal(flashFee); - }); - - it('default flash fee receiver', async function () { - const tx = await this.token.flashLoan(this.receiver, this.token, loanValue, '0x'); - await expect(tx) - .to.emit(this.token, 'Transfer') - .withArgs(ethers.ZeroAddress, this.receiver, loanValue) - .to.emit(this.token, 'Transfer') - .withArgs(this.receiver, ethers.ZeroAddress, loanValue + flashFee) - .to.emit(this.receiver, 'BalanceOf') - .withArgs(this.token, this.receiver, receiverInitialBalance + loanValue) - .to.emit(this.receiver, 'TotalSupply') - .withArgs(this.token, initialSupply + receiverInitialBalance + loanValue); - await expect(tx).to.changeTokenBalances(this.token, [this.receiver, ethers.ZeroAddress], [-flashFee, 0]); - - expect(await this.token.totalSupply()).to.equal(initialSupply + receiverInitialBalance - flashFee); - expect(await this.token.allowance(this.receiver, this.token)).to.equal(0n); - }); - - it('custom flash fee receiver', async function () { - const flashFeeReceiverAddress = this.other; - await this.token.setFlashFeeReceiver(flashFeeReceiverAddress); - expect(await this.token.$_flashFeeReceiver()).to.equal(flashFeeReceiverAddress); - - const tx = await this.token.flashLoan(this.receiver, this.token, loanValue, '0x'); - await expect(tx) - .to.emit(this.token, 'Transfer') - .withArgs(ethers.ZeroAddress, this.receiver, loanValue) - .to.emit(this.token, 'Transfer') - .withArgs(this.receiver, ethers.ZeroAddress, loanValue) - .to.emit(this.token, 'Transfer') - .withArgs(this.receiver, flashFeeReceiverAddress, flashFee) - .to.emit(this.receiver, 'BalanceOf') - .withArgs(this.token, this.receiver, receiverInitialBalance + loanValue) - .to.emit(this.receiver, 'TotalSupply') - .withArgs(this.token, initialSupply + receiverInitialBalance + loanValue); - await expect(tx).to.changeTokenBalances( - this.token, - [this.receiver, flashFeeReceiverAddress], - [-flashFee, flashFee], - ); - - expect(await this.token.totalSupply()).to.equal(initialSupply + receiverInitialBalance); - expect(await this.token.allowance(this.receiver, flashFeeReceiverAddress)).to.equal(0n); - }); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Pausable.test.js b/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Pausable.test.js deleted file mode 100644 index 1f1157c..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Pausable.test.js +++ /dev/null @@ -1,129 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const name = 'My Token'; -const symbol = 'MTKN'; -const initialSupply = 100n; - -async function fixture() { - const [holder, recipient, approved] = await ethers.getSigners(); - - const token = await ethers.deployContract('$ERC20Pausable', [name, symbol]); - await token.$_mint(holder, initialSupply); - - return { holder, recipient, approved, token }; -} - -describe('ERC20Pausable', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('pausable token', function () { - describe('transfer', function () { - it('allows to transfer when unpaused', async function () { - await expect(this.token.connect(this.holder).transfer(this.recipient, initialSupply)).to.changeTokenBalances( - this.token, - [this.holder, this.recipient], - [-initialSupply, initialSupply], - ); - }); - - it('allows to transfer when paused and then unpaused', async function () { - await this.token.$_pause(); - await this.token.$_unpause(); - - await expect(this.token.connect(this.holder).transfer(this.recipient, initialSupply)).to.changeTokenBalances( - this.token, - [this.holder, this.recipient], - [-initialSupply, initialSupply], - ); - }); - - it('reverts when trying to transfer when paused', async function () { - await this.token.$_pause(); - - await expect( - this.token.connect(this.holder).transfer(this.recipient, initialSupply), - ).to.be.revertedWithCustomError(this.token, 'EnforcedPause'); - }); - }); - - describe('transfer from', function () { - const allowance = 40n; - - beforeEach(async function () { - await this.token.connect(this.holder).approve(this.approved, allowance); - }); - - it('allows to transfer from when unpaused', async function () { - await expect( - this.token.connect(this.approved).transferFrom(this.holder, this.recipient, allowance), - ).to.changeTokenBalances(this.token, [this.holder, this.recipient], [-allowance, allowance]); - }); - - it('allows to transfer when paused and then unpaused', async function () { - await this.token.$_pause(); - await this.token.$_unpause(); - - await expect( - this.token.connect(this.approved).transferFrom(this.holder, this.recipient, allowance), - ).to.changeTokenBalances(this.token, [this.holder, this.recipient], [-allowance, allowance]); - }); - - it('reverts when trying to transfer from when paused', async function () { - await this.token.$_pause(); - - await expect( - this.token.connect(this.approved).transferFrom(this.holder, this.recipient, allowance), - ).to.be.revertedWithCustomError(this.token, 'EnforcedPause'); - }); - }); - - describe('mint', function () { - const value = 42n; - - it('allows to mint when unpaused', async function () { - await expect(this.token.$_mint(this.recipient, value)).to.changeTokenBalance(this.token, this.recipient, value); - }); - - it('allows to mint when paused and then unpaused', async function () { - await this.token.$_pause(); - await this.token.$_unpause(); - - await expect(this.token.$_mint(this.recipient, value)).to.changeTokenBalance(this.token, this.recipient, value); - }); - - it('reverts when trying to mint when paused', async function () { - await this.token.$_pause(); - - await expect(this.token.$_mint(this.recipient, value)).to.be.revertedWithCustomError( - this.token, - 'EnforcedPause', - ); - }); - }); - - describe('burn', function () { - const value = 42n; - - it('allows to burn when unpaused', async function () { - await expect(this.token.$_burn(this.holder, value)).to.changeTokenBalance(this.token, this.holder, -value); - }); - - it('allows to burn when paused and then unpaused', async function () { - await this.token.$_pause(); - await this.token.$_unpause(); - - await expect(this.token.$_burn(this.holder, value)).to.changeTokenBalance(this.token, this.holder, -value); - }); - - it('reverts when trying to burn when paused', async function () { - await this.token.$_pause(); - - await expect(this.token.$_burn(this.holder, value)).to.be.revertedWithCustomError(this.token, 'EnforcedPause'); - }); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Permit.test.js b/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Permit.test.js deleted file mode 100644 index c3c80d7..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Permit.test.js +++ /dev/null @@ -1,109 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { getDomain, domainSeparator, Permit } = require('../../../helpers/eip712'); -const time = require('../../../helpers/time'); - -const name = 'My Token'; -const symbol = 'MTKN'; -const initialSupply = 100n; - -async function fixture() { - const [holder, spender, owner, other] = await ethers.getSigners(); - - const token = await ethers.deployContract('$ERC20Permit', [name, symbol, name]); - await token.$_mint(holder, initialSupply); - - return { - holder, - spender, - owner, - other, - token, - }; -} - -describe('ERC20Permit', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - it('initial nonce is 0', async function () { - expect(await this.token.nonces(this.holder)).to.equal(0n); - }); - - it('domain separator', async function () { - expect(await this.token.DOMAIN_SEPARATOR()).to.equal(await getDomain(this.token).then(domainSeparator)); - }); - - describe('permit', function () { - const value = 42n; - const nonce = 0n; - const maxDeadline = ethers.MaxUint256; - - beforeEach(function () { - this.buildData = (contract, deadline = maxDeadline) => - getDomain(contract).then(domain => ({ - domain, - types: { Permit }, - message: { - owner: this.owner.address, - spender: this.spender.address, - value, - nonce, - deadline, - }, - })); - }); - - it('accepts owner signature', async function () { - const { v, r, s } = await this.buildData(this.token) - .then(({ domain, types, message }) => this.owner.signTypedData(domain, types, message)) - .then(ethers.Signature.from); - - await this.token.permit(this.owner, this.spender, value, maxDeadline, v, r, s); - - expect(await this.token.nonces(this.owner)).to.equal(1n); - expect(await this.token.allowance(this.owner, this.spender)).to.equal(value); - }); - - it('rejects reused signature', async function () { - const { v, r, s, serialized } = await this.buildData(this.token) - .then(({ domain, types, message }) => this.owner.signTypedData(domain, types, message)) - .then(ethers.Signature.from); - - await this.token.permit(this.owner, this.spender, value, maxDeadline, v, r, s); - - const recovered = await this.buildData(this.token).then(({ domain, types, message }) => - ethers.verifyTypedData(domain, types, { ...message, nonce: nonce + 1n, deadline: maxDeadline }, serialized), - ); - - await expect(this.token.permit(this.owner, this.spender, value, maxDeadline, v, r, s)) - .to.be.revertedWithCustomError(this.token, 'ERC2612InvalidSigner') - .withArgs(recovered, this.owner); - }); - - it('rejects other signature', async function () { - const { v, r, s } = await this.buildData(this.token) - .then(({ domain, types, message }) => this.other.signTypedData(domain, types, message)) - .then(ethers.Signature.from); - - await expect(this.token.permit(this.owner, this.spender, value, maxDeadline, v, r, s)) - .to.be.revertedWithCustomError(this.token, 'ERC2612InvalidSigner') - .withArgs(this.other, this.owner); - }); - - it('rejects expired permit', async function () { - const deadline = (await time.clock.timestamp()) - time.duration.weeks(1); - - const { v, r, s } = await this.buildData(this.token, deadline) - .then(({ domain, types, message }) => this.owner.signTypedData(domain, types, message)) - .then(ethers.Signature.from); - - await expect(this.token.permit(this.owner, this.spender, value, deadline, v, r, s)) - .to.be.revertedWithCustomError(this.token, 'ERC2612ExpiredSignature') - .withArgs(deadline); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Votes.test.js b/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Votes.test.js deleted file mode 100644 index 3c595c9..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Votes.test.js +++ /dev/null @@ -1,546 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture, mine } = require('@nomicfoundation/hardhat-network-helpers'); - -const { getDomain, Delegation } = require('../../../helpers/eip712'); -const { batchInBlock } = require('../../../helpers/txpool'); -const time = require('../../../helpers/time'); - -const { shouldBehaveLikeVotes } = require('../../../governance/utils/Votes.behavior'); - -const TOKENS = [ - { Token: '$ERC20Votes', mode: 'blocknumber' }, - { Token: '$ERC20VotesTimestampMock', mode: 'timestamp' }, -]; - -const name = 'My Token'; -const symbol = 'MTKN'; -const version = '1'; -const supply = ethers.parseEther('10000000'); - -describe('ERC20Votes', function () { - for (const { Token, mode } of TOKENS) { - const fixture = async () => { - // accounts is required by shouldBehaveLikeVotes - const accounts = await ethers.getSigners(); - const [holder, recipient, delegatee, other1, other2] = accounts; - - const token = await ethers.deployContract(Token, [name, symbol, name, version]); - const domain = await getDomain(token); - - return { accounts, holder, recipient, delegatee, other1, other2, token, domain }; - }; - - describe(`vote with ${mode}`, function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - this.votes = this.token; - }); - - // includes ERC6372 behavior check - shouldBehaveLikeVotes([1, 17, 42], { mode, fungible: true }); - - it('initial nonce is 0', async function () { - expect(await this.token.nonces(this.holder)).to.equal(0n); - }); - - it('minting restriction', async function () { - const value = 2n ** 208n; - await expect(this.token.$_mint(this.holder, value)) - .to.be.revertedWithCustomError(this.token, 'ERC20ExceededSafeSupply') - .withArgs(value, value - 1n); - }); - - it('recent checkpoints', async function () { - await this.token.connect(this.holder).delegate(this.holder); - for (let i = 0; i < 6; i++) { - await this.token.$_mint(this.holder, 1n); - } - const timepoint = await time.clock[mode](); - expect(await this.token.numCheckpoints(this.holder)).to.equal(6n); - // recent - expect(await this.token.getPastVotes(this.holder, timepoint - 1n)).to.equal(5n); - // non-recent - expect(await this.token.getPastVotes(this.holder, timepoint - 6n)).to.equal(0n); - }); - - describe('set delegation', function () { - describe('call', function () { - it('delegation with balance', async function () { - await this.token.$_mint(this.holder, supply); - expect(await this.token.delegates(this.holder)).to.equal(ethers.ZeroAddress); - - const tx = await this.token.connect(this.holder).delegate(this.holder); - const timepoint = await time.clockFromReceipt[mode](tx); - - await expect(tx) - .to.emit(this.token, 'DelegateChanged') - .withArgs(this.holder, ethers.ZeroAddress, this.holder) - .to.emit(this.token, 'DelegateVotesChanged') - .withArgs(this.holder, 0n, supply); - - expect(await this.token.delegates(this.holder)).to.equal(this.holder); - expect(await this.token.getVotes(this.holder)).to.equal(supply); - expect(await this.token.getPastVotes(this.holder, timepoint - 1n)).to.equal(0n); - await mine(); - expect(await this.token.getPastVotes(this.holder, timepoint)).to.equal(supply); - }); - - it('delegation without balance', async function () { - expect(await this.token.delegates(this.holder)).to.equal(ethers.ZeroAddress); - - await expect(this.token.connect(this.holder).delegate(this.holder)) - .to.emit(this.token, 'DelegateChanged') - .withArgs(this.holder, ethers.ZeroAddress, this.holder) - .to.not.emit(this.token, 'DelegateVotesChanged'); - - expect(await this.token.delegates(this.holder)).to.equal(this.holder); - }); - }); - - describe('with signature', function () { - const nonce = 0n; - - beforeEach(async function () { - await this.token.$_mint(this.holder, supply); - }); - - it('accept signed delegation', async function () { - const { r, s, v } = await this.holder - .signTypedData( - this.domain, - { Delegation }, - { - delegatee: this.holder.address, - nonce, - expiry: ethers.MaxUint256, - }, - ) - .then(ethers.Signature.from); - - expect(await this.token.delegates(this.holder)).to.equal(ethers.ZeroAddress); - - const tx = await this.token.delegateBySig(this.holder, nonce, ethers.MaxUint256, v, r, s); - const timepoint = await time.clockFromReceipt[mode](tx); - - await expect(tx) - .to.emit(this.token, 'DelegateChanged') - .withArgs(this.holder, ethers.ZeroAddress, this.holder) - .to.emit(this.token, 'DelegateVotesChanged') - .withArgs(this.holder, 0n, supply); - - expect(await this.token.delegates(this.holder)).to.equal(this.holder); - - expect(await this.token.getVotes(this.holder)).to.equal(supply); - expect(await this.token.getPastVotes(this.holder, timepoint - 1n)).to.equal(0n); - await mine(); - expect(await this.token.getPastVotes(this.holder, timepoint)).to.equal(supply); - }); - - it('rejects reused signature', async function () { - const { r, s, v } = await this.holder - .signTypedData( - this.domain, - { Delegation }, - { - delegatee: this.holder.address, - nonce, - expiry: ethers.MaxUint256, - }, - ) - .then(ethers.Signature.from); - - await this.token.delegateBySig(this.holder, nonce, ethers.MaxUint256, v, r, s); - - await expect(this.token.delegateBySig(this.holder, nonce, ethers.MaxUint256, v, r, s)) - .to.be.revertedWithCustomError(this.token, 'InvalidAccountNonce') - .withArgs(this.holder, nonce + 1n); - }); - - it('rejects bad delegatee', async function () { - const { r, s, v } = await this.holder - .signTypedData( - this.domain, - { Delegation }, - { - delegatee: this.holder.address, - nonce, - expiry: ethers.MaxUint256, - }, - ) - .then(ethers.Signature.from); - - const tx = await this.token.delegateBySig(this.delegatee, nonce, ethers.MaxUint256, v, r, s); - - const { args } = await tx - .wait() - .then(receipt => receipt.logs.find(event => event.fragment.name == 'DelegateChanged')); - expect(args[0]).to.not.equal(this.holder); - expect(args[1]).to.equal(ethers.ZeroAddress); - expect(args[2]).to.equal(this.delegatee); - }); - - it('rejects bad nonce', async function () { - const { r, s, v, serialized } = await this.holder - .signTypedData( - this.domain, - { Delegation }, - { - delegatee: this.holder.address, - nonce, - expiry: ethers.MaxUint256, - }, - ) - .then(ethers.Signature.from); - - const recovered = ethers.verifyTypedData( - this.domain, - { Delegation }, - { - delegatee: this.holder.address, - nonce: nonce + 1n, - expiry: ethers.MaxUint256, - }, - serialized, - ); - - await expect(this.token.delegateBySig(this.holder, nonce + 1n, ethers.MaxUint256, v, r, s)) - .to.be.revertedWithCustomError(this.token, 'InvalidAccountNonce') - .withArgs(recovered, nonce); - }); - - it('rejects expired permit', async function () { - const expiry = (await time.clock.timestamp()) - time.duration.weeks(1); - - const { r, s, v } = await this.holder - .signTypedData( - this.domain, - { Delegation }, - { - delegatee: this.holder.address, - nonce, - expiry, - }, - ) - .then(ethers.Signature.from); - - await expect(this.token.delegateBySig(this.holder, nonce, expiry, v, r, s)) - .to.be.revertedWithCustomError(this.token, 'VotesExpiredSignature') - .withArgs(expiry); - }); - }); - }); - - describe('change delegation', function () { - beforeEach(async function () { - await this.token.$_mint(this.holder, supply); - await this.token.connect(this.holder).delegate(this.holder); - }); - - it('call', async function () { - expect(await this.token.delegates(this.holder)).to.equal(this.holder); - - const tx = await this.token.connect(this.holder).delegate(this.delegatee); - const timepoint = await time.clockFromReceipt[mode](tx); - - await expect(tx) - .to.emit(this.token, 'DelegateChanged') - .withArgs(this.holder, this.holder, this.delegatee) - .to.emit(this.token, 'DelegateVotesChanged') - .withArgs(this.holder, supply, 0n) - .to.emit(this.token, 'DelegateVotesChanged') - .withArgs(this.delegatee, 0n, supply); - - expect(await this.token.delegates(this.holder)).to.equal(this.delegatee); - - expect(await this.token.getVotes(this.holder)).to.equal(0n); - expect(await this.token.getVotes(this.delegatee)).to.equal(supply); - expect(await this.token.getPastVotes(this.holder, timepoint - 1n)).to.equal(supply); - expect(await this.token.getPastVotes(this.delegatee, timepoint - 1n)).to.equal(0n); - await mine(); - expect(await this.token.getPastVotes(this.holder, timepoint)).to.equal(0n); - expect(await this.token.getPastVotes(this.delegatee, timepoint)).to.equal(supply); - }); - }); - - describe('transfers', function () { - beforeEach(async function () { - await this.token.$_mint(this.holder, supply); - }); - - it('no delegation', async function () { - await expect(this.token.connect(this.holder).transfer(this.recipient, 1n)) - .to.emit(this.token, 'Transfer') - .withArgs(this.holder, this.recipient, 1n) - .to.not.emit(this.token, 'DelegateVotesChanged'); - - this.holderVotes = 0n; - this.recipientVotes = 0n; - }); - - it('sender delegation', async function () { - await this.token.connect(this.holder).delegate(this.holder); - - const tx = await this.token.connect(this.holder).transfer(this.recipient, 1n); - await expect(tx) - .to.emit(this.token, 'Transfer') - .withArgs(this.holder, this.recipient, 1n) - .to.emit(this.token, 'DelegateVotesChanged') - .withArgs(this.holder, supply, supply - 1n); - - const { logs } = await tx.wait(); - const { index } = logs.find(event => event.fragment.name == 'DelegateVotesChanged'); - for (const event of logs.filter(event => event.fragment.name == 'Transfer')) { - expect(event.index).to.lt(index); - } - - this.holderVotes = supply - 1n; - this.recipientVotes = 0n; - }); - - it('receiver delegation', async function () { - await this.token.connect(this.recipient).delegate(this.recipient); - - const tx = await this.token.connect(this.holder).transfer(this.recipient, 1n); - await expect(tx) - .to.emit(this.token, 'Transfer') - .withArgs(this.holder, this.recipient, 1n) - .to.emit(this.token, 'DelegateVotesChanged') - .withArgs(this.recipient, 0n, 1n); - - const { logs } = await tx.wait(); - const { index } = logs.find(event => event.fragment.name == 'DelegateVotesChanged'); - for (const event of logs.filter(event => event.fragment.name == 'Transfer')) { - expect(event.index).to.lt(index); - } - - this.holderVotes = 0n; - this.recipientVotes = 1n; - }); - - it('full delegation', async function () { - await this.token.connect(this.holder).delegate(this.holder); - await this.token.connect(this.recipient).delegate(this.recipient); - - const tx = await this.token.connect(this.holder).transfer(this.recipient, 1n); - await expect(tx) - .to.emit(this.token, 'Transfer') - .withArgs(this.holder, this.recipient, 1n) - .to.emit(this.token, 'DelegateVotesChanged') - .withArgs(this.holder, supply, supply - 1n) - .to.emit(this.token, 'DelegateVotesChanged') - .withArgs(this.recipient, 0n, 1n); - - const { logs } = await tx.wait(); - const { index } = logs.find(event => event.fragment.name == 'DelegateVotesChanged'); - for (const event of logs.filter(event => event.fragment.name == 'Transfer')) { - expect(event.index).to.lt(index); - } - - this.holderVotes = supply - 1n; - this.recipientVotes = 1n; - }); - - afterEach(async function () { - expect(await this.token.getVotes(this.holder)).to.equal(this.holderVotes); - expect(await this.token.getVotes(this.recipient)).to.equal(this.recipientVotes); - - // need to advance 2 blocks to see the effect of a transfer on "getPastVotes" - const timepoint = await time.clock[mode](); - await mine(); - expect(await this.token.getPastVotes(this.holder, timepoint)).to.equal(this.holderVotes); - expect(await this.token.getPastVotes(this.recipient, timepoint)).to.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(this.holder, supply); - }); - - describe('balanceOf', function () { - it('grants to initial account', async function () { - expect(await this.token.balanceOf(this.holder)).to.equal(supply); - }); - }); - - describe('numCheckpoints', function () { - it('returns the number of checkpoints for a delegate', async function () { - await this.token.connect(this.holder).transfer(this.recipient, 100n); //give an account a few tokens for readability - expect(await this.token.numCheckpoints(this.other1)).to.equal(0n); - - const t1 = await this.token.connect(this.recipient).delegate(this.other1); - t1.timepoint = await time.clockFromReceipt[mode](t1); - expect(await this.token.numCheckpoints(this.other1)).to.equal(1n); - - const t2 = await this.token.connect(this.recipient).transfer(this.other2, 10); - t2.timepoint = await time.clockFromReceipt[mode](t2); - expect(await this.token.numCheckpoints(this.other1)).to.equal(2n); - - const t3 = await this.token.connect(this.recipient).transfer(this.other2, 10); - t3.timepoint = await time.clockFromReceipt[mode](t3); - expect(await this.token.numCheckpoints(this.other1)).to.equal(3n); - - const t4 = await this.token.connect(this.holder).transfer(this.recipient, 20); - t4.timepoint = await time.clockFromReceipt[mode](t4); - expect(await this.token.numCheckpoints(this.other1)).to.equal(4n); - - expect(await this.token.checkpoints(this.other1, 0n)).to.deep.equal([t1.timepoint, 100n]); - expect(await this.token.checkpoints(this.other1, 1n)).to.deep.equal([t2.timepoint, 90n]); - expect(await this.token.checkpoints(this.other1, 2n)).to.deep.equal([t3.timepoint, 80n]); - expect(await this.token.checkpoints(this.other1, 3n)).to.deep.equal([t4.timepoint, 100n]); - await mine(); - expect(await this.token.getPastVotes(this.other1, t1.timepoint)).to.equal(100n); - expect(await this.token.getPastVotes(this.other1, t2.timepoint)).to.equal(90n); - expect(await this.token.getPastVotes(this.other1, t3.timepoint)).to.equal(80n); - expect(await this.token.getPastVotes(this.other1, t4.timepoint)).to.equal(100n); - }); - - it('does not add more than one checkpoint in a block', async function () { - await this.token.connect(this.holder).transfer(this.recipient, 100n); - expect(await this.token.numCheckpoints(this.other1)).to.equal(0n); - - const [t1, t2, t3] = await batchInBlock([ - () => this.token.connect(this.recipient).delegate(this.other1, { gasLimit: 200000 }), - () => this.token.connect(this.recipient).transfer(this.other2, 10n, { gasLimit: 200000 }), - () => this.token.connect(this.recipient).transfer(this.other2, 10n, { gasLimit: 200000 }), - ]); - t1.timepoint = await time.clockFromReceipt[mode](t1); - t2.timepoint = await time.clockFromReceipt[mode](t2); - t3.timepoint = await time.clockFromReceipt[mode](t3); - - expect(await this.token.numCheckpoints(this.other1)).to.equal(1); - expect(await this.token.checkpoints(this.other1, 0n)).to.be.deep.equal([t1.timepoint, 80n]); - - const t4 = await this.token.connect(this.holder).transfer(this.recipient, 20n); - t4.timepoint = await time.clockFromReceipt[mode](t4); - - expect(await this.token.numCheckpoints(this.other1)).to.equal(2n); - expect(await this.token.checkpoints(this.other1, 1n)).to.be.deep.equal([t4.timepoint, 100n]); - }); - }); - - describe('getPastVotes', function () { - it('reverts if block number >= current block', async function () { - const clock = await this.token.clock(); - await expect(this.token.getPastVotes(this.other1, 50_000_000_000n)) - .to.be.revertedWithCustomError(this.token, 'ERC5805FutureLookup') - .withArgs(50_000_000_000n, clock); - }); - - it('returns 0 if there are no checkpoints', async function () { - expect(await this.token.getPastVotes(this.other1, 0n)).to.equal(0n); - }); - - it('returns the latest block if >= last checkpoint block', async function () { - const tx = await this.token.connect(this.holder).delegate(this.other1); - const timepoint = await time.clockFromReceipt[mode](tx); - await mine(2); - - expect(await this.token.getPastVotes(this.other1, timepoint)).to.equal(supply); - expect(await this.token.getPastVotes(this.other1, timepoint + 1n)).to.equal(supply); - }); - - it('returns zero if < first checkpoint block', async function () { - await mine(); - const tx = await this.token.connect(this.holder).delegate(this.other1); - const timepoint = await time.clockFromReceipt[mode](tx); - await mine(2); - - expect(await this.token.getPastVotes(this.other1, timepoint - 1n)).to.equal(0n); - expect(await this.token.getPastVotes(this.other1, timepoint + 1n)).to.equal(supply); - }); - - it('generally returns the voting balance at the appropriate checkpoint', async function () { - const t1 = await this.token.connect(this.holder).delegate(this.other1); - await mine(2); - const t2 = await this.token.connect(this.holder).transfer(this.other2, 10); - await mine(2); - const t3 = await this.token.connect(this.holder).transfer(this.other2, 10); - await mine(2); - const t4 = await this.token.connect(this.other2).transfer(this.holder, 20); - await mine(2); - - t1.timepoint = await time.clockFromReceipt[mode](t1); - t2.timepoint = await time.clockFromReceipt[mode](t2); - t3.timepoint = await time.clockFromReceipt[mode](t3); - t4.timepoint = await time.clockFromReceipt[mode](t4); - - expect(await this.token.getPastVotes(this.other1, t1.timepoint - 1n)).to.equal(0n); - expect(await this.token.getPastVotes(this.other1, t1.timepoint)).to.equal(supply); - expect(await this.token.getPastVotes(this.other1, t1.timepoint + 1n)).to.equal(supply); - expect(await this.token.getPastVotes(this.other1, t2.timepoint)).to.equal(supply - 10n); - expect(await this.token.getPastVotes(this.other1, t2.timepoint + 1n)).to.equal(supply - 10n); - expect(await this.token.getPastVotes(this.other1, t3.timepoint)).to.equal(supply - 20n); - expect(await this.token.getPastVotes(this.other1, t3.timepoint + 1n)).to.equal(supply - 20n); - expect(await this.token.getPastVotes(this.other1, t4.timepoint)).to.equal(supply); - expect(await this.token.getPastVotes(this.other1, t4.timepoint + 1n)).to.equal(supply); - }); - }); - }); - - describe('getPastTotalSupply', function () { - beforeEach(async function () { - await this.token.connect(this.holder).delegate(this.holder); - }); - - it('reverts if block number >= current block', async function () { - const clock = await this.token.clock(); - await expect(this.token.getPastTotalSupply(50_000_000_000n)) - .to.be.revertedWithCustomError(this.token, 'ERC5805FutureLookup') - .withArgs(50_000_000_000n, clock); - }); - - it('returns 0 if there are no checkpoints', async function () { - expect(await this.token.getPastTotalSupply(0n)).to.equal(0n); - }); - - it('returns the latest block if >= last checkpoint block', async function () { - const tx = await this.token.$_mint(this.holder, supply); - const timepoint = await time.clockFromReceipt[mode](tx); - await mine(2); - - expect(await this.token.getPastTotalSupply(timepoint)).to.equal(supply); - expect(await this.token.getPastTotalSupply(timepoint + 1n)).to.equal(supply); - }); - - it('returns zero if < first checkpoint block', async function () { - await mine(); - const tx = await this.token.$_mint(this.holder, supply); - const timepoint = await time.clockFromReceipt[mode](tx); - await mine(2); - - expect(await this.token.getPastTotalSupply(timepoint - 1n)).to.equal(0n); - expect(await this.token.getPastTotalSupply(timepoint + 1n)).to.equal(supply); - }); - - it('generally returns the voting balance at the appropriate checkpoint', async function () { - const t1 = await this.token.$_mint(this.holder, supply); - await mine(2); - const t2 = await this.token.$_burn(this.holder, 10n); - await mine(2); - const t3 = await this.token.$_burn(this.holder, 10n); - await mine(2); - const t4 = await this.token.$_mint(this.holder, 20n); - await mine(2); - - t1.timepoint = await time.clockFromReceipt[mode](t1); - t2.timepoint = await time.clockFromReceipt[mode](t2); - t3.timepoint = await time.clockFromReceipt[mode](t3); - t4.timepoint = await time.clockFromReceipt[mode](t4); - - expect(await this.token.getPastTotalSupply(t1.timepoint - 1n)).to.equal(0n); - expect(await this.token.getPastTotalSupply(t1.timepoint)).to.equal(supply); - expect(await this.token.getPastTotalSupply(t1.timepoint + 1n)).to.equal(supply); - expect(await this.token.getPastTotalSupply(t2.timepoint)).to.equal(supply - 10n); - expect(await this.token.getPastTotalSupply(t2.timepoint + 1n)).to.equal(supply - 10n); - expect(await this.token.getPastTotalSupply(t3.timepoint)).to.equal(supply - 20n); - expect(await this.token.getPastTotalSupply(t3.timepoint + 1n)).to.equal(supply - 20n); - expect(await this.token.getPastTotalSupply(t4.timepoint)).to.equal(supply); - expect(await this.token.getPastTotalSupply(t4.timepoint + 1n)).to.equal(supply); - }); - }); - }); - } -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Wrapper.test.js b/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Wrapper.test.js deleted file mode 100644 index 9e72e1a..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Wrapper.test.js +++ /dev/null @@ -1,203 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { shouldBehaveLikeERC20 } = require('../ERC20.behavior'); - -const name = 'My Token'; -const symbol = 'MTKN'; -const decimals = 9n; -const initialSupply = 100n; - -async function fixture() { - // this.accounts is used by shouldBehaveLikeERC20 - const accounts = await ethers.getSigners(); - const [holder, recipient, other] = accounts; - - const underlying = await ethers.deployContract('$ERC20DecimalsMock', [name, symbol, decimals]); - await underlying.$_mint(holder, initialSupply); - - const token = await ethers.deployContract('$ERC20Wrapper', [`Wrapped ${name}`, `W${symbol}`, underlying]); - - return { accounts, holder, recipient, other, underlying, token }; -} - -describe('ERC20Wrapper', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - afterEach('Underlying balance', async function () { - expect(await this.underlying.balanceOf(this.token)).to.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.equal(decimals); - }); - - it('decimals default back to 18 if token has no metadata', async function () { - const noDecimals = await ethers.deployContract('CallReceiverMock'); - const token = await ethers.deployContract('$ERC20Wrapper', [`Wrapped ${name}`, `W${symbol}`, noDecimals]); - expect(await token.decimals()).to.equal(18n); - }); - - it('has underlying', async function () { - expect(await this.token.underlying()).to.equal(this.underlying); - }); - - describe('deposit', function () { - it('executes with approval', async function () { - await this.underlying.connect(this.holder).approve(this.token, initialSupply); - - const tx = await this.token.connect(this.holder).depositFor(this.holder, initialSupply); - await expect(tx) - .to.emit(this.underlying, 'Transfer') - .withArgs(this.holder, this.token, initialSupply) - .to.emit(this.token, 'Transfer') - .withArgs(ethers.ZeroAddress, this.holder, initialSupply); - await expect(tx).to.changeTokenBalances( - this.underlying, - [this.holder, this.token], - [-initialSupply, initialSupply], - ); - await expect(tx).to.changeTokenBalance(this.token, this.holder, initialSupply); - }); - - it('reverts when missing approval', async function () { - await expect(this.token.connect(this.holder).depositFor(this.holder, initialSupply)) - .to.be.revertedWithCustomError(this.underlying, 'ERC20InsufficientAllowance') - .withArgs(this.token, 0, initialSupply); - }); - - it('reverts when inssuficient balance', async function () { - await this.underlying.connect(this.holder).approve(this.token, ethers.MaxUint256); - - await expect(this.token.connect(this.holder).depositFor(this.holder, ethers.MaxUint256)) - .to.be.revertedWithCustomError(this.underlying, 'ERC20InsufficientBalance') - .withArgs(this.holder, initialSupply, ethers.MaxUint256); - }); - - it('deposits to other account', async function () { - await this.underlying.connect(this.holder).approve(this.token, initialSupply); - - const tx = await this.token.connect(this.holder).depositFor(this.recipient, initialSupply); - await expect(tx) - .to.emit(this.underlying, 'Transfer') - .withArgs(this.holder, this.token.target, initialSupply) - .to.emit(this.token, 'Transfer') - .withArgs(ethers.ZeroAddress, this.recipient, initialSupply); - await expect(tx).to.changeTokenBalances( - this.underlying, - [this.holder, this.token], - [-initialSupply, initialSupply], - ); - await expect(tx).to.changeTokenBalances(this.token, [this.holder, this.recipient], [0, initialSupply]); - }); - - it('reverts minting to the wrapper contract', async function () { - await this.underlying.connect(this.holder).approve(this.token, ethers.MaxUint256); - - await expect(this.token.connect(this.holder).depositFor(this.token, ethers.MaxUint256)) - .to.be.revertedWithCustomError(this.token, 'ERC20InvalidReceiver') - .withArgs(this.token); - }); - }); - - describe('withdraw', function () { - beforeEach(async function () { - await this.underlying.connect(this.holder).approve(this.token, initialSupply); - await this.token.connect(this.holder).depositFor(this.holder, initialSupply); - }); - - it('reverts when inssuficient balance', async function () { - await expect(this.token.connect(this.holder).withdrawTo(this.holder, ethers.MaxInt256)) - .to.be.revertedWithCustomError(this.token, 'ERC20InsufficientBalance') - .withArgs(this.holder, initialSupply, ethers.MaxInt256); - }); - - it('executes when operation is valid', async function () { - const value = 42n; - - const tx = await this.token.connect(this.holder).withdrawTo(this.holder, value); - await expect(tx) - .to.emit(this.underlying, 'Transfer') - .withArgs(this.token.target, this.holder, value) - .to.emit(this.token, 'Transfer') - .withArgs(this.holder, ethers.ZeroAddress, value); - await expect(tx).to.changeTokenBalances(this.underlying, [this.token, this.holder], [-value, value]); - await expect(tx).to.changeTokenBalance(this.token, this.holder, -value); - }); - - it('entire balance', async function () { - const tx = await this.token.connect(this.holder).withdrawTo(this.holder, initialSupply); - await expect(tx) - .to.emit(this.underlying, 'Transfer') - .withArgs(this.token.target, this.holder, initialSupply) - .to.emit(this.token, 'Transfer') - .withArgs(this.holder, ethers.ZeroAddress, initialSupply); - await expect(tx).to.changeTokenBalances( - this.underlying, - [this.token, this.holder], - [-initialSupply, initialSupply], - ); - await expect(tx).to.changeTokenBalance(this.token, this.holder, -initialSupply); - }); - - it('to other account', async function () { - const tx = await this.token.connect(this.holder).withdrawTo(this.recipient, initialSupply); - await expect(tx) - .to.emit(this.underlying, 'Transfer') - .withArgs(this.token, this.recipient, initialSupply) - .to.emit(this.token, 'Transfer') - .withArgs(this.holder, ethers.ZeroAddress, initialSupply); - await expect(tx).to.changeTokenBalances( - this.underlying, - [this.token, this.holder, this.recipient], - [-initialSupply, 0, initialSupply], - ); - await expect(tx).to.changeTokenBalance(this.token, this.holder, -initialSupply); - }); - - it('reverts withdrawing to the wrapper contract', async function () { - await expect(this.token.connect(this.holder).withdrawTo(this.token, initialSupply)) - .to.be.revertedWithCustomError(this.token, 'ERC20InvalidReceiver') - .withArgs(this.token); - }); - }); - - describe('recover', function () { - it('nothing to recover', async function () { - await this.underlying.connect(this.holder).approve(this.token, initialSupply); - await this.token.connect(this.holder).depositFor(this.holder, initialSupply); - - const tx = await this.token.$_recover(this.recipient); - await expect(tx).to.emit(this.token, 'Transfer').withArgs(ethers.ZeroAddress, this.recipient, 0n); - await expect(tx).to.changeTokenBalance(this.token, this.recipient, 0); - }); - - it('something to recover', async function () { - await this.underlying.connect(this.holder).transfer(this.token, initialSupply); - - const tx = await this.token.$_recover(this.recipient); - await expect(tx).to.emit(this.token, 'Transfer').withArgs(ethers.ZeroAddress, this.recipient, initialSupply); - await expect(tx).to.changeTokenBalance(this.token, this.recipient, initialSupply); - }); - }); - - describe('erc20 behaviour', function () { - beforeEach(async function () { - await this.underlying.connect(this.holder).approve(this.token, initialSupply); - await this.token.connect(this.holder).depositFor(this.holder, initialSupply); - }); - - shouldBehaveLikeERC20(initialSupply); - }); -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC4626.t.sol b/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC4626.t.sol deleted file mode 100644 index 72b0dac..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC4626.t.sol +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import {ERC4626Test} from "erc4626-tests/ERC4626.test.sol"; - -import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import {ERC4626} from "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol"; - -import {ERC20Mock} from "@openzeppelin/contracts/mocks/token/ERC20Mock.sol"; -import {ERC4626Mock} from "@openzeppelin/contracts/mocks/token/ERC4626Mock.sol"; -import {ERC4626OffsetMock} from "@openzeppelin/contracts/mocks/token/ERC4626OffsetMock.sol"; - -contract ERC4626VaultOffsetMock is ERC4626OffsetMock { - constructor( - ERC20 underlying_, - uint8 offset_ - ) ERC20("My Token Vault", "MTKNV") ERC4626(underlying_) ERC4626OffsetMock(offset_) {} -} - -contract ERC4626StdTest is ERC4626Test { - ERC20 private _underlying = new ERC20Mock(); - - function setUp() public override { - _underlying_ = address(_underlying); - _vault_ = address(new ERC4626Mock(_underlying_)); - _delta_ = 0; - _vaultMayBeEmpty = true; - _unlimitedAmount = true; - } - - /** - * @dev Check the case where calculated `decimals` value overflows the `uint8` type. - */ - function testFuzzDecimalsOverflow(uint8 offset) public { - /// @dev Remember that the `_underlying` exhibits a `decimals` value of 18. - offset = uint8(bound(uint256(offset), 238, uint256(type(uint8).max))); - ERC4626VaultOffsetMock erc4626VaultOffsetMock = new ERC4626VaultOffsetMock(_underlying, offset); - vm.expectRevert(); - erc4626VaultOffsetMock.decimals(); - } -} diff --git a/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC4626.test.js b/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC4626.test.js deleted file mode 100644 index 71c7cba..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC4626.test.js +++ /dev/null @@ -1,888 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); - -const { Enum } = require('../../../helpers/enums'); - -const name = 'My Token'; -const symbol = 'MTKN'; -const decimals = 18n; - -async function fixture() { - const [holder, recipient, spender, other, ...accounts] = await ethers.getSigners(); - return { holder, recipient, spender, other, accounts }; -} - -describe('ERC4626', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - it('inherit decimals if from asset', async function () { - for (const decimals of [0n, 9n, 12n, 18n, 36n]) { - const token = await ethers.deployContract('$ERC20DecimalsMock', ['', '', decimals]); - const vault = await ethers.deployContract('$ERC4626', ['', '', token]); - expect(await vault.decimals()).to.equal(decimals); - } - }); - - it('asset has not yet been created', async function () { - const vault = await ethers.deployContract('$ERC4626', ['', '', this.other.address]); - expect(await vault.decimals()).to.equal(decimals); - }); - - it('underlying excess decimals', async function () { - const token = await ethers.deployContract('$ERC20ExcessDecimalsMock'); - const vault = await ethers.deployContract('$ERC4626', ['', '', token]); - expect(await vault.decimals()).to.equal(decimals); - }); - - it('decimals overflow', async function () { - for (const offset of [243n, 250n, 255n]) { - const token = await ethers.deployContract('$ERC20DecimalsMock', ['', '', decimals]); - const vault = await ethers.deployContract('$ERC4626OffsetMock', ['', '', token, offset]); - await expect(vault.decimals()).to.be.revertedWithPanic(PANIC_CODES.ARITHMETIC_UNDER_OR_OVERFLOW); - } - }); - - describe('reentrancy', function () { - const reenterType = Enum('No', 'Before', 'After'); - - const value = 1_000_000_000_000_000_000n; - const reenterValue = 1_000_000_000n; - - beforeEach(async function () { - // Use offset 1 so the rate is not 1:1 and we can't possibly confuse assets and shares - const token = await ethers.deployContract('$ERC20Reentrant'); - const vault = await ethers.deployContract('$ERC4626OffsetMock', ['', '', token, 1n]); - // Funds and approval for tests - await token.$_mint(this.holder, value); - await token.$_mint(this.other, value); - await token.$_approve(this.holder, vault, ethers.MaxUint256); - await token.$_approve(this.other, vault, ethers.MaxUint256); - await token.$_approve(token, vault, ethers.MaxUint256); - - Object.assign(this, { token, vault }); - }); - - // During a `_deposit`, the vault does `transferFrom(depositor, vault, assets)` -> `_mint(receiver, shares)` - // such that a reentrancy BEFORE the transfer guarantees the price is kept the same. - // If the order of transfer -> mint is changed to mint -> transfer, the reentrancy could be triggered on an - // intermediate state in which the ratio of assets/shares has been decreased (more shares than assets). - it('correct share price is observed during reentrancy before deposit', async function () { - // mint token for deposit - await this.token.$_mint(this.token, reenterValue); - - // Schedules a reentrancy from the token contract - await this.token.scheduleReenter( - reenterType.Before, - this.vault, - this.vault.interface.encodeFunctionData('deposit', [reenterValue, this.holder.address]), - ); - - // Initial share price - const sharesForDeposit = await this.vault.previewDeposit(value); - const sharesForReenter = await this.vault.previewDeposit(reenterValue); - - await expect(this.vault.connect(this.holder).deposit(value, this.holder)) - // Deposit normally, reentering before the internal `_update` - .to.emit(this.vault, 'Deposit') - .withArgs(this.holder, this.holder, value, sharesForDeposit) - // Reentrant deposit event → uses the same price - .to.emit(this.vault, 'Deposit') - .withArgs(this.token, this.holder, reenterValue, sharesForReenter); - - // Assert prices is kept - expect(await this.vault.previewDeposit(value)).to.equal(sharesForDeposit); - }); - - // During a `_withdraw`, the vault does `_burn(owner, shares)` -> `transfer(receiver, assets)` - // such that a reentrancy AFTER the transfer guarantees the price is kept the same. - // If the order of burn -> transfer is changed to transfer -> burn, the reentrancy could be triggered on an - // intermediate state in which the ratio of shares/assets has been decreased (more assets than shares). - it('correct share price is observed during reentrancy after withdraw', async function () { - // Deposit into the vault: holder gets `value` share, token.address gets `reenterValue` shares - await this.vault.connect(this.holder).deposit(value, this.holder); - await this.vault.connect(this.other).deposit(reenterValue, this.token); - - // Schedules a reentrancy from the token contract - await this.token.scheduleReenter( - reenterType.After, - this.vault, - this.vault.interface.encodeFunctionData('withdraw', [reenterValue, this.holder.address, this.token.target]), - ); - - // Initial share price - const sharesForWithdraw = await this.vault.previewWithdraw(value); - const sharesForReenter = await this.vault.previewWithdraw(reenterValue); - - // Do withdraw normally, triggering the _afterTokenTransfer hook - await expect(this.vault.connect(this.holder).withdraw(value, this.holder, this.holder)) - // Main withdraw event - .to.emit(this.vault, 'Withdraw') - .withArgs(this.holder, this.holder, this.holder, value, sharesForWithdraw) - // Reentrant withdraw event → uses the same price - .to.emit(this.vault, 'Withdraw') - .withArgs(this.token, this.holder, this.token, reenterValue, sharesForReenter); - - // Assert price is kept - expect(await this.vault.previewWithdraw(value)).to.equal(sharesForWithdraw); - }); - - // Donate newly minted tokens to the vault during the reentracy causes the share price to increase. - // Still, the deposit that trigger the reentracy is not affected and get the previewed price. - // Further deposits will get a different price (getting fewer shares for the same value of assets) - it('share price change during reentracy does not affect deposit', async function () { - // Schedules a reentrancy from the token contract that mess up the share price - await this.token.scheduleReenter( - reenterType.Before, - this.token, - this.token.interface.encodeFunctionData('$_mint', [this.vault.target, reenterValue]), - ); - - // Price before - const sharesBefore = await this.vault.previewDeposit(value); - - // Deposit, reentering before the internal `_update` - await expect(this.vault.connect(this.holder).deposit(value, this.holder)) - // Price is as previewed - .to.emit(this.vault, 'Deposit') - .withArgs(this.holder, this.holder, value, sharesBefore); - - // Price was modified during reentrancy - expect(await this.vault.previewDeposit(value)).to.lt(sharesBefore); - }); - - // Burn some tokens from the vault during the reentracy causes the share price to drop. - // Still, the withdraw that trigger the reentracy is not affected and get the previewed price. - // Further withdraw will get a different price (needing more shares for the same value of assets) - it('share price change during reentracy does not affect withdraw', async function () { - await this.vault.connect(this.holder).deposit(value, this.holder); - await this.vault.connect(this.other).deposit(value, this.other); - - // Schedules a reentrancy from the token contract that mess up the share price - await this.token.scheduleReenter( - reenterType.After, - this.token, - this.token.interface.encodeFunctionData('$_burn', [this.vault.target, reenterValue]), - ); - - // Price before - const sharesBefore = await this.vault.previewWithdraw(value); - - // Withdraw, triggering the _afterTokenTransfer hook - await expect(this.vault.connect(this.holder).withdraw(value, this.holder, this.holder)) - // Price is as previewed - .to.emit(this.vault, 'Withdraw') - .withArgs(this.holder, this.holder, this.holder, value, sharesBefore); - - // Price was modified during reentrancy - expect(await this.vault.previewWithdraw(value)).to.gt(sharesBefore); - }); - }); - - describe('limits', function () { - beforeEach(async function () { - const token = await ethers.deployContract('$ERC20DecimalsMock', [name, symbol, decimals]); - const vault = await ethers.deployContract('$ERC4626LimitsMock', ['', '', token]); - - Object.assign(this, { token, vault }); - }); - - it('reverts on deposit() above max deposit', async function () { - const maxDeposit = await this.vault.maxDeposit(this.holder); - await expect(this.vault.connect(this.holder).deposit(maxDeposit + 1n, this.recipient)) - .to.be.revertedWithCustomError(this.vault, 'ERC4626ExceededMaxDeposit') - .withArgs(this.recipient, maxDeposit + 1n, maxDeposit); - }); - - it('reverts on mint() above max mint', async function () { - const maxMint = await this.vault.maxMint(this.holder); - - await expect(this.vault.connect(this.holder).mint(maxMint + 1n, this.recipient)) - .to.be.revertedWithCustomError(this.vault, 'ERC4626ExceededMaxMint') - .withArgs(this.recipient, maxMint + 1n, maxMint); - }); - - it('reverts on withdraw() above max withdraw', async function () { - const maxWithdraw = await this.vault.maxWithdraw(this.holder); - - await expect(this.vault.connect(this.holder).withdraw(maxWithdraw + 1n, this.recipient, this.holder)) - .to.be.revertedWithCustomError(this.vault, 'ERC4626ExceededMaxWithdraw') - .withArgs(this.holder, maxWithdraw + 1n, maxWithdraw); - }); - - it('reverts on redeem() above max redeem', async function () { - const maxRedeem = await this.vault.maxRedeem(this.holder); - - await expect(this.vault.connect(this.holder).redeem(maxRedeem + 1n, this.recipient, this.holder)) - .to.be.revertedWithCustomError(this.vault, 'ERC4626ExceededMaxRedeem') - .withArgs(this.holder, maxRedeem + 1n, maxRedeem); - }); - }); - - for (const offset of [0n, 6n, 18n]) { - const parseToken = token => token * 10n ** decimals; - const parseShare = share => share * 10n ** (decimals + offset); - - const virtualAssets = 1n; - const virtualShares = 10n ** offset; - - describe(`offset: ${offset}`, function () { - beforeEach(async function () { - const token = await ethers.deployContract('$ERC20DecimalsMock', [name, symbol, decimals]); - const vault = await ethers.deployContract('$ERC4626OffsetMock', [name + ' Vault', symbol + 'V', token, offset]); - - await token.$_mint(this.holder, ethers.MaxUint256 / 2n); // 50% of maximum - await token.$_approve(this.holder, vault, ethers.MaxUint256); - await vault.$_approve(this.holder, this.spender, ethers.MaxUint256); - - Object.assign(this, { token, vault }); - }); - - it('metadata', async function () { - expect(await this.vault.name()).to.equal(name + ' Vault'); - expect(await this.vault.symbol()).to.equal(symbol + 'V'); - expect(await this.vault.decimals()).to.equal(decimals + offset); - expect(await this.vault.asset()).to.equal(this.token); - }); - - describe('empty vault: no assets & no shares', function () { - it('status', async function () { - expect(await this.vault.totalAssets()).to.equal(0n); - }); - - it('deposit', async function () { - expect(await this.vault.maxDeposit(this.holder)).to.equal(ethers.MaxUint256); - expect(await this.vault.previewDeposit(parseToken(1n))).to.equal(parseShare(1n)); - - const tx = this.vault.connect(this.holder).deposit(parseToken(1n), this.recipient); - - await expect(tx).to.changeTokenBalances( - this.token, - [this.holder, this.vault], - [-parseToken(1n), parseToken(1n)], - ); - await expect(tx).to.changeTokenBalance(this.vault, this.recipient, parseShare(1n)); - await expect(tx) - .to.emit(this.token, 'Transfer') - .withArgs(this.holder, this.vault, parseToken(1n)) - .to.emit(this.vault, 'Transfer') - .withArgs(ethers.ZeroAddress, this.recipient, parseShare(1n)) - .to.emit(this.vault, 'Deposit') - .withArgs(this.holder, this.recipient, parseToken(1n), parseShare(1n)); - }); - - it('mint', async function () { - expect(await this.vault.maxMint(this.holder)).to.equal(ethers.MaxUint256); - expect(await this.vault.previewMint(parseShare(1n))).to.equal(parseToken(1n)); - - const tx = this.vault.connect(this.holder).mint(parseShare(1n), this.recipient); - - await expect(tx).to.changeTokenBalances( - this.token, - [this.holder, this.vault], - [-parseToken(1n), parseToken(1n)], - ); - await expect(tx).to.changeTokenBalance(this.vault, this.recipient, parseShare(1n)); - await expect(tx) - .to.emit(this.token, 'Transfer') - .withArgs(this.holder, this.vault, parseToken(1n)) - .to.emit(this.vault, 'Transfer') - .withArgs(ethers.ZeroAddress, this.recipient, parseShare(1n)) - .to.emit(this.vault, 'Deposit') - .withArgs(this.holder, this.recipient, parseToken(1n), parseShare(1n)); - }); - - it('withdraw', async function () { - expect(await this.vault.maxWithdraw(this.holder)).to.equal(0n); - expect(await this.vault.previewWithdraw(0n)).to.equal(0n); - - const tx = this.vault.connect(this.holder).withdraw(0n, this.recipient, this.holder); - - await expect(tx).to.changeTokenBalances(this.token, [this.vault, this.recipient], [0n, 0n]); - await expect(tx).to.changeTokenBalance(this.vault, this.holder, 0n); - await expect(tx) - .to.emit(this.token, 'Transfer') - .withArgs(this.vault, this.recipient, 0n) - .to.emit(this.vault, 'Transfer') - .withArgs(this.holder, ethers.ZeroAddress, 0n) - .to.emit(this.vault, 'Withdraw') - .withArgs(this.holder, this.recipient, this.holder, 0n, 0n); - }); - - it('redeem', async function () { - expect(await this.vault.maxRedeem(this.holder)).to.equal(0n); - expect(await this.vault.previewRedeem(0n)).to.equal(0n); - - const tx = this.vault.connect(this.holder).redeem(0n, this.recipient, this.holder); - - await expect(tx).to.changeTokenBalances(this.token, [this.vault, this.recipient], [0n, 0n]); - await expect(tx).to.changeTokenBalance(this.vault, this.holder, 0n); - await expect(tx) - .to.emit(this.token, 'Transfer') - .withArgs(this.vault, this.recipient, 0n) - .to.emit(this.vault, 'Transfer') - .withArgs(this.holder, ethers.ZeroAddress, 0n) - .to.emit(this.vault, 'Withdraw') - .withArgs(this.holder, this.recipient, this.holder, 0n, 0n); - }); - }); - - describe('inflation attack: offset price by direct deposit of assets', function () { - beforeEach(async function () { - // Donate 1 token to the vault to offset the price - await this.token.$_mint(this.vault, parseToken(1n)); - }); - - it('status', async function () { - expect(await this.vault.totalSupply()).to.equal(0n); - expect(await this.vault.totalAssets()).to.equal(parseToken(1n)); - }); - - /** - * | offset | deposited assets | redeemable assets | - * |--------|----------------------|----------------------| - * | 0 | 1.000000000000000000 | 0. | - * | 6 | 1.000000000000000000 | 0.999999000000000000 | - * | 18 | 1.000000000000000000 | 0.999999999999999999 | - * - * Attack is possible, but made difficult by the offset. For the attack to be successful - * the attacker needs to frontrun a deposit 10**offset times bigger than what the victim - * was trying to deposit - */ - it('deposit', async function () { - const effectiveAssets = (await this.vault.totalAssets()) + virtualAssets; - const effectiveShares = (await this.vault.totalSupply()) + virtualShares; - - const depositAssets = parseToken(1n); - const expectedShares = (depositAssets * effectiveShares) / effectiveAssets; - - expect(await this.vault.maxDeposit(this.holder)).to.equal(ethers.MaxUint256); - expect(await this.vault.previewDeposit(depositAssets)).to.equal(expectedShares); - - const tx = this.vault.connect(this.holder).deposit(depositAssets, this.recipient); - - await expect(tx).to.changeTokenBalances( - this.token, - [this.holder, this.vault], - [-depositAssets, depositAssets], - ); - await expect(tx).to.changeTokenBalance(this.vault, this.recipient, expectedShares); - await expect(tx) - .to.emit(this.token, 'Transfer') - .withArgs(this.holder, this.vault, depositAssets) - .to.emit(this.vault, 'Transfer') - .withArgs(ethers.ZeroAddress, this.recipient, expectedShares) - .to.emit(this.vault, 'Deposit') - .withArgs(this.holder, this.recipient, depositAssets, expectedShares); - }); - - /** - * | offset | deposited assets | redeemable assets | - * |--------|----------------------|----------------------| - * | 0 | 1000000000000000001. | 1000000000000000001. | - * | 6 | 1000000000000000001. | 1000000000000000001. | - * | 18 | 1000000000000000001. | 1000000000000000001. | - * - * Using mint protects against inflation attack, but makes minting shares very expensive. - * The ER20 allowance for the underlying asset is needed to protect the user from (too) - * large deposits. - */ - it('mint', async function () { - const effectiveAssets = (await this.vault.totalAssets()) + virtualAssets; - const effectiveShares = (await this.vault.totalSupply()) + virtualShares; - - const mintShares = parseShare(1n); - const expectedAssets = (mintShares * effectiveAssets) / effectiveShares; - - expect(await this.vault.maxMint(this.holder)).to.equal(ethers.MaxUint256); - expect(await this.vault.previewMint(mintShares)).to.equal(expectedAssets); - - const tx = this.vault.connect(this.holder).mint(mintShares, this.recipient); - - await expect(tx).to.changeTokenBalances( - this.token, - [this.holder, this.vault], - [-expectedAssets, expectedAssets], - ); - await expect(tx).to.changeTokenBalance(this.vault, this.recipient, mintShares); - await expect(tx) - .to.emit(this.token, 'Transfer') - .withArgs(this.holder, this.vault, expectedAssets) - .to.emit(this.vault, 'Transfer') - .withArgs(ethers.ZeroAddress, this.recipient, mintShares) - .to.emit(this.vault, 'Deposit') - .withArgs(this.holder, this.recipient, expectedAssets, mintShares); - }); - - it('withdraw', async function () { - expect(await this.vault.maxWithdraw(this.holder)).to.equal(0n); - expect(await this.vault.previewWithdraw(0n)).to.equal(0n); - - const tx = this.vault.connect(this.holder).withdraw(0n, this.recipient, this.holder); - - await expect(tx).to.changeTokenBalances(this.token, [this.vault, this.recipient], [0n, 0n]); - await expect(tx).to.changeTokenBalance(this.vault, this.holder, 0n); - await expect(tx) - .to.emit(this.token, 'Transfer') - .withArgs(this.vault, this.recipient, 0n) - .to.emit(this.vault, 'Transfer') - .withArgs(this.holder, ethers.ZeroAddress, 0n) - .to.emit(this.vault, 'Withdraw') - .withArgs(this.holder, this.recipient, this.holder, 0n, 0n); - }); - - it('redeem', async function () { - expect(await this.vault.maxRedeem(this.holder)).to.equal(0n); - expect(await this.vault.previewRedeem(0n)).to.equal(0n); - - const tx = this.vault.connect(this.holder).redeem(0n, this.recipient, this.holder); - - await expect(tx).to.changeTokenBalances(this.token, [this.vault, this.recipient], [0n, 0n]); - await expect(tx).to.changeTokenBalance(this.vault, this.holder, 0n); - await expect(tx) - .to.emit(this.token, 'Transfer') - .withArgs(this.vault, this.recipient, 0n) - .to.emit(this.vault, 'Transfer') - .withArgs(this.holder, ethers.ZeroAddress, 0n) - .to.emit(this.vault, 'Withdraw') - .withArgs(this.holder, this.recipient, this.holder, 0n, 0n); - }); - }); - - describe('full vault: assets & shares', function () { - beforeEach(async function () { - // Add 1 token of underlying asset and 100 shares to the vault - await this.token.$_mint(this.vault, parseToken(1n)); - await this.vault.$_mint(this.holder, parseShare(100n)); - }); - - it('status', async function () { - expect(await this.vault.totalSupply()).to.equal(parseShare(100n)); - expect(await this.vault.totalAssets()).to.equal(parseToken(1n)); - }); - - /** - * | offset | deposited assets | redeemable assets | - * |--------|--------------------- |----------------------| - * | 0 | 1.000000000000000000 | 0.999999999999999999 | - * | 6 | 1.000000000000000000 | 0.999999999999999999 | - * | 18 | 1.000000000000000000 | 0.999999999999999999 | - * - * Virtual shares & assets captures part of the value - */ - it('deposit', async function () { - const effectiveAssets = (await this.vault.totalAssets()) + virtualAssets; - const effectiveShares = (await this.vault.totalSupply()) + virtualShares; - - const depositAssets = parseToken(1n); - const expectedShares = (depositAssets * effectiveShares) / effectiveAssets; - - expect(await this.vault.maxDeposit(this.holder)).to.equal(ethers.MaxUint256); - expect(await this.vault.previewDeposit(depositAssets)).to.equal(expectedShares); - - const tx = this.vault.connect(this.holder).deposit(depositAssets, this.recipient); - - await expect(tx).to.changeTokenBalances( - this.token, - [this.holder, this.vault], - [-depositAssets, depositAssets], - ); - await expect(tx).to.changeTokenBalance(this.vault, this.recipient, expectedShares); - await expect(tx) - .to.emit(this.token, 'Transfer') - .withArgs(this.holder, this.vault, depositAssets) - .to.emit(this.vault, 'Transfer') - .withArgs(ethers.ZeroAddress, this.recipient, expectedShares) - .to.emit(this.vault, 'Deposit') - .withArgs(this.holder, this.recipient, depositAssets, expectedShares); - }); - - /** - * | offset | deposited assets | redeemable assets | - * |--------|--------------------- |----------------------| - * | 0 | 0.010000000000000001 | 0.010000000000000000 | - * | 6 | 0.010000000000000001 | 0.010000000000000000 | - * | 18 | 0.010000000000000001 | 0.010000000000000000 | - * - * Virtual shares & assets captures part of the value - */ - it('mint', async function () { - const effectiveAssets = (await this.vault.totalAssets()) + virtualAssets; - const effectiveShares = (await this.vault.totalSupply()) + virtualShares; - - const mintShares = parseShare(1n); - const expectedAssets = (mintShares * effectiveAssets) / effectiveShares + 1n; // add for the rounding - - expect(await this.vault.maxMint(this.holder)).to.equal(ethers.MaxUint256); - expect(await this.vault.previewMint(mintShares)).to.equal(expectedAssets); - - const tx = this.vault.connect(this.holder).mint(mintShares, this.recipient); - - await expect(tx).to.changeTokenBalances( - this.token, - [this.holder, this.vault], - [-expectedAssets, expectedAssets], - ); - await expect(tx).to.changeTokenBalance(this.vault, this.recipient, mintShares); - await expect(tx) - .to.emit(this.token, 'Transfer') - .withArgs(this.holder, this.vault, expectedAssets) - .to.emit(this.vault, 'Transfer') - .withArgs(ethers.ZeroAddress, this.recipient, mintShares) - .to.emit(this.vault, 'Deposit') - .withArgs(this.holder, this.recipient, expectedAssets, mintShares); - }); - - it('withdraw', async function () { - const effectiveAssets = (await this.vault.totalAssets()) + virtualAssets; - const effectiveShares = (await this.vault.totalSupply()) + virtualShares; - - const withdrawAssets = parseToken(1n); - const expectedShares = (withdrawAssets * effectiveShares) / effectiveAssets + 1n; // add for the rounding - - expect(await this.vault.maxWithdraw(this.holder)).to.equal(withdrawAssets); - expect(await this.vault.previewWithdraw(withdrawAssets)).to.equal(expectedShares); - - const tx = this.vault.connect(this.holder).withdraw(withdrawAssets, this.recipient, this.holder); - - await expect(tx).to.changeTokenBalances( - this.token, - [this.vault, this.recipient], - [-withdrawAssets, withdrawAssets], - ); - await expect(tx).to.changeTokenBalance(this.vault, this.holder, -expectedShares); - await expect(tx) - .to.emit(this.token, 'Transfer') - .withArgs(this.vault, this.recipient, withdrawAssets) - .to.emit(this.vault, 'Transfer') - .withArgs(this.holder, ethers.ZeroAddress, expectedShares) - .to.emit(this.vault, 'Withdraw') - .withArgs(this.holder, this.recipient, this.holder, withdrawAssets, expectedShares); - }); - - it('withdraw with approval', async function () { - const assets = await this.vault.previewWithdraw(parseToken(1n)); - - await expect(this.vault.connect(this.other).withdraw(parseToken(1n), this.recipient, this.holder)) - .to.be.revertedWithCustomError(this.vault, 'ERC20InsufficientAllowance') - .withArgs(this.other, 0n, assets); - - await expect(this.vault.connect(this.spender).withdraw(parseToken(1n), this.recipient, this.holder)).to.not.be - .reverted; - }); - - it('redeem', async function () { - const effectiveAssets = (await this.vault.totalAssets()) + virtualAssets; - const effectiveShares = (await this.vault.totalSupply()) + virtualShares; - - const redeemShares = parseShare(100n); - const expectedAssets = (redeemShares * effectiveAssets) / effectiveShares; - - expect(await this.vault.maxRedeem(this.holder)).to.equal(redeemShares); - expect(await this.vault.previewRedeem(redeemShares)).to.equal(expectedAssets); - - const tx = this.vault.connect(this.holder).redeem(redeemShares, this.recipient, this.holder); - - await expect(tx).to.changeTokenBalances( - this.token, - [this.vault, this.recipient], - [-expectedAssets, expectedAssets], - ); - await expect(tx).to.changeTokenBalance(this.vault, this.holder, -redeemShares); - await expect(tx) - .to.emit(this.token, 'Transfer') - .withArgs(this.vault, this.recipient, expectedAssets) - .to.emit(this.vault, 'Transfer') - .withArgs(this.holder, ethers.ZeroAddress, redeemShares) - .to.emit(this.vault, 'Withdraw') - .withArgs(this.holder, this.recipient, this.holder, expectedAssets, redeemShares); - }); - - it('redeem with approval', async function () { - await expect(this.vault.connect(this.other).redeem(parseShare(100n), this.recipient, this.holder)) - .to.be.revertedWithCustomError(this.vault, 'ERC20InsufficientAllowance') - .withArgs(this.other, 0n, parseShare(100n)); - - await expect(this.vault.connect(this.spender).redeem(parseShare(100n), this.recipient, this.holder)).to.not.be - .reverted; - }); - }); - }); - } - - describe('ERC4626Fees', function () { - const feeBasisPoints = 500n; // 5% - const valueWithoutFees = 10_000n; - const fees = (valueWithoutFees * feeBasisPoints) / 10_000n; - const valueWithFees = valueWithoutFees + fees; - - describe('input fees', function () { - beforeEach(async function () { - const token = await ethers.deployContract('$ERC20DecimalsMock', [name, symbol, 18n]); - const vault = await ethers.deployContract('$ERC4626FeesMock', [ - '', - '', - token, - feeBasisPoints, - this.other, - 0n, - ethers.ZeroAddress, - ]); - - await token.$_mint(this.holder, ethers.MaxUint256 / 2n); - await token.$_approve(this.holder, vault, ethers.MaxUint256 / 2n); - - Object.assign(this, { token, vault }); - }); - - it('deposit', async function () { - expect(await this.vault.previewDeposit(valueWithFees)).to.equal(valueWithoutFees); - this.tx = this.vault.connect(this.holder).deposit(valueWithFees, this.recipient); - }); - - it('mint', async function () { - expect(await this.vault.previewMint(valueWithoutFees)).to.equal(valueWithFees); - this.tx = this.vault.connect(this.holder).mint(valueWithoutFees, this.recipient); - }); - - afterEach(async function () { - await expect(this.tx).to.changeTokenBalances( - this.token, - [this.holder, this.vault, this.other], - [-valueWithFees, valueWithoutFees, fees], - ); - await expect(this.tx).to.changeTokenBalance(this.vault, this.recipient, valueWithoutFees); - await expect(this.tx) - // get total - .to.emit(this.token, 'Transfer') - .withArgs(this.holder, this.vault, valueWithFees) - // redirect fees - .to.emit(this.token, 'Transfer') - .withArgs(this.vault, this.other, fees) - // mint shares - .to.emit(this.vault, 'Transfer') - .withArgs(ethers.ZeroAddress, this.recipient, valueWithoutFees) - // deposit event - .to.emit(this.vault, 'Deposit') - .withArgs(this.holder, this.recipient, valueWithFees, valueWithoutFees); - }); - }); - - describe('output fees', function () { - beforeEach(async function () { - const token = await ethers.deployContract('$ERC20DecimalsMock', [name, symbol, 18n]); - const vault = await ethers.deployContract('$ERC4626FeesMock', [ - '', - '', - token, - 0n, - ethers.ZeroAddress, - feeBasisPoints, - this.other, - ]); - - await token.$_mint(vault, ethers.MaxUint256 / 2n); - await vault.$_mint(this.holder, ethers.MaxUint256 / 2n); - - Object.assign(this, { token, vault }); - }); - - it('redeem', async function () { - expect(await this.vault.previewRedeem(valueWithFees)).to.equal(valueWithoutFees); - this.tx = this.vault.connect(this.holder).redeem(valueWithFees, this.recipient, this.holder); - }); - - it('withdraw', async function () { - expect(await this.vault.previewWithdraw(valueWithoutFees)).to.equal(valueWithFees); - this.tx = this.vault.connect(this.holder).withdraw(valueWithoutFees, this.recipient, this.holder); - }); - - afterEach(async function () { - await expect(this.tx).to.changeTokenBalances( - this.token, - [this.vault, this.recipient, this.other], - [-valueWithFees, valueWithoutFees, fees], - ); - await expect(this.tx).to.changeTokenBalance(this.vault, this.holder, -valueWithFees); - await expect(this.tx) - // withdraw principal - .to.emit(this.token, 'Transfer') - .withArgs(this.vault, this.recipient, valueWithoutFees) - // redirect fees - .to.emit(this.token, 'Transfer') - .withArgs(this.vault, this.other, fees) - // mint shares - .to.emit(this.vault, 'Transfer') - .withArgs(this.holder, ethers.ZeroAddress, valueWithFees) - // withdraw event - .to.emit(this.vault, 'Withdraw') - .withArgs(this.holder, this.recipient, this.holder, valueWithoutFees, valueWithFees); - }); - }); - }); - - /// 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 - const [alice, bruce] = this.accounts; - const token = await ethers.deployContract('$ERC20DecimalsMock', [name, symbol, 18n]); - const vault = await ethers.deployContract('$ERC4626', ['', '', token]); - - await token.$_mint(alice, 4000n); - await token.$_mint(bruce, 7001n); - await token.connect(alice).approve(vault, 4000n); - await token.connect(bruce).approve(vault, 7001n); - - // 1. Alice mints 2000 shares (costs 2000 tokens) - await expect(vault.connect(alice).mint(2000n, alice)) - .to.emit(token, 'Transfer') - .withArgs(alice, vault, 2000n) - .to.emit(vault, 'Transfer') - .withArgs(ethers.ZeroAddress, alice, 2000n); - - expect(await vault.previewDeposit(2000n)).to.equal(2000n); - expect(await vault.balanceOf(alice)).to.equal(2000n); - expect(await vault.balanceOf(bruce)).to.equal(0n); - expect(await vault.convertToAssets(await vault.balanceOf(alice))).to.equal(2000n); - expect(await vault.convertToAssets(await vault.balanceOf(bruce))).to.equal(0n); - expect(await vault.convertToShares(await token.balanceOf(vault))).to.equal(2000n); - expect(await vault.totalSupply()).to.equal(2000n); - expect(await vault.totalAssets()).to.equal(2000n); - - // 2. Bruce deposits 4000 tokens (mints 4000 shares) - await expect(vault.connect(bruce).mint(4000n, bruce)) - .to.emit(token, 'Transfer') - .withArgs(bruce, vault, 4000n) - .to.emit(vault, 'Transfer') - .withArgs(ethers.ZeroAddress, bruce, 4000n); - - expect(await vault.previewDeposit(4000n)).to.equal(4000n); - expect(await vault.balanceOf(alice)).to.equal(2000n); - expect(await vault.balanceOf(bruce)).to.equal(4000n); - expect(await vault.convertToAssets(await vault.balanceOf(alice))).to.equal(2000n); - expect(await vault.convertToAssets(await vault.balanceOf(bruce))).to.equal(4000n); - expect(await vault.convertToShares(await token.balanceOf(vault))).to.equal(6000n); - expect(await vault.totalSupply()).to.equal(6000n); - expect(await vault.totalAssets()).to.equal(6000n); - - // 3. Vault mutates by +3000 tokens (simulated yield returned from strategy) - await token.$_mint(vault, 3000n); - - expect(await vault.balanceOf(alice)).to.equal(2000n); - expect(await vault.balanceOf(bruce)).to.equal(4000n); - expect(await vault.convertToAssets(await vault.balanceOf(alice))).to.equal(2999n); // used to be 3000, but virtual assets/shares captures part of the yield - expect(await vault.convertToAssets(await vault.balanceOf(bruce))).to.equal(5999n); // used to be 6000, but virtual assets/shares captures part of the yield - expect(await vault.convertToShares(await token.balanceOf(vault))).to.equal(6000n); - expect(await vault.totalSupply()).to.equal(6000n); - expect(await vault.totalAssets()).to.equal(9000n); - - // 4. Alice deposits 2000 tokens (mints 1333 shares) - await expect(vault.connect(alice).deposit(2000n, alice)) - .to.emit(token, 'Transfer') - .withArgs(alice, vault, 2000n) - .to.emit(vault, 'Transfer') - .withArgs(ethers.ZeroAddress, alice, 1333n); - - expect(await vault.balanceOf(alice)).to.equal(3333n); - expect(await vault.balanceOf(bruce)).to.equal(4000n); - expect(await vault.convertToAssets(await vault.balanceOf(alice))).to.equal(4999n); - expect(await vault.convertToAssets(await vault.balanceOf(bruce))).to.equal(6000n); - expect(await vault.convertToShares(await token.balanceOf(vault))).to.equal(7333n); - expect(await vault.totalSupply()).to.equal(7333n); - expect(await vault.totalAssets()).to.equal(11000n); - - // 5. Bruce mints 2000 shares (costs 3001 assets) - // NOTE: Bruce's assets spent got rounded towards infinity - // NOTE: Alices's vault assets got rounded towards infinity - await expect(vault.connect(bruce).mint(2000n, bruce)) - .to.emit(token, 'Transfer') - .withArgs(bruce, vault, 3000n) - .to.emit(vault, 'Transfer') - .withArgs(ethers.ZeroAddress, bruce, 2000n); - - expect(await vault.balanceOf(alice)).to.equal(3333n); - expect(await vault.balanceOf(bruce)).to.equal(6000n); - expect(await vault.convertToAssets(await vault.balanceOf(alice))).to.equal(4999n); // used to be 5000 - expect(await vault.convertToAssets(await vault.balanceOf(bruce))).to.equal(9000n); - expect(await vault.convertToShares(await token.balanceOf(vault))).to.equal(9333n); - expect(await vault.totalSupply()).to.equal(9333n); - expect(await vault.totalAssets()).to.equal(14000n); // used to be 14001 - - // 6. Vault mutates by +3000 tokens - // NOTE: Vault holds 17001 tokens, but sum of assetsOf() is 17000. - await token.$_mint(vault, 3000n); - - expect(await vault.balanceOf(alice)).to.equal(3333n); - expect(await vault.balanceOf(bruce)).to.equal(6000n); - expect(await vault.convertToAssets(await vault.balanceOf(alice))).to.equal(6070n); // used to be 6071 - expect(await vault.convertToAssets(await vault.balanceOf(bruce))).to.equal(10928n); // used to be 10929 - expect(await vault.convertToShares(await token.balanceOf(vault))).to.equal(9333n); - expect(await vault.totalSupply()).to.equal(9333n); - expect(await vault.totalAssets()).to.equal(17000n); // used to be 17001 - - // 7. Alice redeem 1333 shares (2428 assets) - await expect(vault.connect(alice).redeem(1333n, alice, alice)) - .to.emit(vault, 'Transfer') - .withArgs(alice, ethers.ZeroAddress, 1333n) - .to.emit(token, 'Transfer') - .withArgs(vault, alice, 2427n); // used to be 2428 - - expect(await vault.balanceOf(alice)).to.equal(2000n); - expect(await vault.balanceOf(bruce)).to.equal(6000n); - expect(await vault.convertToAssets(await vault.balanceOf(alice))).to.equal(3643n); - expect(await vault.convertToAssets(await vault.balanceOf(bruce))).to.equal(10929n); - expect(await vault.convertToShares(await token.balanceOf(vault))).to.equal(8000n); - expect(await vault.totalSupply()).to.equal(8000n); - expect(await vault.totalAssets()).to.equal(14573n); - - // 8. Bruce withdraws 2929 assets (1608 shares) - await expect(vault.connect(bruce).withdraw(2929n, bruce, bruce)) - .to.emit(vault, 'Transfer') - .withArgs(bruce, ethers.ZeroAddress, 1608n) - .to.emit(token, 'Transfer') - .withArgs(vault, bruce, 2929n); - - expect(await vault.balanceOf(alice)).to.equal(2000n); - expect(await vault.balanceOf(bruce)).to.equal(4392n); - expect(await vault.convertToAssets(await vault.balanceOf(alice))).to.equal(3643n); - expect(await vault.convertToAssets(await vault.balanceOf(bruce))).to.equal(8000n); - expect(await vault.convertToShares(await token.balanceOf(vault))).to.equal(6392n); - expect(await vault.totalSupply()).to.equal(6392n); - expect(await vault.totalAssets()).to.equal(11644n); - - // 9. Alice withdraws 3643 assets (2000 shares) - // NOTE: Bruce's assets have been rounded back towards infinity - await expect(vault.connect(alice).withdraw(3643n, alice, alice)) - .to.emit(vault, 'Transfer') - .withArgs(alice, ethers.ZeroAddress, 2000n) - .to.emit(token, 'Transfer') - .withArgs(vault, alice, 3643n); - - expect(await vault.balanceOf(alice)).to.equal(0n); - expect(await vault.balanceOf(bruce)).to.equal(4392n); - expect(await vault.convertToAssets(await vault.balanceOf(alice))).to.equal(0n); - expect(await vault.convertToAssets(await vault.balanceOf(bruce))).to.equal(8000n); // used to be 8001 - expect(await vault.convertToShares(await token.balanceOf(vault))).to.equal(4392n); - expect(await vault.totalSupply()).to.equal(4392n); - expect(await vault.totalAssets()).to.equal(8001n); - - // 10. Bruce redeem 4392 shares (8001 tokens) - await expect(vault.connect(bruce).redeem(4392n, bruce, bruce)) - .to.emit(vault, 'Transfer') - .withArgs(bruce, ethers.ZeroAddress, 4392n) - .to.emit(token, 'Transfer') - .withArgs(vault, bruce, 8000n); // used to be 8001 - - expect(await vault.balanceOf(alice)).to.equal(0n); - expect(await vault.balanceOf(bruce)).to.equal(0n); - expect(await vault.convertToAssets(await vault.balanceOf(alice))).to.equal(0n); - expect(await vault.convertToAssets(await vault.balanceOf(bruce))).to.equal(0n); - expect(await vault.convertToShares(await token.balanceOf(vault))).to.equal(0n); - expect(await vault.totalSupply()).to.equal(0n); - expect(await vault.totalAssets()).to.equal(1n); // used to be 0 - }); -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC20/utils/SafeERC20.test.js b/lib/openzeppelin-contracts/test/token/ERC20/utils/SafeERC20.test.js deleted file mode 100644 index 16b72bd..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC20/utils/SafeERC20.test.js +++ /dev/null @@ -1,427 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const name = 'ERC20Mock'; -const symbol = 'ERC20Mock'; -const value = 100n; -const data = '0x12345678'; - -async function fixture() { - const [hasNoCode, owner, receiver, spender, other] = await ethers.getSigners(); - - const mock = await ethers.deployContract('$SafeERC20'); - const erc20ReturnFalseMock = await ethers.deployContract('$ERC20ReturnFalseMock', [name, symbol]); - const erc20ReturnTrueMock = await ethers.deployContract('$ERC20', [name, symbol]); // default implementation returns true - const erc20NoReturnMock = await ethers.deployContract('$ERC20NoReturnMock', [name, symbol]); - const erc20ForceApproveMock = await ethers.deployContract('$ERC20ForceApproveMock', [name, symbol]); - const erc1363Mock = await ethers.deployContract('$ERC1363', [name, symbol]); - const erc1363ReturnFalseOnErc20Mock = await ethers.deployContract('$ERC1363ReturnFalseOnERC20Mock', [name, symbol]); - const erc1363ReturnFalseMock = await ethers.deployContract('$ERC1363ReturnFalseMock', [name, symbol]); - const erc1363NoReturnMock = await ethers.deployContract('$ERC1363NoReturnMock', [name, symbol]); - const erc1363ForceApproveMock = await ethers.deployContract('$ERC1363ForceApproveMock', [name, symbol]); - const erc1363Receiver = await ethers.deployContract('$ERC1363ReceiverMock'); - const erc1363Spender = await ethers.deployContract('$ERC1363SpenderMock'); - - return { - hasNoCode, - owner, - receiver, - spender, - other, - mock, - erc20ReturnFalseMock, - erc20ReturnTrueMock, - erc20NoReturnMock, - erc20ForceApproveMock, - erc1363Mock, - erc1363ReturnFalseOnErc20Mock, - erc1363ReturnFalseMock, - erc1363NoReturnMock, - erc1363ForceApproveMock, - erc1363Receiver, - erc1363Spender, - }; -} - -describe('SafeERC20', function () { - before(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('with address that has no contract code', function () { - beforeEach(async function () { - this.token = this.hasNoCode; - }); - - it('reverts on transfer', async function () { - await expect(this.mock.$safeTransfer(this.token, this.receiver, 0n)) - .to.be.revertedWithCustomError(this.mock, 'SafeERC20FailedOperation') - .withArgs(this.token); - }); - - it('reverts on transferFrom', async function () { - await expect(this.mock.$safeTransferFrom(this.token, this.mock, this.receiver, 0n)) - .to.be.revertedWithCustomError(this.mock, 'SafeERC20FailedOperation') - .withArgs(this.token); - }); - - it('reverts on increaseAllowance', async function () { - // Call to 'token.allowance' does not return any data, resulting in a decoding error (revert without reason) - await expect(this.mock.$safeIncreaseAllowance(this.token, this.spender, 0n)).to.be.revertedWithoutReason(); - }); - - it('reverts on decreaseAllowance', async function () { - // Call to 'token.allowance' does not return any data, resulting in a decoding error (revert without reason) - await expect(this.mock.$safeDecreaseAllowance(this.token, this.spender, 0n)).to.be.revertedWithoutReason(); - }); - - it('reverts on forceApprove', async function () { - await expect(this.mock.$forceApprove(this.token, this.spender, 0n)) - .to.be.revertedWithCustomError(this.mock, 'SafeERC20FailedOperation') - .withArgs(this.token); - }); - }); - - describe('with token that returns false on all calls', function () { - beforeEach(async function () { - this.token = this.erc20ReturnFalseMock; - }); - - it('reverts on transfer', async function () { - await expect(this.mock.$safeTransfer(this.token, this.receiver, 0n)) - .to.be.revertedWithCustomError(this.mock, 'SafeERC20FailedOperation') - .withArgs(this.token); - }); - - it('reverts on transferFrom', async function () { - await expect(this.mock.$safeTransferFrom(this.token, this.mock, this.receiver, 0n)) - .to.be.revertedWithCustomError(this.mock, 'SafeERC20FailedOperation') - .withArgs(this.token); - }); - - it('reverts on increaseAllowance', async function () { - await expect(this.mock.$safeIncreaseAllowance(this.token, this.spender, 0n)) - .to.be.revertedWithCustomError(this.mock, 'SafeERC20FailedOperation') - .withArgs(this.token); - }); - - it('reverts on decreaseAllowance', async function () { - await expect(this.mock.$safeDecreaseAllowance(this.token, this.spender, 0n)) - .to.be.revertedWithCustomError(this.mock, 'SafeERC20FailedOperation') - .withArgs(this.token); - }); - - it('reverts on forceApprove', async function () { - await expect(this.mock.$forceApprove(this.token, this.spender, 0n)) - .to.be.revertedWithCustomError(this.mock, 'SafeERC20FailedOperation') - .withArgs(this.token); - }); - }); - - describe('with token that returns true on all calls', function () { - beforeEach(async function () { - this.token = this.erc20ReturnTrueMock; - }); - - shouldOnlyRevertOnErrors(); - }); - - describe('with token that returns no boolean values', function () { - beforeEach(async function () { - this.token = this.erc20NoReturnMock; - }); - - shouldOnlyRevertOnErrors(); - }); - - describe('with usdt approval behaviour', function () { - beforeEach(async function () { - this.token = this.erc20ForceApproveMock; - }); - - describe('with initial approval', function () { - beforeEach(async function () { - await this.token.$_approve(this.mock, this.spender, 100n); - }); - - it('safeIncreaseAllowance works', async function () { - await this.mock.$safeIncreaseAllowance(this.token, this.spender, 10n); - expect(await this.token.allowance(this.mock, this.spender)).to.equal(110n); - }); - - it('safeDecreaseAllowance works', async function () { - await this.mock.$safeDecreaseAllowance(this.token, this.spender, 10n); - expect(await this.token.allowance(this.mock, this.spender)).to.equal(90n); - }); - - it('forceApprove works', async function () { - await this.mock.$forceApprove(this.token, this.spender, 200n); - expect(await this.token.allowance(this.mock, this.spender)).to.equal(200n); - }); - }); - }); - - describe('with standard ERC1363', function () { - beforeEach(async function () { - this.token = this.erc1363Mock; - }); - - shouldOnlyRevertOnErrors(); - - describe('transferAndCall', function () { - it('cannot transferAndCall to an EOA directly', async function () { - await this.token.$_mint(this.owner, 100n); - - await expect(this.token.connect(this.owner).transferAndCall(this.receiver, value, ethers.Typed.bytes(data))) - .to.be.revertedWithCustomError(this.token, 'ERC1363InvalidReceiver') - .withArgs(this.receiver); - }); - - it('can transferAndCall to an EOA using helper', async function () { - await this.token.$_mint(this.mock, value); - - await expect(this.mock.$transferAndCallRelaxed(this.token, this.receiver, value, data)) - .to.emit(this.token, 'Transfer') - .withArgs(this.mock, this.receiver, value); - }); - - it('can transferAndCall to an ERC1363Receiver using helper', async function () { - await this.token.$_mint(this.mock, value); - - await expect(this.mock.$transferAndCallRelaxed(this.token, this.erc1363Receiver, value, data)) - .to.emit(this.token, 'Transfer') - .withArgs(this.mock, this.erc1363Receiver, value) - .to.emit(this.erc1363Receiver, 'Received') - .withArgs(this.mock, this.mock, value, data); - }); - }); - - describe('transferFromAndCall', function () { - it('can transferFromAndCall to an EOA using helper', async function () { - await this.token.$_mint(this.owner, value); - await this.token.$_approve(this.owner, this.mock, ethers.MaxUint256); - - await expect(this.mock.$transferFromAndCallRelaxed(this.token, this.owner, this.receiver, value, data)) - .to.emit(this.token, 'Transfer') - .withArgs(this.owner, this.receiver, value); - }); - - it('can transferFromAndCall to an ERC1363Receiver using helper', async function () { - await this.token.$_mint(this.owner, value); - await this.token.$_approve(this.owner, this.mock, ethers.MaxUint256); - - await expect(this.mock.$transferFromAndCallRelaxed(this.token, this.owner, this.erc1363Receiver, value, data)) - .to.emit(this.token, 'Transfer') - .withArgs(this.owner, this.erc1363Receiver, value) - .to.emit(this.erc1363Receiver, 'Received') - .withArgs(this.mock, this.owner, value, data); - }); - }); - - describe('approveAndCall', function () { - it('can approveAndCall to an EOA using helper', async function () { - await expect(this.mock.$approveAndCallRelaxed(this.token, this.receiver, value, data)) - .to.emit(this.token, 'Approval') - .withArgs(this.mock, this.receiver, value); - }); - - it('can approveAndCall to an ERC1363Spender using helper', async function () { - await expect(this.mock.$approveAndCallRelaxed(this.token, this.erc1363Spender, value, data)) - .to.emit(this.token, 'Approval') - .withArgs(this.mock, this.erc1363Spender, value) - .to.emit(this.erc1363Spender, 'Approved') - .withArgs(this.mock, value, data); - }); - }); - }); - - describe('with ERC1363 that returns false on all ERC20 calls', function () { - beforeEach(async function () { - this.token = this.erc1363ReturnFalseOnErc20Mock; - }); - - it('reverts on transferAndCallRelaxed', async function () { - await expect(this.mock.$transferAndCallRelaxed(this.token, this.erc1363Receiver, 0n, data)) - .to.be.revertedWithCustomError(this.token, 'ERC1363TransferFailed') - .withArgs(this.erc1363Receiver, 0n); - }); - - it('reverts on transferFromAndCallRelaxed', async function () { - await expect(this.mock.$transferFromAndCallRelaxed(this.token, this.mock, this.erc1363Receiver, 0n, data)) - .to.be.revertedWithCustomError(this.token, 'ERC1363TransferFromFailed') - .withArgs(this.mock, this.erc1363Receiver, 0n); - }); - - it('reverts on approveAndCallRelaxed', async function () { - await expect(this.mock.$approveAndCallRelaxed(this.token, this.erc1363Spender, 0n, data)) - .to.be.revertedWithCustomError(this.token, 'ERC1363ApproveFailed') - .withArgs(this.erc1363Spender, 0n); - }); - }); - - describe('with ERC1363 that returns false on all ERC1363 calls', function () { - beforeEach(async function () { - this.token = this.erc1363ReturnFalseMock; - }); - - it('reverts on transferAndCallRelaxed', async function () { - await expect(this.mock.$transferAndCallRelaxed(this.token, this.erc1363Receiver, 0n, data)) - .to.be.revertedWithCustomError(this.mock, 'SafeERC20FailedOperation') - .withArgs(this.token); - }); - - it('reverts on transferFromAndCallRelaxed', async function () { - await expect(this.mock.$transferFromAndCallRelaxed(this.token, this.mock, this.erc1363Receiver, 0n, data)) - .to.be.revertedWithCustomError(this.mock, 'SafeERC20FailedOperation') - .withArgs(this.token); - }); - - it('reverts on approveAndCallRelaxed', async function () { - await expect(this.mock.$approveAndCallRelaxed(this.token, this.erc1363Spender, 0n, data)) - .to.be.revertedWithCustomError(this.mock, 'SafeERC20FailedOperation') - .withArgs(this.token); - }); - }); - - describe('with ERC1363 that returns no boolean values', function () { - beforeEach(async function () { - this.token = this.erc1363NoReturnMock; - }); - - it('reverts on transferAndCallRelaxed', async function () { - await expect( - this.mock.$transferAndCallRelaxed(this.token, this.erc1363Receiver, 0n, data), - ).to.be.revertedWithoutReason(); - }); - - it('reverts on transferFromAndCallRelaxed', async function () { - await expect( - this.mock.$transferFromAndCallRelaxed(this.token, this.mock, this.erc1363Receiver, 0n, data), - ).to.be.revertedWithoutReason(); - }); - - it('reverts on approveAndCallRelaxed', async function () { - await expect( - this.mock.$approveAndCallRelaxed(this.token, this.erc1363Spender, 0n, data), - ).to.be.revertedWithoutReason(); - }); - }); - - describe('with ERC1363 with usdt approval behaviour', function () { - beforeEach(async function () { - this.token = this.erc1363ForceApproveMock; - }); - - describe('without initial approval', function () { - it('approveAndCallRelaxed works when recipient is an EOA', async function () { - await this.mock.$approveAndCallRelaxed(this.token, this.spender, 10n, data); - expect(await this.token.allowance(this.mock, this.spender)).to.equal(10n); - }); - - it('approveAndCallRelaxed works when recipient is a contract', async function () { - await this.mock.$approveAndCallRelaxed(this.token, this.erc1363Spender, 10n, data); - expect(await this.token.allowance(this.mock, this.erc1363Spender)).to.equal(10n); - }); - }); - - describe('with initial approval', function () { - it('approveAndCallRelaxed works when recipient is an EOA', async function () { - await this.token.$_approve(this.mock, this.spender, 100n); - - await this.mock.$approveAndCallRelaxed(this.token, this.spender, 10n, data); - expect(await this.token.allowance(this.mock, this.spender)).to.equal(10n); - }); - - it('approveAndCallRelaxed reverts when recipient is a contract', async function () { - await this.token.$_approve(this.mock, this.erc1363Spender, 100n); - await expect(this.mock.$approveAndCallRelaxed(this.token, this.erc1363Spender, 10n, data)).to.be.revertedWith( - 'USDT approval failure', - ); - }); - }); - }); -}); - -function shouldOnlyRevertOnErrors() { - describe('transfers', function () { - beforeEach(async function () { - await this.token.$_mint(this.owner, 100n); - await this.token.$_mint(this.mock, 100n); - await this.token.$_approve(this.owner, this.mock, ethers.MaxUint256); - }); - - it("doesn't revert on transfer", async function () { - await expect(this.mock.$safeTransfer(this.token, this.receiver, 10n)) - .to.emit(this.token, 'Transfer') - .withArgs(this.mock, this.receiver, 10n); - }); - - it("doesn't revert on transferFrom", async function () { - await expect(this.mock.$safeTransferFrom(this.token, this.owner, this.receiver, 10n)) - .to.emit(this.token, 'Transfer') - .withArgs(this.owner, this.receiver, 10n); - }); - }); - - describe('approvals', function () { - describe('with zero allowance', function () { - beforeEach(async function () { - await this.token.$_approve(this.mock, this.spender, 0n); - }); - - it("doesn't revert when force approving a non-zero allowance", async function () { - await this.mock.$forceApprove(this.token, this.spender, 100n); - expect(await this.token.allowance(this.mock, this.spender)).to.equal(100n); - }); - - it("doesn't revert when force approving a zero allowance", async function () { - await this.mock.$forceApprove(this.token, this.spender, 0n); - expect(await this.token.allowance(this.mock, this.spender)).to.equal(0n); - }); - - it("doesn't revert when increasing the allowance", async function () { - await this.mock.$safeIncreaseAllowance(this.token, this.spender, 10n); - expect(await this.token.allowance(this.mock, this.spender)).to.equal(10n); - }); - - it('reverts when decreasing the allowance', async function () { - await expect(this.mock.$safeDecreaseAllowance(this.token, this.spender, 10n)) - .to.be.revertedWithCustomError(this.mock, 'SafeERC20FailedDecreaseAllowance') - .withArgs(this.spender, 0n, 10n); - }); - }); - - describe('with non-zero allowance', function () { - beforeEach(async function () { - await this.token.$_approve(this.mock, this.spender, 100n); - }); - - it("doesn't revert when force approving a non-zero allowance", async function () { - await this.mock.$forceApprove(this.token, this.spender, 20n); - expect(await this.token.allowance(this.mock, this.spender)).to.equal(20n); - }); - - it("doesn't revert when force approving a zero allowance", async function () { - await this.mock.$forceApprove(this.token, this.spender, 0n); - expect(await this.token.allowance(this.mock, this.spender)).to.equal(0n); - }); - - it("doesn't revert when increasing the allowance", async function () { - await this.mock.$safeIncreaseAllowance(this.token, this.spender, 10n); - expect(await this.token.allowance(this.mock, this.spender)).to.equal(110n); - }); - - it("doesn't revert when decreasing the allowance to a positive value", async function () { - await this.mock.$safeDecreaseAllowance(this.token, this.spender, 50n); - expect(await this.token.allowance(this.mock, this.spender)).to.equal(50n); - }); - - it('reverts when decreasing the allowance to a negative value', async function () { - await expect(this.mock.$safeDecreaseAllowance(this.token, this.spender, 200n)) - .to.be.revertedWithCustomError(this.mock, 'SafeERC20FailedDecreaseAllowance') - .withArgs(this.spender, 100n, 200n); - }); - }); - }); -} diff --git a/lib/openzeppelin-contracts/test/token/ERC721/ERC721.behavior.js b/lib/openzeppelin-contracts/test/token/ERC721/ERC721.behavior.js deleted file mode 100644 index b9dd80d..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC721/ERC721.behavior.js +++ /dev/null @@ -1,972 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); -const { anyValue } = require('@nomicfoundation/hardhat-chai-matchers/withArgs'); - -const { shouldSupportInterfaces } = require('../../utils/introspection/SupportsInterface.behavior'); -const { RevertType } = require('../../helpers/enums'); - -const firstTokenId = 5042n; -const secondTokenId = 79217n; -const nonExistentTokenId = 13n; -const fourthTokenId = 4n; -const baseURI = 'https://api.example.com/v1/'; - -const RECEIVER_MAGIC_VALUE = '0x150b7a02'; - -function shouldBehaveLikeERC721() { - beforeEach(async function () { - const [owner, newOwner, approved, operator, other] = this.accounts; - Object.assign(this, { owner, newOwner, approved, operator, other }); - }); - - shouldSupportInterfaces(['ERC721']); - - describe('with minted tokens', function () { - beforeEach(async function () { - await this.token.$_mint(this.owner, firstTokenId); - await this.token.$_mint(this.owner, secondTokenId); - this.to = this.other; - }); - - describe('balanceOf', function () { - describe('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(this.owner)).to.equal(2n); - }); - }); - - describe('when the given address does not own any tokens', function () { - it('returns 0', async function () { - expect(await this.token.balanceOf(this.other)).to.equal(0n); - }); - }); - - describe('when querying the zero address', function () { - it('throws', async function () { - await expect(this.token.balanceOf(ethers.ZeroAddress)) - .to.be.revertedWithCustomError(this.token, 'ERC721InvalidOwner') - .withArgs(ethers.ZeroAddress); - }); - }); - }); - - describe('ownerOf', function () { - describe('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.equal(this.owner); - }); - }); - - describe('when the given token ID was not tracked by this token', function () { - const tokenId = nonExistentTokenId; - - it('reverts', async function () { - await expect(this.token.ownerOf(tokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721NonexistentToken') - .withArgs(tokenId); - }); - }); - }); - - describe('transfers', function () { - const tokenId = firstTokenId; - const data = '0x42'; - - beforeEach(async function () { - await this.token.connect(this.owner).approve(this.approved, tokenId); - await this.token.connect(this.owner).setApprovalForAll(this.operator, true); - }); - - const transferWasSuccessful = () => { - it('transfers the ownership of the given token ID to the given address', async function () { - await this.tx(); - expect(await this.token.ownerOf(tokenId)).to.equal(this.to); - }); - - it('emits a Transfer event', async function () { - await expect(this.tx()).to.emit(this.token, 'Transfer').withArgs(this.owner, this.to, tokenId); - }); - - it('clears the approval for the token ID with no event', async function () { - await expect(this.tx()).to.not.emit(this.token, 'Approval'); - - expect(await this.token.getApproved(tokenId)).to.equal(ethers.ZeroAddress); - }); - - it('adjusts owners balances', async function () { - const balanceBefore = await this.token.balanceOf(this.owner); - await this.tx(); - expect(await this.token.balanceOf(this.owner)).to.equal(balanceBefore - 1n); - }); - - it('adjusts owners tokens by index', async function () { - if (!this.token.tokenOfOwnerByIndex) return; - - await this.tx(); - expect(await this.token.tokenOfOwnerByIndex(this.to, 0n)).to.equal(tokenId); - expect(await this.token.tokenOfOwnerByIndex(this.owner, 0n)).to.not.equal(tokenId); - }); - }; - - const shouldTransferTokensByUsers = function (fragment, opts = {}) { - describe('when called by the owner', function () { - beforeEach(async function () { - this.tx = () => - this.token.connect(this.owner)[fragment](this.owner, this.to, tokenId, ...(opts.extra ?? [])); - }); - transferWasSuccessful(); - }); - - describe('when called by the approved individual', function () { - beforeEach(async function () { - this.tx = () => - this.token.connect(this.approved)[fragment](this.owner, this.to, tokenId, ...(opts.extra ?? [])); - }); - transferWasSuccessful(); - }); - - describe('when called by the operator', function () { - beforeEach(async function () { - this.tx = () => - this.token.connect(this.operator)[fragment](this.owner, this.to, tokenId, ...(opts.extra ?? [])); - }); - transferWasSuccessful(); - }); - - describe('when called by the owner without an approved user', function () { - beforeEach(async function () { - await this.token.connect(this.owner).approve(ethers.ZeroAddress, tokenId); - this.tx = () => - this.token.connect(this.operator)[fragment](this.owner, this.to, tokenId, ...(opts.extra ?? [])); - }); - transferWasSuccessful(); - }); - - describe('when sent to the owner', function () { - beforeEach(async function () { - this.tx = () => - this.token.connect(this.owner)[fragment](this.owner, this.owner, tokenId, ...(opts.extra ?? [])); - }); - - it('keeps ownership of the token', async function () { - await this.tx(); - expect(await this.token.ownerOf(tokenId)).to.equal(this.owner); - }); - - it('clears the approval for the token ID', async function () { - await this.tx(); - expect(await this.token.getApproved(tokenId)).to.equal(ethers.ZeroAddress); - }); - - it('emits only a transfer event', async function () { - await expect(this.tx()).to.emit(this.token, 'Transfer').withArgs(this.owner, this.owner, tokenId); - }); - - it('keeps the owner balance', async function () { - const balanceBefore = await this.token.balanceOf(this.owner); - await this.tx(); - expect(await this.token.balanceOf(this.owner)).to.equal(balanceBefore); - }); - - it('keeps same tokens by index', async function () { - if (!this.token.tokenOfOwnerByIndex) return; - - expect(await Promise.all([0n, 1n].map(i => this.token.tokenOfOwnerByIndex(this.owner, i)))).to.have.members( - [firstTokenId, secondTokenId], - ); - }); - }); - - describe('when the address of the previous owner is incorrect', function () { - it('reverts', async function () { - await expect( - this.token.connect(this.owner)[fragment](this.other, this.other, tokenId, ...(opts.extra ?? [])), - ) - .to.be.revertedWithCustomError(this.token, 'ERC721IncorrectOwner') - .withArgs(this.other, tokenId, this.owner); - }); - }); - - describe('when the sender is not authorized for the token id', function () { - if (opts.unrestricted) { - it('does not revert', async function () { - await this.token.connect(this.other)[fragment](this.owner, this.other, tokenId, ...(opts.extra ?? [])); - }); - } else { - it('reverts', async function () { - await expect( - this.token.connect(this.other)[fragment](this.owner, this.other, tokenId, ...(opts.extra ?? [])), - ) - .to.be.revertedWithCustomError(this.token, 'ERC721InsufficientApproval') - .withArgs(this.other, tokenId); - }); - } - }); - - describe('when the given token ID does not exist', function () { - it('reverts', async function () { - await expect( - this.token - .connect(this.owner) - [fragment](this.owner, this.other, nonExistentTokenId, ...(opts.extra ?? [])), - ) - .to.be.revertedWithCustomError(this.token, 'ERC721NonexistentToken') - .withArgs(nonExistentTokenId); - }); - }); - - describe('when the address to transfer the token to is the zero address', function () { - it('reverts', async function () { - await expect( - this.token.connect(this.owner)[fragment](this.owner, ethers.ZeroAddress, tokenId, ...(opts.extra ?? [])), - ) - .to.be.revertedWithCustomError(this.token, 'ERC721InvalidReceiver') - .withArgs(ethers.ZeroAddress); - }); - }); - }; - - const shouldTransferSafely = function (fragment, data, opts = {}) { - // sanity - it('function exists', async function () { - expect(this.token.interface.hasFunction(fragment)).to.be.true; - }); - - describe('to a user account', function () { - shouldTransferTokensByUsers(fragment, opts); - }); - - describe('to a valid receiver contract', function () { - beforeEach(async function () { - this.to = await ethers.deployContract('ERC721ReceiverMock', [RECEIVER_MAGIC_VALUE, RevertType.None]); - }); - - shouldTransferTokensByUsers(fragment, opts); - - it('calls onERC721Received', async function () { - await expect(this.token.connect(this.owner)[fragment](this.owner, this.to, tokenId, ...(opts.extra ?? []))) - .to.emit(this.to, 'Received') - .withArgs(this.owner, this.owner, tokenId, data, anyValue); - }); - - it('calls onERC721Received from approved', async function () { - await expect( - this.token.connect(this.approved)[fragment](this.owner, this.to, tokenId, ...(opts.extra ?? [])), - ) - .to.emit(this.to, 'Received') - .withArgs(this.approved, this.owner, tokenId, data, anyValue); - }); - - describe('with an invalid token id', function () { - it('reverts', async function () { - await expect( - this.token - .connect(this.approved) - [fragment](this.owner, this.to, nonExistentTokenId, ...(opts.extra ?? [])), - ) - .to.be.revertedWithCustomError(this.token, 'ERC721NonexistentToken') - .withArgs(nonExistentTokenId); - }); - }); - }); - }; - - for (const { fnName, opts } of [ - { fnName: 'transferFrom', opts: {} }, - { fnName: '$_transfer', opts: { unrestricted: true } }, - ]) { - describe(`via ${fnName}`, function () { - shouldTransferTokensByUsers(fnName, opts); - }); - } - - for (const { fnName, opts } of [ - { fnName: 'safeTransferFrom', opts: {} }, - { fnName: '$_safeTransfer', opts: { unrestricted: true } }, - ]) { - describe(`via ${fnName}`, function () { - describe('with data', function () { - shouldTransferSafely(fnName, data, { ...opts, extra: [ethers.Typed.bytes(data)] }); - }); - - describe('without data', function () { - shouldTransferSafely(fnName, '0x', opts); - }); - - describe('to a receiver contract returning unexpected value', function () { - it('reverts', async function () { - const invalidReceiver = await ethers.deployContract('ERC721ReceiverMock', [ - '0xdeadbeef', - RevertType.None, - ]); - - await expect(this.token.connect(this.owner)[fnName](this.owner, invalidReceiver, tokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721InvalidReceiver') - .withArgs(invalidReceiver); - }); - }); - - describe('to a receiver contract that reverts with message', function () { - it('reverts', async function () { - const revertingReceiver = await ethers.deployContract('ERC721ReceiverMock', [ - RECEIVER_MAGIC_VALUE, - RevertType.RevertWithMessage, - ]); - - await expect( - this.token.connect(this.owner)[fnName](this.owner, revertingReceiver, tokenId), - ).to.be.revertedWith('ERC721ReceiverMock: reverting'); - }); - }); - - describe('to a receiver contract that reverts without message', function () { - it('reverts', async function () { - const revertingReceiver = await ethers.deployContract('ERC721ReceiverMock', [ - RECEIVER_MAGIC_VALUE, - RevertType.RevertWithoutMessage, - ]); - - await expect(this.token.connect(this.owner)[fnName](this.owner, revertingReceiver, tokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721InvalidReceiver') - .withArgs(revertingReceiver); - }); - }); - - describe('to a receiver contract that reverts with custom error', function () { - it('reverts', async function () { - const revertingReceiver = await ethers.deployContract('ERC721ReceiverMock', [ - RECEIVER_MAGIC_VALUE, - RevertType.RevertWithCustomError, - ]); - - await expect(this.token.connect(this.owner)[fnName](this.owner, revertingReceiver, tokenId)) - .to.be.revertedWithCustomError(revertingReceiver, 'CustomError') - .withArgs(RECEIVER_MAGIC_VALUE); - }); - }); - - describe('to a receiver contract that panics', function () { - it('reverts', async function () { - const revertingReceiver = await ethers.deployContract('ERC721ReceiverMock', [ - RECEIVER_MAGIC_VALUE, - RevertType.Panic, - ]); - - await expect( - this.token.connect(this.owner)[fnName](this.owner, revertingReceiver, tokenId), - ).to.be.revertedWithPanic(PANIC_CODES.DIVISION_BY_ZERO); - }); - }); - - describe('to a contract that does not implement the required function', function () { - it('reverts', async function () { - const nonReceiver = await ethers.deployContract('CallReceiverMock'); - - await expect(this.token.connect(this.owner)[fnName](this.owner, nonReceiver, tokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721InvalidReceiver') - .withArgs(nonReceiver); - }); - }); - }); - } - }); - - 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 () { - const receiver = await ethers.deployContract('ERC721ReceiverMock', [RECEIVER_MAGIC_VALUE, RevertType.None]); - - await expect(await this.token.$_safeMint(receiver, tokenId, ethers.Typed.bytes(data))) - .to.emit(receiver, 'Received') - .withArgs(anyValue, ethers.ZeroAddress, tokenId, data, anyValue); - }); - - it('calls onERC721Received — without data', async function () { - const receiver = await ethers.deployContract('ERC721ReceiverMock', [RECEIVER_MAGIC_VALUE, RevertType.None]); - - await expect(await this.token.$_safeMint(receiver, tokenId)) - .to.emit(receiver, 'Received') - .withArgs(anyValue, ethers.ZeroAddress, tokenId, '0x', anyValue); - }); - - describe('to a receiver contract returning unexpected value', function () { - it('reverts', async function () { - const invalidReceiver = await ethers.deployContract('ERC721ReceiverMock', ['0xdeadbeef', RevertType.None]); - - await expect(this.token.$_safeMint(invalidReceiver, tokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721InvalidReceiver') - .withArgs(invalidReceiver); - }); - }); - - describe('to a receiver contract that reverts with message', function () { - it('reverts', async function () { - const revertingReceiver = await ethers.deployContract('ERC721ReceiverMock', [ - RECEIVER_MAGIC_VALUE, - RevertType.RevertWithMessage, - ]); - - await expect(this.token.$_safeMint(revertingReceiver, tokenId)).to.be.revertedWith( - 'ERC721ReceiverMock: reverting', - ); - }); - }); - - describe('to a receiver contract that reverts without message', function () { - it('reverts', async function () { - const revertingReceiver = await ethers.deployContract('ERC721ReceiverMock', [ - RECEIVER_MAGIC_VALUE, - RevertType.RevertWithoutMessage, - ]); - - await expect(this.token.$_safeMint(revertingReceiver, tokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721InvalidReceiver') - .withArgs(revertingReceiver); - }); - }); - - describe('to a receiver contract that reverts with custom error', function () { - it('reverts', async function () { - const revertingReceiver = await ethers.deployContract('ERC721ReceiverMock', [ - RECEIVER_MAGIC_VALUE, - RevertType.RevertWithCustomError, - ]); - - await expect(this.token.$_safeMint(revertingReceiver, tokenId)) - .to.be.revertedWithCustomError(revertingReceiver, 'CustomError') - .withArgs(RECEIVER_MAGIC_VALUE); - }); - }); - - describe('to a receiver contract that panics', function () { - it('reverts', async function () { - const revertingReceiver = await ethers.deployContract('ERC721ReceiverMock', [ - RECEIVER_MAGIC_VALUE, - RevertType.Panic, - ]); - - await expect(this.token.$_safeMint(revertingReceiver, tokenId)).to.be.revertedWithPanic( - PANIC_CODES.DIVISION_BY_ZERO, - ); - }); - }); - - describe('to a contract that does not implement the required function', function () { - it('reverts', async function () { - const nonReceiver = await ethers.deployContract('CallReceiverMock'); - - await expect(this.token.$_safeMint(nonReceiver, tokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721InvalidReceiver') - .withArgs(nonReceiver); - }); - }); - }); - }); - - describe('approve', function () { - const tokenId = firstTokenId; - - const itClearsApproval = function () { - it('clears approval for the token', async function () { - expect(await this.token.getApproved(tokenId)).to.equal(ethers.ZeroAddress); - }); - }; - - const itApproves = function () { - it('sets the approval for the target address', async function () { - expect(await this.token.getApproved(tokenId)).to.equal(this.approved ?? this.approved); - }); - }; - - const itEmitsApprovalEvent = function () { - it('emits an approval event', async function () { - await expect(this.tx) - .to.emit(this.token, 'Approval') - .withArgs(this.owner, this.approved ?? this.approved, tokenId); - }); - }; - - describe('when clearing approval', function () { - describe('when there was no prior approval', function () { - beforeEach(async function () { - this.approved = ethers.ZeroAddress; - this.tx = await this.token.connect(this.owner).approve(this.approved, tokenId); - }); - - itClearsApproval(); - itEmitsApprovalEvent(); - }); - - describe('when there was a prior approval', function () { - beforeEach(async function () { - await this.token.connect(this.owner).approve(this.other, tokenId); - this.approved = ethers.ZeroAddress; - this.tx = await this.token.connect(this.owner).approve(this.approved, tokenId); - }); - - itClearsApproval(); - itEmitsApprovalEvent(); - }); - }); - - describe('when approving a non-zero address', function () { - describe('when there was no prior approval', function () { - beforeEach(async function () { - this.tx = await this.token.connect(this.owner).approve(this.approved, tokenId); - }); - - itApproves(); - itEmitsApprovalEvent(); - }); - - describe('when there was a prior approval to the same address', function () { - beforeEach(async function () { - await this.token.connect(this.owner).approve(this.approved, tokenId); - this.tx = await this.token.connect(this.owner).approve(this.approved, tokenId); - }); - - itApproves(); - itEmitsApprovalEvent(); - }); - - describe('when there was a prior approval to a different address', function () { - beforeEach(async function () { - await this.token.connect(this.owner).approve(this.other, tokenId); - this.tx = await this.token.connect(this.owner).approve(this.approved, tokenId); - }); - - itApproves(); - itEmitsApprovalEvent(); - }); - }); - - describe('when the sender does not own the given token ID', function () { - it('reverts', async function () { - await expect(this.token.connect(this.other).approve(this.approved, tokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721InvalidApprover') - .withArgs(this.other); - }); - }); - - describe('when the sender is approved for the given token ID', function () { - it('reverts', async function () { - await this.token.connect(this.owner).approve(this.approved, tokenId); - - await expect(this.token.connect(this.approved).approve(this.other, tokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721InvalidApprover') - .withArgs(this.approved); - }); - }); - - describe('when the sender is an operator', function () { - beforeEach(async function () { - await this.token.connect(this.owner).setApprovalForAll(this.operator, true); - - this.tx = await this.token.connect(this.operator).approve(this.approved, tokenId); - }); - - itApproves(); - itEmitsApprovalEvent(); - }); - - describe('when the given token ID does not exist', function () { - it('reverts', async function () { - await expect(this.token.connect(this.operator).approve(this.approved, nonExistentTokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721NonexistentToken') - .withArgs(nonExistentTokenId); - }); - }); - }); - - describe('setApprovalForAll', function () { - describe('when the operator willing to approve is not the owner', function () { - describe('when there is no operator approval set by the sender', function () { - it('approves the operator', async function () { - await this.token.connect(this.owner).setApprovalForAll(this.operator, true); - - expect(await this.token.isApprovedForAll(this.owner, this.operator)).to.be.true; - }); - - it('emits an approval event', async function () { - await expect(this.token.connect(this.owner).setApprovalForAll(this.operator, true)) - .to.emit(this.token, 'ApprovalForAll') - .withArgs(this.owner, this.operator, true); - }); - }); - - describe('when the operator was set as not approved', function () { - beforeEach(async function () { - await this.token.connect(this.owner).setApprovalForAll(this.operator, false); - }); - - it('approves the operator', async function () { - await this.token.connect(this.owner).setApprovalForAll(this.operator, true); - - expect(await this.token.isApprovedForAll(this.owner, this.operator)).to.be.true; - }); - - it('emits an approval event', async function () { - await expect(this.token.connect(this.owner).setApprovalForAll(this.operator, true)) - .to.emit(this.token, 'ApprovalForAll') - .withArgs(this.owner, this.operator, true); - }); - - it('can unset the operator approval', async function () { - await this.token.connect(this.owner).setApprovalForAll(this.operator, false); - - expect(await this.token.isApprovedForAll(this.owner, this.operator)).to.be.false; - }); - }); - - describe('when the operator was already approved', function () { - beforeEach(async function () { - await this.token.connect(this.owner).setApprovalForAll(this.operator, true); - }); - - it('keeps the approval to the given address', async function () { - await this.token.connect(this.owner).setApprovalForAll(this.operator, true); - - expect(await this.token.isApprovedForAll(this.owner, this.operator)).to.be.true; - }); - - it('emits an approval event', async function () { - await expect(this.token.connect(this.owner).setApprovalForAll(this.operator, true)) - .to.emit(this.token, 'ApprovalForAll') - .withArgs(this.owner, this.operator, true); - }); - }); - }); - - describe('when the operator is address zero', function () { - it('reverts', async function () { - await expect(this.token.connect(this.owner).setApprovalForAll(ethers.ZeroAddress, true)) - .to.be.revertedWithCustomError(this.token, 'ERC721InvalidOperator') - .withArgs(ethers.ZeroAddress); - }); - }); - }); - - describe('getApproved', function () { - describe('when token is not minted', function () { - it('reverts', async function () { - await expect(this.token.getApproved(nonExistentTokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721NonexistentToken') - .withArgs(nonExistentTokenId); - }); - }); - - describe('when token has been minted ', function () { - it('should return the zero address', async function () { - expect(await this.token.getApproved(firstTokenId)).to.equal(ethers.ZeroAddress); - }); - - describe('when account has been approved', function () { - beforeEach(async function () { - await this.token.connect(this.owner).approve(this.approved, firstTokenId); - }); - - it('returns approved account', async function () { - expect(await this.token.getApproved(firstTokenId)).to.equal(this.approved); - }); - }); - }); - }); - }); - - describe('_mint(address, uint256)', function () { - it('reverts with a null destination address', async function () { - await expect(this.token.$_mint(ethers.ZeroAddress, firstTokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721InvalidReceiver') - .withArgs(ethers.ZeroAddress); - }); - - describe('with minted token', function () { - beforeEach(async function () { - this.tx = await this.token.$_mint(this.owner, firstTokenId); - }); - - it('emits a Transfer event', async function () { - await expect(this.tx).to.emit(this.token, 'Transfer').withArgs(ethers.ZeroAddress, this.owner, firstTokenId); - }); - - it('creates the token', async function () { - expect(await this.token.balanceOf(this.owner)).to.equal(1n); - expect(await this.token.ownerOf(firstTokenId)).to.equal(this.owner); - }); - - it('reverts when adding a token id that already exists', async function () { - await expect(this.token.$_mint(this.owner, firstTokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721InvalidSender') - .withArgs(ethers.ZeroAddress); - }); - }); - }); - - describe('_burn', function () { - it('reverts when burning a non-existent token id', async function () { - await expect(this.token.$_burn(nonExistentTokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721NonexistentToken') - .withArgs(nonExistentTokenId); - }); - - describe('with minted tokens', function () { - beforeEach(async function () { - await this.token.$_mint(this.owner, firstTokenId); - await this.token.$_mint(this.owner, secondTokenId); - }); - - describe('with burnt token', function () { - beforeEach(async function () { - this.tx = await this.token.$_burn(firstTokenId); - }); - - it('emits a Transfer event', async function () { - await expect(this.tx).to.emit(this.token, 'Transfer').withArgs(this.owner, ethers.ZeroAddress, firstTokenId); - }); - - it('deletes the token', async function () { - expect(await this.token.balanceOf(this.owner)).to.equal(1n); - await expect(this.token.ownerOf(firstTokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721NonexistentToken') - .withArgs(firstTokenId); - }); - - it('reverts when burning a token id that has been deleted', async function () { - await expect(this.token.$_burn(firstTokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721NonexistentToken') - .withArgs(firstTokenId); - }); - }); - }); - }); -} - -function shouldBehaveLikeERC721Enumerable() { - beforeEach(async function () { - const [owner, newOwner, approved, operator, other] = this.accounts; - Object.assign(this, { owner, newOwner, approved, operator, other }); - }); - - shouldSupportInterfaces(['ERC721Enumerable']); - - describe('with minted tokens', function () { - beforeEach(async function () { - await this.token.$_mint(this.owner, firstTokenId); - await this.token.$_mint(this.owner, secondTokenId); - this.to = this.other; - }); - - describe('totalSupply', function () { - it('returns total token supply', async function () { - expect(await this.token.totalSupply()).to.equal(2n); - }); - }); - - 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(this.owner, 0n)).to.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 expect(this.token.tokenOfOwnerByIndex(this.owner, 2n)) - .to.be.revertedWithCustomError(this.token, 'ERC721OutOfBoundsIndex') - .withArgs(this.owner, 2n); - }); - }); - - describe('when the given address does not own any token', function () { - it('reverts', async function () { - await expect(this.token.tokenOfOwnerByIndex(this.other, 0n)) - .to.be.revertedWithCustomError(this.token, 'ERC721OutOfBoundsIndex') - .withArgs(this.other, 0n); - }); - }); - - describe('after transferring all tokens to another user', function () { - beforeEach(async function () { - await this.token.connect(this.owner).transferFrom(this.owner, this.other, firstTokenId); - await this.token.connect(this.owner).transferFrom(this.owner, this.other, secondTokenId); - }); - - it('returns correct token IDs for target', async function () { - expect(await this.token.balanceOf(this.other)).to.equal(2n); - - expect(await Promise.all([0n, 1n].map(i => this.token.tokenOfOwnerByIndex(this.other, i)))).to.have.members([ - firstTokenId, - secondTokenId, - ]); - }); - - it('returns empty collection for original owner', async function () { - expect(await this.token.balanceOf(this.owner)).to.equal(0n); - await expect(this.token.tokenOfOwnerByIndex(this.owner, 0n)) - .to.be.revertedWithCustomError(this.token, 'ERC721OutOfBoundsIndex') - .withArgs(this.owner, 0n); - }); - }); - }); - - describe('tokenByIndex', function () { - it('returns all tokens', async function () { - expect(await Promise.all([0n, 1n].map(i => this.token.tokenByIndex(i)))).to.have.members([ - firstTokenId, - secondTokenId, - ]); - }); - - it('reverts if index is greater than supply', async function () { - await expect(this.token.tokenByIndex(2n)) - .to.be.revertedWithCustomError(this.token, 'ERC721OutOfBoundsIndex') - .withArgs(ethers.ZeroAddress, 2n); - }); - - for (const tokenId of [firstTokenId, secondTokenId]) { - it(`returns all tokens after burning token ${tokenId} and minting new tokens`, async function () { - const newTokenId = 300n; - const anotherNewTokenId = 400n; - - await this.token.$_burn(tokenId); - await this.token.$_mint(this.newOwner, newTokenId); - await this.token.$_mint(this.newOwner, anotherNewTokenId); - - expect(await this.token.totalSupply()).to.equal(3n); - - expect(await Promise.all([0n, 1n, 2n].map(i => this.token.tokenByIndex(i)))) - .to.have.members([firstTokenId, secondTokenId, newTokenId, anotherNewTokenId].filter(x => x !== tokenId)) - .to.not.include(tokenId); - }); - } - }); - }); - - describe('_mint(address, uint256)', function () { - it('reverts with a null destination address', async function () { - await expect(this.token.$_mint(ethers.ZeroAddress, firstTokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721InvalidReceiver') - .withArgs(ethers.ZeroAddress); - }); - - describe('with minted token', function () { - beforeEach(async function () { - await this.token.$_mint(this.owner, firstTokenId); - }); - - it('adjusts owner tokens by index', async function () { - expect(await this.token.tokenOfOwnerByIndex(this.owner, 0n)).to.equal(firstTokenId); - }); - - it('adjusts all tokens list', async function () { - expect(await this.token.tokenByIndex(0n)).to.equal(firstTokenId); - }); - }); - }); - - describe('_burn', function () { - it('reverts when burning a non-existent token id', async function () { - await expect(this.token.$_burn(firstTokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721NonexistentToken') - .withArgs(firstTokenId); - }); - - describe('with minted tokens', function () { - beforeEach(async function () { - await this.token.$_mint(this.owner, firstTokenId); - await this.token.$_mint(this.owner, secondTokenId); - }); - - describe('with burnt token', function () { - beforeEach(async function () { - await this.token.$_burn(firstTokenId); - }); - - it('removes that token from the token list of the owner', async function () { - expect(await this.token.tokenOfOwnerByIndex(this.owner, 0n)).to.equal(secondTokenId); - }); - - it('adjusts all tokens list', async function () { - expect(await this.token.tokenByIndex(0n)).to.equal(secondTokenId); - }); - - it('burns all tokens', async function () { - await this.token.$_burn(secondTokenId); - expect(await this.token.totalSupply()).to.equal(0n); - - await expect(this.token.tokenByIndex(0n)) - .to.be.revertedWithCustomError(this.token, 'ERC721OutOfBoundsIndex') - .withArgs(ethers.ZeroAddress, 0n); - }); - }); - }); - }); -} - -function shouldBehaveLikeERC721Metadata(name, symbol) { - shouldSupportInterfaces(['ERC721Metadata']); - - describe('metadata', function () { - 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); - }); - - describe('token URI', function () { - beforeEach(async function () { - await this.token.$_mint(this.owner, firstTokenId); - }); - - it('return empty string by default', async function () { - expect(await this.token.tokenURI(firstTokenId)).to.equal(''); - }); - - it('reverts when queried for non existent token id', async function () { - await expect(this.token.tokenURI(nonExistentTokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721NonexistentToken') - .withArgs(nonExistentTokenId); - }); - - describe('base URI', function () { - beforeEach(function () { - if (!this.token.interface.hasFunction('setBaseURI')) { - 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.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.equal(newBaseURI + firstTokenId.toString()); - }); - }); - }); - }); -} - -module.exports = { - shouldBehaveLikeERC721, - shouldBehaveLikeERC721Enumerable, - shouldBehaveLikeERC721Metadata, -}; diff --git a/lib/openzeppelin-contracts/test/token/ERC721/ERC721.test.js b/lib/openzeppelin-contracts/test/token/ERC721/ERC721.test.js deleted file mode 100644 index 1454cb0..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC721/ERC721.test.js +++ /dev/null @@ -1,23 +0,0 @@ -const { ethers } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { shouldBehaveLikeERC721, shouldBehaveLikeERC721Metadata } = require('./ERC721.behavior'); - -const name = 'Non Fungible Token'; -const symbol = 'NFT'; - -async function fixture() { - return { - accounts: await ethers.getSigners(), - token: await ethers.deployContract('$ERC721', [name, symbol]), - }; -} - -describe('ERC721', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - shouldBehaveLikeERC721(); - shouldBehaveLikeERC721Metadata(name, symbol); -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC721/ERC721Enumerable.test.js b/lib/openzeppelin-contracts/test/token/ERC721/ERC721Enumerable.test.js deleted file mode 100644 index a3bdea7..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC721/ERC721Enumerable.test.js +++ /dev/null @@ -1,28 +0,0 @@ -const { ethers } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { - shouldBehaveLikeERC721, - shouldBehaveLikeERC721Metadata, - shouldBehaveLikeERC721Enumerable, -} = require('./ERC721.behavior'); - -const name = 'Non Fungible Token'; -const symbol = 'NFT'; - -async function fixture() { - return { - accounts: await ethers.getSigners(), - token: await ethers.deployContract('$ERC721Enumerable', [name, symbol]), - }; -} - -describe('ERC721', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - shouldBehaveLikeERC721(); - shouldBehaveLikeERC721Metadata(name, symbol); - shouldBehaveLikeERC721Enumerable(); -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Burnable.test.js b/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Burnable.test.js deleted file mode 100644 index d6f0b80..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Burnable.test.js +++ /dev/null @@ -1,77 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const name = 'Non Fungible Token'; -const symbol = 'NFT'; -const tokenId = 1n; -const otherTokenId = 2n; -const unknownTokenId = 3n; - -async function fixture() { - const [owner, approved, another] = await ethers.getSigners(); - const token = await ethers.deployContract('$ERC721Burnable', [name, symbol]); - return { owner, approved, another, token }; -} - -describe('ERC721Burnable', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('like a burnable ERC721', function () { - beforeEach(async function () { - await this.token.$_mint(this.owner, tokenId); - await this.token.$_mint(this.owner, otherTokenId); - }); - - describe('burn', function () { - describe('when successful', function () { - it('emits a burn event, burns the given token ID and adjusts the balance of the owner', async function () { - const balanceBefore = await this.token.balanceOf(this.owner); - - await expect(this.token.connect(this.owner).burn(tokenId)) - .to.emit(this.token, 'Transfer') - .withArgs(this.owner, ethers.ZeroAddress, tokenId); - - await expect(this.token.ownerOf(tokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721NonexistentToken') - .withArgs(tokenId); - - expect(await this.token.balanceOf(this.owner)).to.equal(balanceBefore - 1n); - }); - }); - - describe('when there is a previous approval burned', function () { - beforeEach(async function () { - await this.token.connect(this.owner).approve(this.approved, tokenId); - await this.token.connect(this.owner).burn(tokenId); - }); - - describe('getApproved', function () { - it('reverts', async function () { - await expect(this.token.getApproved(tokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721NonexistentToken') - .withArgs(tokenId); - }); - }); - }); - - describe('when there is no previous approval burned', function () { - it('reverts', async function () { - await expect(this.token.connect(this.another).burn(tokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721InsufficientApproval') - .withArgs(this.another, tokenId); - }); - }); - - describe('when the given token ID was not tracked by this contract', function () { - it('reverts', async function () { - await expect(this.token.connect(this.owner).burn(unknownTokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721NonexistentToken') - .withArgs(unknownTokenId); - }); - }); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Consecutive.t.sol b/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Consecutive.t.sol deleted file mode 100644 index eca15e7..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Consecutive.t.sol +++ /dev/null @@ -1,181 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -// solhint-disable func-name-mixedcase - -import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; -import {ERC721Consecutive} from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Consecutive.sol"; -import {Test, StdUtils} from "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 { - uint96 private immutable _offset; - uint256 public totalMinted = 0; - - constructor(address[] memory receivers, uint256[] memory batches, uint256 startingId) ERC721("", "") { - _offset = uint96(startingId); - 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); - } - - function _firstConsecutiveId() internal view virtual override returns (uint96) { - return _offset; - } -} - -contract ERC721ConsecutiveTest is Test { - function test_balance(address receiver, uint256[] calldata batches, uint96 startingId) public { - vm.assume(receiver != address(0)); - - uint256 startingTokenId = bound(startingId, 0, 5000); - - ERC721ConsecutiveTarget token = new ERC721ConsecutiveTarget(toSingleton(receiver), batches, startingTokenId); - - assertEq(token.balanceOf(receiver), token.totalMinted()); - } - - function test_ownership( - address receiver, - uint256[] calldata batches, - uint256[2] calldata unboundedTokenId, - uint96 startingId - ) public { - vm.assume(receiver != address(0)); - - uint256 startingTokenId = bound(startingId, 0, 5000); - - ERC721ConsecutiveTarget token = new ERC721ConsecutiveTarget(toSingleton(receiver), batches, startingTokenId); - - if (token.totalMinted() > 0) { - uint256 validTokenId = bound( - unboundedTokenId[0], - startingTokenId, - startingTokenId + token.totalMinted() - 1 - ); - assertEq(token.ownerOf(validTokenId), receiver); - } - - uint256 invalidTokenId = bound( - unboundedTokenId[1], - startingTokenId + token.totalMinted(), - startingTokenId + token.totalMinted() + 1 - ); - vm.expectRevert(); - token.ownerOf(invalidTokenId); - } - - function test_burn( - address receiver, - uint256[] calldata batches, - uint256 unboundedTokenId, - uint96 startingId - ) public { - vm.assume(receiver != address(0)); - - uint256 startingTokenId = bound(startingId, 0, 5000); - - ERC721ConsecutiveTarget token = new ERC721ConsecutiveTarget(toSingleton(receiver), batches, startingTokenId); - - // 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, startingTokenId, startingTokenId + 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, - uint96 startingId - ) public { - vm.assume(accounts[0] != address(0)); - vm.assume(accounts[1] != address(0)); - vm.assume(accounts[0] != accounts[1]); - - uint256 startingTokenId = bound(startingId, 1, 5000); - - 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], startingTokenId, 5000); - batches[1] = bound(unboundedBatches[1], startingTokenId, 5000); - - ERC721ConsecutiveTarget token = new ERC721ConsecutiveTarget(receivers, batches, startingTokenId); - - uint256 tokenId0 = bound(unboundedTokenId[0], startingTokenId, batches[0]); - uint256 tokenId1 = bound(unboundedTokenId[1], startingTokenId, batches[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]); - } - - function test_start_consecutive_id( - address receiver, - uint256[2] calldata unboundedBatches, - uint256[2] calldata unboundedTokenId, - uint96 startingId - ) public { - vm.assume(receiver != address(0)); - - uint256 startingTokenId = bound(startingId, 1, 5000); - - // We assume _maxBatchSize is 5000 (the default). This test will break otherwise. - uint256[] memory batches = new uint256[](2); - batches[0] = bound(unboundedBatches[0], startingTokenId, 5000); - batches[1] = bound(unboundedBatches[1], startingTokenId, 5000); - - ERC721ConsecutiveTarget token = new ERC721ConsecutiveTarget(toSingleton(receiver), batches, startingTokenId); - - uint256 tokenId0 = bound(unboundedTokenId[0], startingTokenId, batches[0]); - uint256 tokenId1 = bound(unboundedTokenId[1], startingTokenId, batches[1]); - - assertEq(token.ownerOf(tokenId0), receiver); - assertEq(token.ownerOf(tokenId1), receiver); - assertEq(token.balanceOf(receiver), batches[0] + batches[1]); - } -} diff --git a/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Consecutive.test.js b/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Consecutive.test.js deleted file mode 100644 index d2eda94..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Consecutive.test.js +++ /dev/null @@ -1,236 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { sum } = require('../../../helpers/math'); - -const name = 'Non Fungible Token'; -const symbol = 'NFT'; - -describe('ERC721Consecutive', function () { - for (const offset of [0n, 1n, 42n]) { - describe(`with offset ${offset}`, function () { - async function fixture() { - const accounts = await ethers.getSigners(); - const [alice, bruce, chris, receiver] = accounts; - - const batches = [ - { receiver: alice, amount: 0n }, - { receiver: alice, amount: 1n }, - { receiver: alice, amount: 2n }, - { receiver: bruce, amount: 5n }, - { receiver: chris, amount: 0n }, - { receiver: alice, amount: 7n }, - ]; - const delegates = [alice, chris]; - - const token = await ethers.deployContract('$ERC721ConsecutiveMock', [ - name, - symbol, - offset, - delegates, - batches.map(({ receiver }) => receiver), - batches.map(({ amount }) => amount), - ]); - - return { accounts, alice, bruce, chris, receiver, batches, delegates, token }; - } - - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('minting during construction', function () { - it('events are emitted at construction', async function () { - let first = offset; - for (const batch of this.batches) { - if (batch.amount > 0) { - await expect(this.token.deploymentTransaction()) - .to.emit(this.token, 'ConsecutiveTransfer') - .withArgs( - first /* fromTokenId */, - first + batch.amount - 1n /* toTokenId */, - ethers.ZeroAddress /* fromAddress */, - batch.receiver /* toAddress */, - ); - } else { - // ".to.not.emit" only looks at event name, and doesn't check the parameters - } - first += batch.amount; - } - }); - - it('ownership is set', async function () { - const owners = [ - ...Array(Number(offset)).fill(ethers.ZeroAddress), - ...this.batches.flatMap(({ receiver, amount }) => Array(Number(amount)).fill(receiver.address)), - ]; - - for (const tokenId in owners) { - if (owners[tokenId] != ethers.ZeroAddress) { - expect(await this.token.ownerOf(tokenId)).to.equal(owners[tokenId]); - } - } - }); - - it('balance & voting power are set', async function () { - for (const account of this.accounts) { - const balance = - sum(...this.batches.filter(({ receiver }) => receiver === account).map(({ amount }) => amount)) ?? 0n; - - expect(await this.token.balanceOf(account)).to.equal(balance); - - // If not delegated at construction, check before + do delegation - if (!this.delegates.includes(account)) { - expect(await this.token.getVotes(account)).to.equal(0n); - - await this.token.connect(account).delegate(account); - } - - // At this point all accounts should have delegated - expect(await this.token.getVotes(account)).to.equal(balance); - } - }); - - it('reverts on consecutive minting to the zero address', async function () { - await expect( - ethers.deployContract('$ERC721ConsecutiveMock', [ - name, - symbol, - offset, - this.delegates, - [ethers.ZeroAddress], - [10], - ]), - ) - .to.be.revertedWithCustomError(this.token, 'ERC721InvalidReceiver') - .withArgs(ethers.ZeroAddress); - }); - }); - - describe('minting after construction', function () { - it('consecutive minting is not possible after construction', async function () { - await expect(this.token.$_mintConsecutive(this.alice, 10)).to.be.revertedWithCustomError( - this.token, - 'ERC721ForbiddenBatchMint', - ); - }); - - it('simple minting is possible after construction', async function () { - const tokenId = sum(...this.batches.map(b => b.amount)) + offset; - - await expect(this.token.ownerOf(tokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721NonexistentToken') - .withArgs(tokenId); - - await expect(this.token.$_mint(this.alice, tokenId)) - .to.emit(this.token, 'Transfer') - .withArgs(ethers.ZeroAddress, this.alice, tokenId); - }); - - it('cannot mint a token that has been batched minted', async function () { - const tokenId = sum(...this.batches.map(b => b.amount)) + offset - 1n; - - expect(await this.token.ownerOf(tokenId)).to.not.equal(ethers.ZeroAddress); - - await expect(this.token.$_mint(this.alice, tokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721InvalidSender') - .withArgs(ethers.ZeroAddress); - }); - }); - - describe('ERC721 behavior', function () { - const tokenId = offset + 1n; - - it('core takes over ownership on transfer', async function () { - await this.token.connect(this.alice).transferFrom(this.alice, this.receiver, tokenId); - - expect(await this.token.ownerOf(tokenId)).to.equal(this.receiver); - }); - - it('tokens can be burned and re-minted #1', async function () { - await expect(this.token.connect(this.alice).$_burn(tokenId)) - .to.emit(this.token, 'Transfer') - .withArgs(this.alice, ethers.ZeroAddress, tokenId); - - await expect(this.token.ownerOf(tokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721NonexistentToken') - .withArgs(tokenId); - - await expect(this.token.$_mint(this.bruce, tokenId)) - .to.emit(this.token, 'Transfer') - .withArgs(ethers.ZeroAddress, this.bruce, tokenId); - - expect(await this.token.ownerOf(tokenId)).to.equal(this.bruce); - }); - - it('tokens can be burned and re-minted #2', async function () { - const tokenId = sum(...this.batches.map(({ amount }) => amount)) + offset; - - await expect(this.token.ownerOf(tokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721NonexistentToken') - .withArgs(tokenId); - - // mint - await expect(this.token.$_mint(this.alice, tokenId)) - .to.emit(this.token, 'Transfer') - .withArgs(ethers.ZeroAddress, this.alice, tokenId); - - expect(await this.token.ownerOf(tokenId)).to.equal(this.alice); - - // burn - await expect(await this.token.$_burn(tokenId)) - .to.emit(this.token, 'Transfer') - .withArgs(this.alice, ethers.ZeroAddress, tokenId); - - await expect(this.token.ownerOf(tokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721NonexistentToken') - .withArgs(tokenId); - - // re-mint - await expect(this.token.$_mint(this.bruce, tokenId)) - .to.emit(this.token, 'Transfer') - .withArgs(ethers.ZeroAddress, this.bruce, tokenId); - - expect(await this.token.ownerOf(tokenId)).to.equal(this.bruce); - }); - }); - }); - } - - describe('invalid use', function () { - const receiver = ethers.Wallet.createRandom(); - - it('cannot mint a batch larger than 5000', async function () { - const { interface } = await ethers.getContractFactory('$ERC721ConsecutiveMock'); - - await expect(ethers.deployContract('$ERC721ConsecutiveMock', [name, symbol, 0, [], [receiver], [5001n]])) - .to.be.revertedWithCustomError({ interface }, 'ERC721ExceededMaxBatchMint') - .withArgs(5001n, 5000n); - }); - - it('cannot use single minting during construction', async function () { - const { interface } = await ethers.getContractFactory('$ERC721ConsecutiveNoConstructorMintMock'); - - await expect( - ethers.deployContract('$ERC721ConsecutiveNoConstructorMintMock', [name, symbol]), - ).to.be.revertedWithCustomError({ interface }, 'ERC721ForbiddenMint'); - }); - - it('cannot use single minting during construction', async function () { - const { interface } = await ethers.getContractFactory('$ERC721ConsecutiveNoConstructorMintMock'); - - await expect( - ethers.deployContract('$ERC721ConsecutiveNoConstructorMintMock', [name, symbol]), - ).to.be.revertedWithCustomError({ interface }, 'ERC721ForbiddenMint'); - }); - - it('consecutive mint not compatible with enumerability', async function () { - const { interface } = await ethers.getContractFactory('$ERC721ConsecutiveEnumerableMock'); - - await expect( - ethers.deployContract('$ERC721ConsecutiveEnumerableMock', [name, symbol, [receiver], [100n]]), - ).to.be.revertedWithCustomError({ interface }, 'ERC721EnumerableForbiddenBatchMint'); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Pausable.test.js b/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Pausable.test.js deleted file mode 100644 index acf731a..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Pausable.test.js +++ /dev/null @@ -1,81 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const name = 'Non Fungible Token'; -const symbol = 'NFT'; -const tokenId = 1n; -const otherTokenId = 2n; -const data = ethers.Typed.bytes('0x42'); - -async function fixture() { - const [owner, receiver, operator] = await ethers.getSigners(); - const token = await ethers.deployContract('$ERC721Pausable', [name, symbol]); - return { owner, receiver, operator, token }; -} - -describe('ERC721Pausable', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('when token is paused', function () { - beforeEach(async function () { - await this.token.$_mint(this.owner, tokenId); - await this.token.$_pause(); - }); - - it('reverts when trying to transferFrom', async function () { - await expect( - this.token.connect(this.owner).transferFrom(this.owner, this.receiver, tokenId), - ).to.be.revertedWithCustomError(this.token, 'EnforcedPause'); - }); - - it('reverts when trying to safeTransferFrom', async function () { - await expect( - this.token.connect(this.owner).safeTransferFrom(this.owner, this.receiver, tokenId), - ).to.be.revertedWithCustomError(this.token, 'EnforcedPause'); - }); - - it('reverts when trying to safeTransferFrom with data', async function () { - await expect( - this.token.connect(this.owner).safeTransferFrom(this.owner, this.receiver, tokenId, data), - ).to.be.revertedWithCustomError(this.token, 'EnforcedPause'); - }); - - it('reverts when trying to mint', async function () { - await expect(this.token.$_mint(this.receiver, otherTokenId)).to.be.revertedWithCustomError( - this.token, - 'EnforcedPause', - ); - }); - - it('reverts when trying to burn', async function () { - await expect(this.token.$_burn(tokenId)).to.be.revertedWithCustomError(this.token, 'EnforcedPause'); - }); - - describe('getApproved', function () { - it('returns approved address', async function () { - expect(await this.token.getApproved(tokenId)).to.equal(ethers.ZeroAddress); - }); - }); - - describe('balanceOf', function () { - it('returns the amount of tokens owned by the given address', async function () { - expect(await this.token.balanceOf(this.owner)).to.equal(1n); - }); - }); - - describe('ownerOf', function () { - it('returns the amount of tokens owned by the given address', async function () { - expect(await this.token.ownerOf(tokenId)).to.equal(this.owner); - }); - }); - - describe('isApprovedForAll', function () { - it('returns the approval of the operator', async function () { - expect(await this.token.isApprovedForAll(this.owner, this.operator)).to.be.false; - }); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Royalty.test.js b/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Royalty.test.js deleted file mode 100644 index e11954a..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Royalty.test.js +++ /dev/null @@ -1,57 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { shouldBehaveLikeERC2981 } = require('../../common/ERC2981.behavior'); - -const name = 'Non Fungible Token'; -const symbol = 'NFT'; - -const tokenId1 = 1n; -const tokenId2 = 2n; -const royalty = 200n; -const salePrice = 1000n; - -async function fixture() { - const [account1, account2, recipient] = await ethers.getSigners(); - - const token = await ethers.deployContract('$ERC721Royalty', [name, symbol]); - await token.$_mint(account1, tokenId1); - await token.$_mint(account1, tokenId2); - - return { account1, account2, recipient, token }; -} - -describe('ERC721Royalty', function () { - beforeEach(async function () { - Object.assign( - this, - await loadFixture(fixture), - { tokenId1, tokenId2, royalty, salePrice }, // set for behavior tests - ); - }); - - describe('token specific functions', function () { - beforeEach(async function () { - await this.token.$_setTokenRoyalty(tokenId1, this.recipient, royalty); - }); - - it('royalty information are kept during burn and re-mint', async function () { - await this.token.$_burn(tokenId1); - - expect(await this.token.royaltyInfo(tokenId1, salePrice)).to.deep.equal([ - this.recipient.address, - (salePrice * royalty) / 10000n, - ]); - - await this.token.$_mint(this.account2, tokenId1); - - expect(await this.token.royaltyInfo(tokenId1, salePrice)).to.deep.equal([ - this.recipient.address, - (salePrice * royalty) / 10000n, - ]); - }); - }); - - shouldBehaveLikeERC2981(); -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721URIStorage.test.js b/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721URIStorage.test.js deleted file mode 100644 index 830c13a..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721URIStorage.test.js +++ /dev/null @@ -1,121 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { shouldSupportInterfaces } = require('../../../utils/introspection/SupportsInterface.behavior'); - -const name = 'Non Fungible Token'; -const symbol = 'NFT'; -const baseURI = 'https://api.example.com/v1/'; -const otherBaseURI = 'https://api.example.com/v2/'; -const sampleUri = 'mock://mytoken'; -const tokenId = 1n; -const nonExistentTokenId = 2n; - -async function fixture() { - const [owner] = await ethers.getSigners(); - const token = await ethers.deployContract('$ERC721URIStorageMock', [name, symbol]); - return { owner, token }; -} - -describe('ERC721URIStorage', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - shouldSupportInterfaces(['0x49064906']); - - describe('token URI', function () { - beforeEach(async function () { - await this.token.$_mint(this.owner, tokenId); - }); - - it('it is empty by default', async function () { - expect(await this.token.tokenURI(tokenId)).to.equal(''); - }); - - it('reverts when queried for non existent token id', async function () { - await expect(this.token.tokenURI(nonExistentTokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721NonexistentToken') - .withArgs(nonExistentTokenId); - }); - - it('can be set for a token id', async function () { - await this.token.$_setTokenURI(tokenId, sampleUri); - expect(await this.token.tokenURI(tokenId)).to.equal(sampleUri); - }); - - it('setting the uri emits an event', async function () { - await expect(this.token.$_setTokenURI(tokenId, sampleUri)) - .to.emit(this.token, 'MetadataUpdate') - .withArgs(tokenId); - }); - - it('setting the uri for non existent token id is allowed', async function () { - await expect(await this.token.$_setTokenURI(nonExistentTokenId, sampleUri)) - .to.emit(this.token, 'MetadataUpdate') - .withArgs(nonExistentTokenId); - - // value will be accessible after mint - await this.token.$_mint(this.owner, nonExistentTokenId); - expect(await this.token.tokenURI(nonExistentTokenId)).to.equal(sampleUri); - }); - - 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(tokenId, sampleUri); - - expect(await this.token.tokenURI(tokenId)).to.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(tokenId, sampleUri); - - await this.token.setBaseURI(otherBaseURI); - expect(await this.token.tokenURI(tokenId)).to.equal(otherBaseURI + 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(tokenId)).to.equal(baseURI + tokenId); - }); - - it('tokens without URI can be burnt ', async function () { - await this.token.$_burn(tokenId); - - await expect(this.token.tokenURI(tokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721NonexistentToken') - .withArgs(tokenId); - }); - - it('tokens with URI can be burnt ', async function () { - await this.token.$_setTokenURI(tokenId, sampleUri); - - await this.token.$_burn(tokenId); - - await expect(this.token.tokenURI(tokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721NonexistentToken') - .withArgs(tokenId); - }); - - it('tokens URI is kept if token is burnt and reminted ', async function () { - await this.token.$_setTokenURI(tokenId, sampleUri); - - await this.token.$_burn(tokenId); - - await expect(this.token.tokenURI(tokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721NonexistentToken') - .withArgs(tokenId); - - await this.token.$_mint(this.owner, tokenId); - expect(await this.token.tokenURI(tokenId)).to.equal(sampleUri); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Votes.test.js b/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Votes.test.js deleted file mode 100644 index dcae1b8..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Votes.test.js +++ /dev/null @@ -1,194 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture, mine } = require('@nomicfoundation/hardhat-network-helpers'); - -const time = require('../../../helpers/time'); - -const { shouldBehaveLikeVotes } = require('../../../governance/utils/Votes.behavior'); - -const TOKENS = [ - { Token: '$ERC721Votes', mode: 'blocknumber' }, - // no timestamp mode for ERC721Votes yet -]; - -const name = 'My Vote'; -const symbol = 'MTKN'; -const version = '1'; -const tokens = [ethers.parseEther('10000000'), 10n, 20n, 30n]; - -describe('ERC721Votes', function () { - for (const { Token, mode } of TOKENS) { - const fixture = async () => { - // accounts is required by shouldBehaveLikeVotes - const accounts = await ethers.getSigners(); - const [holder, recipient, other1, other2] = accounts; - - const token = await ethers.deployContract(Token, [name, symbol, name, version]); - - return { accounts, holder, recipient, other1, other2, token }; - }; - - describe(`vote with ${mode}`, function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - this.votes = this.token; - }); - - // includes ERC6372 behavior check - shouldBehaveLikeVotes(tokens, { mode, fungible: false }); - - describe('balanceOf', function () { - beforeEach(async function () { - await this.votes.$_mint(this.holder, tokens[0]); - await this.votes.$_mint(this.holder, tokens[1]); - await this.votes.$_mint(this.holder, tokens[2]); - await this.votes.$_mint(this.holder, tokens[3]); - }); - - it('grants to initial account', async function () { - expect(await this.votes.balanceOf(this.holder)).to.equal(4n); - }); - }); - - describe('transfers', function () { - beforeEach(async function () { - await this.votes.$_mint(this.holder, tokens[0]); - }); - - it('no delegation', async function () { - await expect(this.votes.connect(this.holder).transferFrom(this.holder, this.recipient, tokens[0])) - .to.emit(this.token, 'Transfer') - .withArgs(this.holder, this.recipient, tokens[0]) - .to.not.emit(this.token, 'DelegateVotesChanged'); - - this.holderVotes = 0n; - this.recipientVotes = 0n; - }); - - it('sender delegation', async function () { - await this.votes.connect(this.holder).delegate(this.holder); - - const tx = await this.votes.connect(this.holder).transferFrom(this.holder, this.recipient, tokens[0]); - await expect(tx) - .to.emit(this.token, 'Transfer') - .withArgs(this.holder, this.recipient, tokens[0]) - .to.emit(this.token, 'DelegateVotesChanged') - .withArgs(this.holder, 1n, 0n); - - const { logs } = await tx.wait(); - const { index } = logs.find(event => event.fragment.name == 'DelegateVotesChanged'); - for (const event of logs.filter(event => event.fragment.name == 'Transfer')) { - expect(event.index).to.lt(index); - } - - this.holderVotes = 0n; - this.recipientVotes = 0n; - }); - - it('receiver delegation', async function () { - await this.votes.connect(this.recipient).delegate(this.recipient); - - const tx = await this.votes.connect(this.holder).transferFrom(this.holder, this.recipient, tokens[0]); - await expect(tx) - .to.emit(this.token, 'Transfer') - .withArgs(this.holder, this.recipient, tokens[0]) - .to.emit(this.token, 'DelegateVotesChanged') - .withArgs(this.recipient, 0n, 1n); - - const { logs } = await tx.wait(); - const { index } = logs.find(event => event.fragment.name == 'DelegateVotesChanged'); - for (const event of logs.filter(event => event.fragment.name == 'Transfer')) { - expect(event.index).to.lt(index); - } - - this.holderVotes = 0n; - this.recipientVotes = 1n; - }); - - it('full delegation', async function () { - await this.votes.connect(this.holder).delegate(this.holder); - await this.votes.connect(this.recipient).delegate(this.recipient); - - const tx = await this.votes.connect(this.holder).transferFrom(this.holder, this.recipient, tokens[0]); - await expect(tx) - .to.emit(this.token, 'Transfer') - .withArgs(this.holder, this.recipient, tokens[0]) - .to.emit(this.token, 'DelegateVotesChanged') - .withArgs(this.holder, 1n, 0n) - .to.emit(this.token, 'DelegateVotesChanged') - .withArgs(this.recipient, 0n, 1n); - - const { logs } = await tx.wait(); - const { index } = logs.find(event => event.fragment.name == 'DelegateVotesChanged'); - for (const event of logs.filter(event => event.fragment.name == 'Transfer')) { - expect(event.index).to.lt(index); - } - - this.holderVotes = 0; - this.recipientVotes = 1n; - }); - - it('returns the same total supply on transfers', async function () { - await this.votes.connect(this.holder).delegate(this.holder); - - const tx = await this.votes.connect(this.holder).transferFrom(this.holder, this.recipient, tokens[0]); - const timepoint = await time.clockFromReceipt[mode](tx); - - await mine(2); - - expect(await this.votes.getPastTotalSupply(timepoint - 1n)).to.equal(1n); - expect(await this.votes.getPastTotalSupply(timepoint + 1n)).to.equal(1n); - - this.holderVotes = 0n; - this.recipientVotes = 0n; - }); - - it('generally returns the voting balance at the appropriate checkpoint', async function () { - await this.votes.$_mint(this.holder, tokens[1]); - await this.votes.$_mint(this.holder, tokens[2]); - await this.votes.$_mint(this.holder, tokens[3]); - - const total = await this.votes.balanceOf(this.holder); - - const t1 = await this.votes.connect(this.holder).delegate(this.other1); - await mine(2); - const t2 = await this.votes.connect(this.holder).transferFrom(this.holder, this.other2, tokens[0]); - await mine(2); - const t3 = await this.votes.connect(this.holder).transferFrom(this.holder, this.other2, tokens[2]); - await mine(2); - const t4 = await this.votes.connect(this.other2).transferFrom(this.other2, this.holder, tokens[2]); - await mine(2); - - t1.timepoint = await time.clockFromReceipt[mode](t1); - t2.timepoint = await time.clockFromReceipt[mode](t2); - t3.timepoint = await time.clockFromReceipt[mode](t3); - t4.timepoint = await time.clockFromReceipt[mode](t4); - - expect(await this.votes.getPastVotes(this.other1, t1.timepoint - 1n)).to.equal(0n); - expect(await this.votes.getPastVotes(this.other1, t1.timepoint)).to.equal(total); - expect(await this.votes.getPastVotes(this.other1, t1.timepoint + 1n)).to.equal(total); - expect(await this.votes.getPastVotes(this.other1, t2.timepoint)).to.equal(3n); - expect(await this.votes.getPastVotes(this.other1, t2.timepoint + 1n)).to.equal(3n); - expect(await this.votes.getPastVotes(this.other1, t3.timepoint)).to.equal(2n); - expect(await this.votes.getPastVotes(this.other1, t3.timepoint + 1n)).to.equal(2n); - expect(await this.votes.getPastVotes(this.other1, t4.timepoint)).to.equal('3'); - expect(await this.votes.getPastVotes(this.other1, t4.timepoint + 1n)).to.equal(3n); - - this.holderVotes = 0n; - this.recipientVotes = 0n; - }); - - afterEach(async function () { - expect(await this.votes.getVotes(this.holder)).to.equal(this.holderVotes); - expect(await this.votes.getVotes(this.recipient)).to.equal(this.recipientVotes); - - // need to advance 2 blocks to see the effect of a transfer on "getPastVotes" - const timepoint = await time.clock[mode](); - await mine(); - expect(await this.votes.getPastVotes(this.holder, timepoint)).to.equal(this.holderVotes); - expect(await this.votes.getPastVotes(this.recipient, timepoint)).to.equal(this.recipientVotes); - }); - }); - }); - } -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Wrapper.test.js b/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Wrapper.test.js deleted file mode 100644 index eeead4c..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Wrapper.test.js +++ /dev/null @@ -1,201 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { shouldBehaveLikeERC721 } = require('../ERC721.behavior'); - -const name = 'Non Fungible Token'; -const symbol = 'NFT'; -const tokenId = 1n; -const otherTokenId = 2n; - -async function fixture() { - const accounts = await ethers.getSigners(); - const [owner, approved, other] = accounts; - - const underlying = await ethers.deployContract('$ERC721', [name, symbol]); - await underlying.$_safeMint(owner, tokenId); - await underlying.$_safeMint(owner, otherTokenId); - const token = await ethers.deployContract('$ERC721Wrapper', [`Wrapped ${name}`, `W${symbol}`, underlying]); - - return { accounts, owner, approved, other, underlying, token }; -} - -describe('ERC721Wrapper', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - 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 underlying', async function () { - expect(await this.token.underlying()).to.equal(this.underlying); - }); - - describe('depositFor', function () { - it('works with token approval', async function () { - await this.underlying.connect(this.owner).approve(this.token, tokenId); - - await expect(this.token.connect(this.owner).depositFor(this.owner, [tokenId])) - .to.emit(this.underlying, 'Transfer') - .withArgs(this.owner, this.token, tokenId) - .to.emit(this.token, 'Transfer') - .withArgs(ethers.ZeroAddress, this.owner, tokenId); - }); - - it('works with approval for all', async function () { - await this.underlying.connect(this.owner).setApprovalForAll(this.token, true); - - await expect(this.token.connect(this.owner).depositFor(this.owner, [tokenId])) - .to.emit(this.underlying, 'Transfer') - .withArgs(this.owner, this.token, tokenId) - .to.emit(this.token, 'Transfer') - .withArgs(ethers.ZeroAddress, this.owner, tokenId); - }); - - it('works sending to another account', async function () { - await this.underlying.connect(this.owner).approve(this.token, tokenId); - - await expect(this.token.connect(this.owner).depositFor(this.other, [tokenId])) - .to.emit(this.underlying, 'Transfer') - .withArgs(this.owner, this.token, tokenId) - .to.emit(this.token, 'Transfer') - .withArgs(ethers.ZeroAddress, this.other, tokenId); - }); - - it('works with multiple tokens', async function () { - await this.underlying.connect(this.owner).approve(this.token, tokenId); - await this.underlying.connect(this.owner).approve(this.token, otherTokenId); - - await expect(this.token.connect(this.owner).depositFor(this.owner, [tokenId, otherTokenId])) - .to.emit(this.underlying, 'Transfer') - .withArgs(this.owner, this.token, tokenId) - .to.emit(this.token, 'Transfer') - .withArgs(ethers.ZeroAddress, this.owner, tokenId) - .to.emit(this.underlying, 'Transfer') - .withArgs(this.owner, this.token, otherTokenId) - .to.emit(this.token, 'Transfer') - .withArgs(ethers.ZeroAddress, this.owner, otherTokenId); - }); - - it('reverts with missing approval', async function () { - await expect(this.token.connect(this.owner).depositFor(this.owner, [tokenId])) - .to.be.revertedWithCustomError(this.token, 'ERC721InsufficientApproval') - .withArgs(this.token, tokenId); - }); - }); - - describe('withdrawTo', function () { - beforeEach(async function () { - await this.underlying.connect(this.owner).approve(this.token, tokenId); - await this.token.connect(this.owner).depositFor(this.owner, [tokenId]); - }); - - it('works for an owner', async function () { - await expect(this.token.connect(this.owner).withdrawTo(this.owner, [tokenId])) - .to.emit(this.underlying, 'Transfer') - .withArgs(this.token, this.owner, tokenId) - .to.emit(this.token, 'Transfer') - .withArgs(this.owner, ethers.ZeroAddress, tokenId); - }); - - it('works for an approved', async function () { - await this.token.connect(this.owner).approve(this.approved, tokenId); - - await expect(this.token.connect(this.approved).withdrawTo(this.owner, [tokenId])) - .to.emit(this.underlying, 'Transfer') - .withArgs(this.token, this.owner, tokenId) - .to.emit(this.token, 'Transfer') - .withArgs(this.owner, ethers.ZeroAddress, tokenId); - }); - - it('works for an approved for all', async function () { - await this.token.connect(this.owner).setApprovalForAll(this.approved, true); - - await expect(this.token.connect(this.approved).withdrawTo(this.owner, [tokenId])) - .to.emit(this.underlying, 'Transfer') - .withArgs(this.token, this.owner, tokenId) - .to.emit(this.token, 'Transfer') - .withArgs(this.owner, ethers.ZeroAddress, tokenId); - }); - - it("doesn't work for a non-owner nor approved", async function () { - await expect(this.token.connect(this.other).withdrawTo(this.owner, [tokenId])) - .to.be.revertedWithCustomError(this.token, 'ERC721InsufficientApproval') - .withArgs(this.other, tokenId); - }); - - it('works with multiple tokens', async function () { - await this.underlying.connect(this.owner).approve(this.token, otherTokenId); - await this.token.connect(this.owner).depositFor(this.owner, [otherTokenId]); - - await expect(this.token.connect(this.owner).withdrawTo(this.owner, [tokenId, otherTokenId])) - .to.emit(this.underlying, 'Transfer') - .withArgs(this.token, this.owner, tokenId) - .to.emit(this.underlying, 'Transfer') - .withArgs(this.token, this.owner, tokenId) - .to.emit(this.token, 'Transfer') - .withArgs(this.owner, ethers.ZeroAddress, tokenId) - .to.emit(this.token, 'Transfer') - .withArgs(this.owner, ethers.ZeroAddress, tokenId); - }); - - it('works to another account', async function () { - await expect(this.token.connect(this.owner).withdrawTo(this.other, [tokenId])) - .to.emit(this.underlying, 'Transfer') - .withArgs(this.token, this.other, tokenId) - .to.emit(this.token, 'Transfer') - .withArgs(this.owner, ethers.ZeroAddress, tokenId); - }); - }); - - describe('onERC721Received', function () { - it('only allows calls from underlying', async function () { - await expect( - this.token.connect(this.other).onERC721Received( - this.owner, - this.token, - tokenId, - this.other.address, // Correct data - ), - ) - .to.be.revertedWithCustomError(this.token, 'ERC721UnsupportedToken') - .withArgs(this.other); - }); - - it('mints a token to from', async function () { - await expect(this.underlying.connect(this.owner).safeTransferFrom(this.owner, this.token, tokenId)) - .to.emit(this.token, 'Transfer') - .withArgs(ethers.ZeroAddress, this.owner, tokenId); - }); - }); - - describe('_recover', function () { - it('works if there is something to recover', async function () { - // Should use `transferFrom` to avoid `onERC721Received` minting - await this.underlying.connect(this.owner).transferFrom(this.owner, this.token, tokenId); - - await expect(this.token.$_recover(this.other, tokenId)) - .to.emit(this.token, 'Transfer') - .withArgs(ethers.ZeroAddress, this.other, tokenId); - }); - - it('reverts if there is nothing to recover', async function () { - const holder = await this.underlying.ownerOf(tokenId); - - await expect(this.token.$_recover(holder, tokenId)) - .to.be.revertedWithCustomError(this.token, 'ERC721IncorrectOwner') - .withArgs(this.token, tokenId, holder); - }); - }); - - describe('ERC712 behavior', function () { - shouldBehaveLikeERC721(); - }); -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC721/utils/ERC721Holder.test.js b/lib/openzeppelin-contracts/test/token/ERC721/utils/ERC721Holder.test.js deleted file mode 100644 index 31dd2fd..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC721/utils/ERC721Holder.test.js +++ /dev/null @@ -1,20 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); - -const name = 'Non Fungible Token'; -const symbol = 'NFT'; -const tokenId = 1n; - -describe('ERC721Holder', function () { - it('receives an ERC721 token', async function () { - const [owner] = await ethers.getSigners(); - - const token = await ethers.deployContract('$ERC721', [name, symbol]); - await token.$_mint(owner, tokenId); - - const receiver = await ethers.deployContract('$ERC721Holder'); - await token.connect(owner).safeTransferFrom(owner, receiver, tokenId); - - expect(await token.ownerOf(tokenId)).to.equal(receiver); - }); -}); diff --git a/lib/openzeppelin-contracts/test/token/ERC721/utils/ERC721Utils.test.js b/lib/openzeppelin-contracts/test/token/ERC721/utils/ERC721Utils.test.js deleted file mode 100644 index 2327d1a..0000000 --- a/lib/openzeppelin-contracts/test/token/ERC721/utils/ERC721Utils.test.js +++ /dev/null @@ -1,94 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { RevertType } = require('../../../helpers/enums'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); - -const tokenId = 1n; - -const RECEIVER_MAGIC_VALUE = '0x150b7a02'; - -const deployReceiver = (revertType, returnValue = RECEIVER_MAGIC_VALUE) => - ethers.deployContract('$ERC721ReceiverMock', [returnValue, revertType]); - -const fixture = async () => { - const [eoa, operator, owner] = await ethers.getSigners(); - const utils = await ethers.deployContract('$ERC721Utils'); - - const receivers = { - correct: await deployReceiver(RevertType.None), - invalid: await deployReceiver(RevertType.None, '0xdeadbeef'), - message: await deployReceiver(RevertType.RevertWithMessage), - empty: await deployReceiver(RevertType.RevertWithoutMessage), - customError: await deployReceiver(RevertType.RevertWithCustomError), - panic: await deployReceiver(RevertType.Panic), - nonReceiver: await ethers.deployContract('CallReceiverMock'), - eoa, - }; - - return { operator, owner, utils, receivers }; -}; - -describe('ERC721Utils', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('onERC721Received', function () { - it('succeeds when called by an EOA', async function () { - await expect(this.utils.$checkOnERC721Received(this.operator, this.owner, this.receivers.eoa, tokenId, '0x')).to - .not.be.reverted; - }); - - it('succeeds when data is passed', async function () { - const data = '0x12345678'; - await expect(this.utils.$checkOnERC721Received(this.operator, this.owner, this.receivers.correct, tokenId, data)) - .to.not.be.reverted; - }); - - it('succeeds when data is empty', async function () { - await expect(this.utils.$checkOnERC721Received(this.operator, this.owner, this.receivers.correct, tokenId, '0x')) - .to.not.be.reverted; - }); - - it('reverts when receiver returns invalid value', async function () { - await expect(this.utils.$checkOnERC721Received(this.operator, this.owner, this.receivers.invalid, tokenId, '0x')) - .to.be.revertedWithCustomError(this.utils, 'ERC721InvalidReceiver') - .withArgs(this.receivers.invalid); - }); - - it('reverts when receiver reverts with message', async function () { - await expect( - this.utils.$checkOnERC721Received(this.operator, this.owner, this.receivers.message, tokenId, '0x'), - ).to.be.revertedWith('ERC721ReceiverMock: reverting'); - }); - - it('reverts when receiver reverts without message', async function () { - await expect(this.utils.$checkOnERC721Received(this.operator, this.owner, this.receivers.empty, tokenId, '0x')) - .to.be.revertedWithCustomError(this.utils, 'ERC721InvalidReceiver') - .withArgs(this.receivers.empty); - }); - - it('reverts when receiver reverts with custom error', async function () { - await expect( - this.utils.$checkOnERC721Received(this.operator, this.owner, this.receivers.customError, tokenId, '0x'), - ) - .to.be.revertedWithCustomError(this.receivers.customError, 'CustomError') - .withArgs(RECEIVER_MAGIC_VALUE); - }); - - it('reverts when receiver panics', async function () { - await expect( - this.utils.$checkOnERC721Received(this.operator, this.owner, this.receivers.panic, tokenId, '0x'), - ).to.be.revertedWithPanic(PANIC_CODES.DIVISION_BY_ZERO); - }); - - it('reverts when receiver does not implement onERC721Received', async function () { - await expect( - this.utils.$checkOnERC721Received(this.operator, this.owner, this.receivers.nonReceiver, tokenId, '0x'), - ) - .to.be.revertedWithCustomError(this.utils, 'ERC721InvalidReceiver') - .withArgs(this.receivers.nonReceiver); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/token/common/ERC2981.behavior.js b/lib/openzeppelin-contracts/test/token/common/ERC2981.behavior.js deleted file mode 100644 index ae6abcc..0000000 --- a/lib/openzeppelin-contracts/test/token/common/ERC2981.behavior.js +++ /dev/null @@ -1,152 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); - -const { shouldSupportInterfaces } = require('../../utils/introspection/SupportsInterface.behavior'); - -function shouldBehaveLikeERC2981() { - const royaltyFraction = 10n; - - shouldSupportInterfaces(['ERC2981']); - - describe('default royalty', function () { - beforeEach(async function () { - await this.token.$_setDefaultRoyalty(this.account1, royaltyFraction); - }); - - it('checks royalty is set', async function () { - expect(await this.token.royaltyInfo(this.tokenId1, this.salePrice)).to.deep.equal([ - this.account1.address, - (this.salePrice * royaltyFraction) / 10_000n, - ]); - }); - - it('updates royalty amount', async function () { - const newFraction = 25n; - - await this.token.$_setDefaultRoyalty(this.account1, newFraction); - - expect(await this.token.royaltyInfo(this.tokenId1, this.salePrice)).to.deep.equal([ - this.account1.address, - (this.salePrice * newFraction) / 10_000n, - ]); - }); - - it('holds same royalty value for different tokens', async function () { - const newFraction = 20n; - - await this.token.$_setDefaultRoyalty(this.account1, newFraction); - - expect(await this.token.royaltyInfo(this.tokenId1, this.salePrice)).to.deep.equal( - await this.token.royaltyInfo(this.tokenId2, this.salePrice), - ); - }); - - it('Remove royalty information', async function () { - const newValue = 0n; - await this.token.$_deleteDefaultRoyalty(); - - expect(await this.token.royaltyInfo(this.tokenId1, this.salePrice)).to.deep.equal([ethers.ZeroAddress, newValue]); - - expect(await this.token.royaltyInfo(this.tokenId2, this.salePrice)).to.deep.equal([ethers.ZeroAddress, newValue]); - }); - - it('reverts if invalid parameters', async function () { - const royaltyDenominator = await this.token.$_feeDenominator(); - - await expect(this.token.$_setDefaultRoyalty(ethers.ZeroAddress, royaltyFraction)) - .to.be.revertedWithCustomError(this.token, 'ERC2981InvalidDefaultRoyaltyReceiver') - .withArgs(ethers.ZeroAddress); - - const anotherRoyaltyFraction = 11000n; - - await expect(this.token.$_setDefaultRoyalty(this.account1, anotherRoyaltyFraction)) - .to.be.revertedWithCustomError(this.token, 'ERC2981InvalidDefaultRoyalty') - .withArgs(anotherRoyaltyFraction, royaltyDenominator); - }); - }); - - describe('token based royalty', function () { - beforeEach(async function () { - await this.token.$_setTokenRoyalty(this.tokenId1, this.account1, royaltyFraction); - }); - - it('updates royalty amount', async function () { - const newFraction = 25n; - - expect(await this.token.royaltyInfo(this.tokenId1, this.salePrice)).to.deep.equal([ - this.account1.address, - (this.salePrice * royaltyFraction) / 10_000n, - ]); - - await this.token.$_setTokenRoyalty(this.tokenId1, this.account1, newFraction); - - expect(await this.token.royaltyInfo(this.tokenId1, this.salePrice)).to.deep.equal([ - this.account1.address, - (this.salePrice * newFraction) / 10_000n, - ]); - }); - - it('holds different values for different tokens', async function () { - const newFraction = 20n; - - await this.token.$_setTokenRoyalty(this.tokenId2, this.account1, newFraction); - - expect(await this.token.royaltyInfo(this.tokenId1, this.salePrice)).to.not.deep.equal( - await this.token.royaltyInfo(this.tokenId2, this.salePrice), - ); - }); - - it('reverts if invalid parameters', async function () { - const royaltyDenominator = await this.token.$_feeDenominator(); - - await expect(this.token.$_setTokenRoyalty(this.tokenId1, ethers.ZeroAddress, royaltyFraction)) - .to.be.revertedWithCustomError(this.token, 'ERC2981InvalidTokenRoyaltyReceiver') - .withArgs(this.tokenId1, ethers.ZeroAddress); - - const anotherRoyaltyFraction = 11000n; - - await expect(this.token.$_setTokenRoyalty(this.tokenId1, this.account1, anotherRoyaltyFraction)) - .to.be.revertedWithCustomError(this.token, 'ERC2981InvalidTokenRoyalty') - .withArgs(this.tokenId1, anotherRoyaltyFraction, royaltyDenominator); - }); - - it('can reset token after setting royalty', async function () { - const newFraction = 30n; - - await this.token.$_setTokenRoyalty(this.tokenId1, this.account2, newFraction); - - // Tokens must have own information - expect(await this.token.royaltyInfo(this.tokenId1, this.salePrice)).to.deep.equal([ - this.account2.address, - (this.salePrice * newFraction) / 10_000n, - ]); - - await this.token.$_setTokenRoyalty(this.tokenId2, this.account1, 0n); - - // Token must not share default information - expect(await this.token.royaltyInfo(this.tokenId2, this.salePrice)).to.deep.equal([this.account1.address, 0n]); - }); - - it('can hold default and token royalty information', async function () { - const newFraction = 30n; - - await this.token.$_setTokenRoyalty(this.tokenId2, this.account2, newFraction); - - // Tokens must not have same values - expect(await this.token.royaltyInfo(this.tokenId1, this.salePrice)).to.not.deep.equal([ - this.account2.address, - (this.salePrice * newFraction) / 10_000n, - ]); - - // Updated token must have new values - expect(await this.token.royaltyInfo(this.tokenId2, this.salePrice)).to.deep.equal([ - this.account2.address, - (this.salePrice * newFraction) / 10_000n, - ]); - }); - }); -} - -module.exports = { - shouldBehaveLikeERC2981, -}; diff --git a/lib/openzeppelin-contracts/test/utils/Address.test.js b/lib/openzeppelin-contracts/test/utils/Address.test.js deleted file mode 100644 index 2177539..0000000 --- a/lib/openzeppelin-contracts/test/utils/Address.test.js +++ /dev/null @@ -1,280 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); - -const coder = ethers.AbiCoder.defaultAbiCoder(); - -async function fixture() { - const [recipient, other] = await ethers.getSigners(); - - const mock = await ethers.deployContract('$Address'); - const target = await ethers.deployContract('CallReceiverMock'); - const targetEther = await ethers.deployContract('EtherReceiverMock'); - - return { recipient, other, mock, target, targetEther }; -} - -describe('Address', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('sendValue', function () { - describe('when sender contract has no funds', function () { - it('sends 0 wei', async function () { - await expect(this.mock.$sendValue(this.other, 0n)).to.changeEtherBalance(this.recipient, 0n); - }); - - it('reverts when sending non-zero amounts', async function () { - await expect(this.mock.$sendValue(this.other, 1n)) - .to.be.revertedWithCustomError(this.mock, 'InsufficientBalance') - .withArgs(0n, 1n); - }); - }); - - describe('when sender contract has funds', function () { - const funds = ethers.parseEther('1'); - - beforeEach(async function () { - await this.other.sendTransaction({ to: this.mock, value: funds }); - }); - - describe('with EOA recipient', function () { - it('sends 0 wei', async function () { - await expect(this.mock.$sendValue(this.recipient, 0n)).to.changeEtherBalance(this.recipient, 0n); - }); - - it('sends non-zero amounts', async function () { - await expect(this.mock.$sendValue(this.recipient, funds - 1n)).to.changeEtherBalance( - this.recipient, - funds - 1n, - ); - }); - - it('sends the whole balance', async function () { - await expect(this.mock.$sendValue(this.recipient, funds)).to.changeEtherBalance(this.recipient, funds); - expect(await ethers.provider.getBalance(this.mock)).to.equal(0n); - }); - - it('reverts when sending more than the balance', async function () { - await expect(this.mock.$sendValue(this.recipient, funds + 1n)) - .to.be.revertedWithCustomError(this.mock, 'InsufficientBalance') - .withArgs(funds, funds + 1n); - }); - }); - - describe('with contract recipient', function () { - it('sends funds', async function () { - await this.targetEther.setAcceptEther(true); - await expect(this.mock.$sendValue(this.targetEther, funds)).to.changeEtherBalance(this.targetEther, funds); - }); - - it('reverts on recipient revert', async function () { - await this.targetEther.setAcceptEther(false); - await expect(this.mock.$sendValue(this.targetEther, funds)).to.be.revertedWithCustomError( - this.mock, - 'FailedCall', - ); - }); - }); - }); - }); - - describe('functionCall', function () { - describe('with valid contract receiver', function () { - it('calls the requested function', async function () { - const call = this.target.interface.encodeFunctionData('mockFunction'); - - await expect(this.mock.$functionCall(this.target, call)) - .to.emit(this.target, 'MockFunctionCalled') - .to.emit(this.mock, 'return$functionCall') - .withArgs(coder.encode(['string'], ['0x1234'])); - }); - - it('calls the requested empty return function', async function () { - const call = this.target.interface.encodeFunctionData('mockFunctionEmptyReturn'); - - await expect(this.mock.$functionCall(this.target, call)).to.emit(this.target, 'MockFunctionCalled'); - }); - - it('reverts when the called function reverts with no reason', async function () { - const call = this.target.interface.encodeFunctionData('mockFunctionRevertsNoReason'); - - await expect(this.mock.$functionCall(this.target, call)).to.be.revertedWithCustomError(this.mock, 'FailedCall'); - }); - - it('reverts when the called function reverts, bubbling up the revert reason', async function () { - const call = this.target.interface.encodeFunctionData('mockFunctionRevertsReason'); - - await expect(this.mock.$functionCall(this.target, call)).to.be.revertedWith('CallReceiverMock: reverting'); - }); - - it('reverts when the called function runs out of gas', async function () { - const call = this.target.interface.encodeFunctionData('mockFunctionOutOfGas'); - - await expect(this.mock.$functionCall(this.target, call, { gasLimit: 120_000n })).to.be.revertedWithCustomError( - this.mock, - 'FailedCall', - ); - }); - - it('reverts when the called function throws', async function () { - const call = this.target.interface.encodeFunctionData('mockFunctionThrows'); - - await expect(this.mock.$functionCall(this.target, call)).to.be.revertedWithPanic(PANIC_CODES.ASSERTION_ERROR); - }); - - it('reverts when function does not exist', async function () { - const interface = new ethers.Interface(['function mockFunctionDoesNotExist()']); - const call = interface.encodeFunctionData('mockFunctionDoesNotExist'); - - await expect(this.mock.$functionCall(this.target, call)).to.be.revertedWithCustomError(this.mock, 'FailedCall'); - }); - }); - - describe('with non-contract receiver', function () { - it('reverts when address is not a contract', async function () { - const call = this.target.interface.encodeFunctionData('mockFunction'); - - await expect(this.mock.$functionCall(this.recipient, call)) - .to.be.revertedWithCustomError(this.mock, 'AddressEmptyCode') - .withArgs(this.recipient); - }); - }); - }); - - describe('functionCallWithValue', function () { - describe('with zero value', function () { - it('calls the requested function', async function () { - const call = this.target.interface.encodeFunctionData('mockFunction'); - - await expect(this.mock.$functionCallWithValue(this.target, call, 0n)) - .to.emit(this.target, 'MockFunctionCalled') - .to.emit(this.mock, 'return$functionCallWithValue') - .withArgs(coder.encode(['string'], ['0x1234'])); - }); - }); - - describe('with non-zero value', function () { - const value = ethers.parseEther('1.2'); - - it('reverts if insufficient sender balance', async function () { - const call = this.target.interface.encodeFunctionData('mockFunction'); - - await expect(this.mock.$functionCallWithValue(this.target, call, value)) - .to.be.revertedWithCustomError(this.mock, 'InsufficientBalance') - .withArgs(0n, value); - }); - - it('calls the requested function with existing value', async function () { - await this.other.sendTransaction({ to: this.mock, value }); - - const call = this.target.interface.encodeFunctionData('mockFunction'); - const tx = await this.mock.$functionCallWithValue(this.target, call, value); - - await expect(tx).to.changeEtherBalance(this.target, value); - - await expect(tx) - .to.emit(this.target, 'MockFunctionCalled') - .to.emit(this.mock, 'return$functionCallWithValue') - .withArgs(coder.encode(['string'], ['0x1234'])); - }); - - it('calls the requested function with transaction funds', async function () { - expect(await ethers.provider.getBalance(this.mock)).to.equal(0n); - - const call = this.target.interface.encodeFunctionData('mockFunction'); - const tx = await this.mock.connect(this.other).$functionCallWithValue(this.target, call, value, { value }); - - await expect(tx).to.changeEtherBalance(this.target, value); - await expect(tx) - .to.emit(this.target, 'MockFunctionCalled') - .to.emit(this.mock, 'return$functionCallWithValue') - .withArgs(coder.encode(['string'], ['0x1234'])); - }); - - it('reverts when calling non-payable functions', async function () { - await this.other.sendTransaction({ to: this.mock, value }); - - const call = this.target.interface.encodeFunctionData('mockFunctionNonPayable'); - - await expect(this.mock.$functionCallWithValue(this.target, call, value)).to.be.revertedWithCustomError( - this.mock, - 'FailedCall', - ); - }); - }); - }); - - describe('functionStaticCall', function () { - it('calls the requested function', async function () { - const call = this.target.interface.encodeFunctionData('mockStaticFunction'); - - expect(await this.mock.$functionStaticCall(this.target, call)).to.equal(coder.encode(['string'], ['0x1234'])); - }); - - it('reverts on a non-static function', async function () { - const call = this.target.interface.encodeFunctionData('mockFunction'); - - await expect(this.mock.$functionStaticCall(this.target, call)).to.be.revertedWithCustomError( - this.mock, - 'FailedCall', - ); - }); - - it('bubbles up revert reason', async function () { - const call = this.target.interface.encodeFunctionData('mockFunctionRevertsReason'); - - await expect(this.mock.$functionStaticCall(this.target, call)).to.be.revertedWith('CallReceiverMock: reverting'); - }); - - it('reverts when address is not a contract', async function () { - const call = this.target.interface.encodeFunctionData('mockFunction'); - - await expect(this.mock.$functionStaticCall(this.recipient, call)) - .to.be.revertedWithCustomError(this.mock, 'AddressEmptyCode') - .withArgs(this.recipient); - }); - }); - - describe('functionDelegateCall', function () { - it('delegate calls the requested function', async function () { - const slot = ethers.hexlify(ethers.randomBytes(32)); - const value = ethers.hexlify(ethers.randomBytes(32)); - - const call = this.target.interface.encodeFunctionData('mockFunctionWritesStorage', [slot, value]); - - expect(await ethers.provider.getStorage(this.mock, slot)).to.equal(ethers.ZeroHash); - - await expect(await this.mock.$functionDelegateCall(this.target, call)) - .to.emit(this.mock, 'return$functionDelegateCall') - .withArgs(coder.encode(['string'], ['0x1234'])); - - expect(await ethers.provider.getStorage(this.mock, slot)).to.equal(value); - }); - - it('bubbles up revert reason', async function () { - const call = this.target.interface.encodeFunctionData('mockFunctionRevertsReason'); - - await expect(this.mock.$functionDelegateCall(this.target, call)).to.be.revertedWith( - 'CallReceiverMock: reverting', - ); - }); - - it('reverts when address is not a contract', async function () { - const call = this.target.interface.encodeFunctionData('mockFunction'); - - await expect(this.mock.$functionDelegateCall(this.recipient, call)) - .to.be.revertedWithCustomError(this.mock, 'AddressEmptyCode') - .withArgs(this.recipient); - }); - }); - - describe('verifyCallResult', function () { - it('returns returndata on success', async function () { - const returndata = '0x123abc'; - expect(await this.mock.$verifyCallResult(true, returndata)).to.equal(returndata); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/utils/Arrays.t.sol b/lib/openzeppelin-contracts/test/utils/Arrays.t.sol deleted file mode 100644 index 09c7b66..0000000 --- a/lib/openzeppelin-contracts/test/utils/Arrays.t.sol +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {Test} from "forge-std/Test.sol"; -import {SymTest} from "halmos-cheatcodes/SymTest.sol"; -import {Arrays} from "@openzeppelin/contracts/utils/Arrays.sol"; - -contract ArraysTest is Test, SymTest { - function testSort(uint256[] memory values) public { - Arrays.sort(values); - _assertSort(values); - } - - function symbolicSort() public { - uint256[] memory values = new uint256[](3); - for (uint256 i = 0; i < 3; i++) { - values[i] = svm.createUint256("arrayElement"); - } - Arrays.sort(values); - _assertSort(values); - } - - /// Asserts - - function _assertSort(uint256[] memory values) internal { - for (uint256 i = 1; i < values.length; ++i) { - assertLe(values[i - 1], values[i]); - } - } -} diff --git a/lib/openzeppelin-contracts/test/utils/Arrays.test.js b/lib/openzeppelin-contracts/test/utils/Arrays.test.js deleted file mode 100644 index bcb3858..0000000 --- a/lib/openzeppelin-contracts/test/utils/Arrays.test.js +++ /dev/null @@ -1,223 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { generators } = require('../helpers/random'); -const { capitalize } = require('../../scripts/helpers'); -const { TYPES } = require('../../scripts/generate/templates/Arrays.opts'); - -// See https://en.cppreference.com/w/cpp/algorithm/lower_bound -const lowerBound = (array, value) => { - const i = array.findIndex(element => value <= element); - return i == -1 ? array.length : i; -}; - -// See https://en.cppreference.com/w/cpp/algorithm/upper_bound -const upperBound = (array, value) => { - const i = array.findIndex(element => value < element); - return i == -1 ? array.length : i; -}; - -const bigintSign = x => (x > 0n ? 1 : x < 0n ? -1 : 0); -const comparator = (a, b) => bigintSign(ethers.toBigInt(a) - ethers.toBigInt(b)); -const hasDuplicates = array => array.some((v, i) => array.indexOf(v) != i); - -describe('Arrays', function () { - const fixture = async () => { - return { mock: await ethers.deployContract('$Arrays') }; - }; - - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('search', function () { - for (const [title, { array, tests }] of Object.entries({ - 'Even number of elements': { - array: [11n, 12n, 13n, 14n, 15n, 16n, 17n, 18n, 19n, 20n], - tests: { - 'basic case': 16n, - 'first element': 11n, - 'last element': 20n, - 'searched value is over the upper boundary': 32n, - 'searched value is under the lower boundary': 2n, - }, - }, - 'Odd number of elements': { - array: [11n, 12n, 13n, 14n, 15n, 16n, 17n, 18n, 19n, 20n, 21n], - tests: { - 'basic case': 16n, - 'first element': 11n, - 'last element': 21n, - 'searched value is over the upper boundary': 32n, - 'searched value is under the lower boundary': 2n, - }, - }, - 'Array with gap': { - array: [11n, 12n, 13n, 14n, 15n, 20n, 21n, 22n, 23n, 24n], - tests: { - 'search value in gap': 17n, - }, - }, - 'Array with duplicated elements': { - array: [0n, 10n, 10n, 10n, 10n, 10n, 10n, 10n, 20n], - tests: { - 'search value is duplicated': 10n, - }, - }, - 'Array with duplicated first element': { - array: [10n, 10n, 10n, 10n, 10n, 10n, 10n, 20n], - tests: { - 'search value is duplicated first element': 10n, - }, - }, - 'Array with duplicated last element': { - array: [0n, 10n, 10n, 10n, 10n, 10n, 10n, 10n], - tests: { - 'search value is duplicated last element': 10n, - }, - }, - 'Empty array': { - array: [], - tests: { - 'always returns 0 for empty array': 10n, - }, - }, - })) { - describe(title, function () { - const fixture = async () => { - return { instance: await ethers.deployContract('Uint256ArraysMock', [array]) }; - }; - - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - for (const [name, input] of Object.entries(tests)) { - describe(name, function () { - it('[deprecated] findUpperBound', async function () { - // findUpperBound does not support duplicated - if (hasDuplicates(array)) { - expect(await this.instance.findUpperBound(input)).to.equal(upperBound(array, input) - 1); - } else { - expect(await this.instance.findUpperBound(input)).to.equal(lowerBound(array, input)); - } - }); - - it('lowerBound', async function () { - expect(await this.instance.lowerBound(input)).to.equal(lowerBound(array, input)); - expect(await this.instance.lowerBoundMemory(array, input)).to.equal(lowerBound(array, input)); - }); - - it('upperBound', async function () { - expect(await this.instance.upperBound(input)).to.equal(upperBound(array, input)); - expect(await this.instance.upperBoundMemory(array, input)).to.equal(upperBound(array, input)); - }); - }); - } - }); - } - }); - - for (const type of TYPES) { - const elements = Array.from({ length: 10 }, generators[type]); - - describe(type, function () { - const fixture = async () => { - return { instance: await ethers.deployContract(`${capitalize(type)}ArraysMock`, [elements]) }; - }; - - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('sort', function () { - for (const length of [0, 1, 2, 8, 32, 128]) { - describe(`${type}[] of length ${length}`, function () { - beforeEach(async function () { - this.array = Array.from({ length }, generators[type]); - }); - - afterEach(async function () { - const expected = Array.from(this.array).sort(comparator); - const reversed = Array.from(expected).reverse(); - expect(await this.instance.sort(this.array)).to.deep.equal(expected); - expect(await this.instance.sortReverse(this.array)).to.deep.equal(reversed); - }); - - it('sort array', async function () { - // nothing to do here, beforeEach and afterEach already take care of everything. - }); - - if (length > 1) { - it('sort array for identical elements', async function () { - // duplicate the first value to all elements - this.array.fill(this.array.at(0)); - }); - - it('sort already sorted array', async function () { - // pre-sort the elements - this.array.sort(comparator); - }); - - it('sort reversed array', async function () { - // pre-sort in reverse order - this.array.sort(comparator).reverse(); - }); - - it('sort almost sorted array', async function () { - // pre-sort + rotate (move the last element to the front) for an almost sorted effect - this.array.sort(comparator); - this.array.unshift(this.array.pop()); - }); - } - }); - } - }); - - describe('unsafeAccess', function () { - describe('storage', function () { - for (const i in elements) { - it(`unsafeAccess within bounds #${i}`, async function () { - expect(await this.instance.unsafeAccess(i)).to.equal(elements[i]); - }); - } - - it('unsafeAccess outside bounds', async function () { - await expect(this.instance.unsafeAccess(elements.length)).to.not.be.rejected; - }); - - it('unsafeSetLength changes the length or the array', async function () { - const newLength = generators.uint256(); - - expect(await this.instance.length()).to.equal(elements.length); - await expect(this.instance.unsafeSetLength(newLength)).to.not.be.rejected; - expect(await this.instance.length()).to.equal(newLength); - }); - }); - - describe('memory', function () { - const fragment = `$unsafeMemoryAccess(${type}[] arr, uint256 pos)`; - - for (const i in elements) { - it(`unsafeMemoryAccess within bounds #${i}`, async function () { - expect(await this.mock[fragment](elements, i)).to.equal(elements[i]); - }); - } - - it('unsafeMemoryAccess outside bounds', async function () { - await expect(this.mock[fragment](elements, elements.length)).to.not.be.rejected; - }); - - it('unsafeMemoryAccess loop around', async function () { - for (let i = 251n; i < 256n; ++i) { - expect(await this.mock[fragment](elements, 2n ** i - 1n)).to.equal(BigInt(elements.length)); - expect(await this.mock[fragment](elements, 2n ** i + 0n)).to.equal(elements[0]); - expect(await this.mock[fragment](elements, 2n ** i + 1n)).to.equal(elements[1]); - } - }); - }); - }); - }); - } -}); diff --git a/lib/openzeppelin-contracts/test/utils/Base64.t.sol b/lib/openzeppelin-contracts/test/utils/Base64.t.sol deleted file mode 100644 index 021ae03..0000000 --- a/lib/openzeppelin-contracts/test/utils/Base64.t.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {Test} from "forge-std/Test.sol"; -import {Base64} from "@openzeppelin/contracts/utils/Base64.sol"; - -contract Base64Test is Test { - function testEncode(bytes memory input) external { - assertEq(Base64.encode(input), vm.toBase64(input)); - } - - function testEncodeURL(bytes memory input) external { - assertEq(Base64.encodeURL(input), _removePadding(vm.toBase64URL(input))); - } - - function _removePadding(string memory inputStr) internal pure returns (string memory) { - bytes memory input = bytes(inputStr); - bytes memory output; - - for (uint256 i = 0; i < input.length; ++i) { - if (input[input.length - i - 1] != 0x3d) { - output = new bytes(input.length - i); - break; - } - } - - for (uint256 i = 0; i < output.length; ++i) { - output[i] = input[i]; - } - - return string(output); - } -} diff --git a/lib/openzeppelin-contracts/test/utils/Base64.test.js b/lib/openzeppelin-contracts/test/utils/Base64.test.js deleted file mode 100644 index 5c42746..0000000 --- a/lib/openzeppelin-contracts/test/utils/Base64.test.js +++ /dev/null @@ -1,59 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -// Replace "+/" with "-_" in the char table, and remove the padding -// see https://datatracker.ietf.org/doc/html/rfc4648#section-5 -const base64toBase64Url = str => str.replaceAll('+', '-').replaceAll('/', '_').replaceAll('=', ''); - -async function fixture() { - const mock = await ethers.deployContract('$Base64'); - return { mock }; -} - -describe('Strings', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('base64', function () { - for (const { title, input, expected } of [ - { title: 'converts to base64 encoded string with double padding', input: 'test', expected: 'dGVzdA==' }, - { title: 'converts to base64 encoded string with single padding', input: 'test1', expected: 'dGVzdDE=' }, - { title: 'converts to base64 encoded string without padding', input: 'test12', expected: 'dGVzdDEy' }, - { title: 'converts to base64 encoded string (/ case)', input: 'où', expected: 'b/k=' }, - { title: 'converts to base64 encoded string (+ case)', input: 'zs~1t8', expected: 'enN+MXQ4' }, - { title: 'empty bytes', input: '', expected: '' }, - ]) - it(title, async function () { - const buffer = Buffer.from(input, 'ascii'); - expect(await this.mock.$encode(buffer)).to.equal(ethers.encodeBase64(buffer)); - expect(await this.mock.$encode(buffer)).to.equal(expected); - }); - }); - - describe('base64url', function () { - for (const { title, input, expected } of [ - { title: 'converts to base64url encoded string with double padding', input: 'test', expected: 'dGVzdA' }, - { title: 'converts to base64url encoded string with single padding', input: 'test1', expected: 'dGVzdDE' }, - { title: 'converts to base64url encoded string without padding', input: 'test12', expected: 'dGVzdDEy' }, - { title: 'converts to base64url encoded string (_ case)', input: 'où', expected: 'b_k' }, - { title: 'converts to base64url encoded string (- case)', input: 'zs~1t8', expected: 'enN-MXQ4' }, - { title: 'empty bytes', input: '', expected: '' }, - ]) - it(title, async function () { - const buffer = Buffer.from(input, 'ascii'); - expect(await this.mock.$encodeURL(buffer)).to.equal(base64toBase64Url(ethers.encodeBase64(buffer))); - expect(await this.mock.$encodeURL(buffer)).to.equal(expected); - }); - }); - - it('Encode reads beyond the input buffer into dirty memory', async function () { - const mock = await ethers.deployContract('Base64Dirty'); - const buffer32 = ethers.id('example'); - const buffer31 = buffer32.slice(0, -2); - - expect(await mock.encode(buffer31)).to.equal(ethers.encodeBase64(buffer31)); - expect(await mock.encode(buffer32)).to.equal(ethers.encodeBase64(buffer32)); - }); -}); diff --git a/lib/openzeppelin-contracts/test/utils/Context.behavior.js b/lib/openzeppelin-contracts/test/utils/Context.behavior.js deleted file mode 100644 index adb140f..0000000 --- a/lib/openzeppelin-contracts/test/utils/Context.behavior.js +++ /dev/null @@ -1,48 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -async function fixture() { - return { contextHelper: await ethers.deployContract('ContextMockCaller', []) }; -} -function shouldBehaveLikeRegularContext() { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('msgSender', function () { - it('returns the transaction sender when called from an EOA', async function () { - await expect(this.context.connect(this.sender).msgSender()).to.emit(this.context, 'Sender').withArgs(this.sender); - }); - - it('returns the transaction sender when called from another contract', async function () { - await expect(this.contextHelper.connect(this.sender).callSender(this.context)) - .to.emit(this.context, 'Sender') - .withArgs(this.contextHelper); - }); - }); - - describe('msgData', function () { - const args = [42n, 'OpenZeppelin']; - - it('returns the transaction data when called from an EOA', async function () { - const callData = this.context.interface.encodeFunctionData('msgData', args); - - await expect(this.context.msgData(...args)) - .to.emit(this.context, 'Data') - .withArgs(callData, ...args); - }); - - it('returns the transaction sender when from another contract', async function () { - const callData = this.context.interface.encodeFunctionData('msgData', args); - - await expect(this.contextHelper.callData(this.context, ...args)) - .to.emit(this.context, 'Data') - .withArgs(callData, ...args); - }); - }); -} - -module.exports = { - shouldBehaveLikeRegularContext, -}; diff --git a/lib/openzeppelin-contracts/test/utils/Context.test.js b/lib/openzeppelin-contracts/test/utils/Context.test.js deleted file mode 100644 index b766729..0000000 --- a/lib/openzeppelin-contracts/test/utils/Context.test.js +++ /dev/null @@ -1,18 +0,0 @@ -const { ethers } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { shouldBehaveLikeRegularContext } = require('./Context.behavior'); - -async function fixture() { - const [sender] = await ethers.getSigners(); - const context = await ethers.deployContract('ContextMock', []); - return { sender, context }; -} - -describe('Context', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - shouldBehaveLikeRegularContext(); -}); diff --git a/lib/openzeppelin-contracts/test/utils/Create2.t.sol b/lib/openzeppelin-contracts/test/utils/Create2.t.sol deleted file mode 100644 index e8e2269..0000000 --- a/lib/openzeppelin-contracts/test/utils/Create2.t.sol +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {Test} from "forge-std/Test.sol"; -import {Create2} from "@openzeppelin/contracts/utils/Create2.sol"; - -contract Create2Test is Test { - function testSymbolicComputeAddressSpillage(bytes32 salt, bytes32 bytecodeHash, address deployer) public { - address predicted = Create2.computeAddress(salt, bytecodeHash, deployer); - bytes32 spillage; - /// @solidity memory-safe-assembly - assembly { - spillage := and(predicted, 0xffffffffffffffffffffffff0000000000000000000000000000000000000000) - } - assertEq(spillage, bytes32(0)); - } -} diff --git a/lib/openzeppelin-contracts/test/utils/Create2.test.js b/lib/openzeppelin-contracts/test/utils/Create2.test.js deleted file mode 100644 index 152fdbd..0000000 --- a/lib/openzeppelin-contracts/test/utils/Create2.test.js +++ /dev/null @@ -1,190 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); - -const { RevertType } = require('../helpers/enums'); - -async function fixture() { - const [deployer, other] = await ethers.getSigners(); - - const factory = await ethers.deployContract('$Create2'); - - // Bytecode for deploying a contract that includes a constructor. - // We use a vesting wallet, with 3 constructor arguments. - const constructorByteCode = await ethers - .getContractFactory('VestingWallet') - .then(({ bytecode, interface }) => ethers.concat([bytecode, interface.encodeDeploy([other.address, 0n, 0n])])); - - // Bytecode for deploying a contract that has no constructor log. - // Here we use the Create2 helper factory. - const constructorLessBytecode = await ethers - .getContractFactory('$Create2') - .then(({ bytecode, interface }) => ethers.concat([bytecode, interface.encodeDeploy([])])); - - const mockFactory = await ethers.getContractFactory('ConstructorMock'); - - return { deployer, other, factory, constructorByteCode, constructorLessBytecode, mockFactory }; -} - -describe('Create2', function () { - const salt = 'salt message'; - const saltHex = ethers.id(salt); - - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('computeAddress', function () { - it('computes the correct contract address', async function () { - const onChainComputed = await this.factory.$computeAddress(saltHex, ethers.keccak256(this.constructorByteCode)); - const offChainComputed = ethers.getCreate2Address( - this.factory.target, - saltHex, - ethers.keccak256(this.constructorByteCode), - ); - expect(onChainComputed).to.equal(offChainComputed); - }); - - it('computes the correct contract address with deployer', async function () { - const onChainComputed = await this.factory.$computeAddress( - saltHex, - ethers.keccak256(this.constructorByteCode), - ethers.Typed.address(this.deployer), - ); - const offChainComputed = ethers.getCreate2Address( - this.deployer.address, - saltHex, - ethers.keccak256(this.constructorByteCode), - ); - expect(onChainComputed).to.equal(offChainComputed); - }); - }); - - describe('deploy', function () { - it('deploys a contract without constructor', async function () { - const offChainComputed = ethers.getCreate2Address( - this.factory.target, - saltHex, - ethers.keccak256(this.constructorLessBytecode), - ); - - await expect(this.factory.$deploy(0n, saltHex, this.constructorLessBytecode)) - .to.emit(this.factory, 'return$deploy') - .withArgs(offChainComputed); - - expect(this.constructorLessBytecode).to.include((await ethers.provider.getCode(offChainComputed)).slice(2)); - }); - - it('deploys a contract with constructor arguments', async function () { - const offChainComputed = ethers.getCreate2Address( - this.factory.target, - saltHex, - ethers.keccak256(this.constructorByteCode), - ); - - await expect(this.factory.$deploy(0n, saltHex, this.constructorByteCode)) - .to.emit(this.factory, 'return$deploy') - .withArgs(offChainComputed); - - const instance = await ethers.getContractAt('VestingWallet', offChainComputed); - - expect(await instance.owner()).to.equal(this.other); - }); - - it('deploys a contract with funds deposited in the factory', async function () { - const value = 10n; - - await this.deployer.sendTransaction({ to: this.factory, value }); - - const offChainComputed = ethers.getCreate2Address( - this.factory.target, - saltHex, - ethers.keccak256(this.constructorByteCode), - ); - - expect(await ethers.provider.getBalance(this.factory)).to.equal(value); - expect(await ethers.provider.getBalance(offChainComputed)).to.equal(0n); - - await expect(this.factory.$deploy(value, saltHex, this.constructorByteCode)) - .to.emit(this.factory, 'return$deploy') - .withArgs(offChainComputed); - - expect(await ethers.provider.getBalance(this.factory)).to.equal(0n); - expect(await ethers.provider.getBalance(offChainComputed)).to.equal(value); - }); - - it('fails deploying a contract in an existent address', async function () { - await expect(this.factory.$deploy(0n, saltHex, this.constructorByteCode)).to.emit(this.factory, 'return$deploy'); - - await expect(this.factory.$deploy(0n, saltHex, this.constructorByteCode)).to.be.revertedWithCustomError( - this.factory, - 'FailedDeployment', - ); - }); - - it('fails deploying a contract if the bytecode length is zero', async function () { - await expect(this.factory.$deploy(0n, saltHex, '0x')).to.be.revertedWithCustomError( - this.factory, - 'Create2EmptyBytecode', - ); - }); - - it('fails deploying a contract if factory contract does not have sufficient balance', async function () { - await expect(this.factory.$deploy(1n, saltHex, this.constructorByteCode)) - .to.be.revertedWithCustomError(this.factory, 'InsufficientBalance') - .withArgs(0n, 1n); - }); - - describe('reverts error thrown during contract creation', function () { - it('bubbles up without message', async function () { - await expect( - this.factory.$deploy( - 0n, - saltHex, - ethers.concat([ - this.mockFactory.bytecode, - this.mockFactory.interface.encodeDeploy([RevertType.RevertWithoutMessage]), - ]), - ), - ).to.be.revertedWithCustomError(this.factory, 'FailedDeployment'); - }); - - it('bubbles up message', async function () { - await expect( - this.factory.$deploy( - 0n, - saltHex, - ethers.concat([ - this.mockFactory.bytecode, - this.mockFactory.interface.encodeDeploy([RevertType.RevertWithMessage]), - ]), - ), - ).to.be.revertedWith('ConstructorMock: reverting'); - }); - - it('bubbles up custom error', async function () { - await expect( - this.factory.$deploy( - 0n, - saltHex, - ethers.concat([ - this.mockFactory.bytecode, - this.mockFactory.interface.encodeDeploy([RevertType.RevertWithCustomError]), - ]), - ), - ).to.be.revertedWithCustomError({ interface: this.mockFactory.interface }, 'CustomError'); - }); - - it('bubbles up panic', async function () { - await expect( - this.factory.$deploy( - 0n, - saltHex, - ethers.concat([this.mockFactory.bytecode, this.mockFactory.interface.encodeDeploy([RevertType.Panic])]), - ), - ).to.be.revertedWithPanic(PANIC_CODES.DIVISION_BY_ZERO); - }); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/utils/Multicall.test.js b/lib/openzeppelin-contracts/test/utils/Multicall.test.js deleted file mode 100644 index 9c84e44..0000000 --- a/lib/openzeppelin-contracts/test/utils/Multicall.test.js +++ /dev/null @@ -1,72 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -async function fixture() { - const [holder, alice, bruce] = await ethers.getSigners(); - - const amount = 12_000n; - const helper = await ethers.deployContract('MulticallHelper'); - const mock = await ethers.deployContract('$ERC20MulticallMock', ['name', 'symbol']); - await mock.$_mint(holder, amount); - - return { holder, alice, bruce, amount, mock, helper }; -} - -describe('Multicall', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - it('batches function calls', async function () { - expect(await this.mock.balanceOf(this.alice)).to.equal(0n); - expect(await this.mock.balanceOf(this.bruce)).to.equal(0n); - - await expect( - this.mock.multicall([ - this.mock.interface.encodeFunctionData('transfer', [this.alice.address, this.amount / 2n]), - this.mock.interface.encodeFunctionData('transfer', [this.bruce.address, this.amount / 3n]), - ]), - ) - .to.emit(this.mock, 'Transfer') - .withArgs(this.holder, this.alice, this.amount / 2n) - .to.emit(this.mock, 'Transfer') - .withArgs(this.holder, this.bruce, this.amount / 3n); - - expect(await this.mock.balanceOf(this.alice)).to.equal(this.amount / 2n); - expect(await this.mock.balanceOf(this.bruce)).to.equal(this.amount / 3n); - }); - - it('returns an array with the result of each call', async function () { - await this.mock.transfer(this.helper, this.amount); - expect(await this.mock.balanceOf(this.helper)).to.equal(this.amount); - - await this.helper.checkReturnValues(this.mock, [this.alice, this.bruce], [this.amount / 2n, this.amount / 3n]); - }); - - it('reverts previous calls', async function () { - expect(await this.mock.balanceOf(this.alice)).to.equal(0n); - - await expect( - this.mock.multicall([ - this.mock.interface.encodeFunctionData('transfer', [this.alice.address, this.amount]), - this.mock.interface.encodeFunctionData('transfer', [this.bruce.address, this.amount]), - ]), - ) - .to.be.revertedWithCustomError(this.mock, 'ERC20InsufficientBalance') - .withArgs(this.holder, 0, this.amount); - - expect(await this.mock.balanceOf(this.alice)).to.equal(0n); - }); - - it('bubbles up revert reasons', async function () { - await expect( - this.mock.multicall([ - this.mock.interface.encodeFunctionData('transfer', [this.alice.address, this.amount]), - this.mock.interface.encodeFunctionData('transfer', [this.bruce.address, this.amount]), - ]), - ) - .to.be.revertedWithCustomError(this.mock, 'ERC20InsufficientBalance') - .withArgs(this.holder, 0, this.amount); - }); -}); diff --git a/lib/openzeppelin-contracts/test/utils/Nonces.test.js b/lib/openzeppelin-contracts/test/utils/Nonces.test.js deleted file mode 100644 index 2cb4798..0000000 --- a/lib/openzeppelin-contracts/test/utils/Nonces.test.js +++ /dev/null @@ -1,75 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -async function fixture() { - const [sender, other] = await ethers.getSigners(); - - const mock = await ethers.deployContract('$Nonces'); - - return { sender, other, mock }; -} - -describe('Nonces', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - it('gets a nonce', async function () { - expect(await this.mock.nonces(this.sender)).to.equal(0n); - }); - - describe('_useNonce', function () { - it('increments a nonce', async function () { - expect(await this.mock.nonces(this.sender)).to.equal(0n); - - await expect(await this.mock.$_useNonce(this.sender)) - .to.emit(this.mock, 'return$_useNonce') - .withArgs(0n); - - expect(await this.mock.nonces(this.sender)).to.equal(1n); - }); - - it("increments only sender's nonce", async function () { - expect(await this.mock.nonces(this.sender)).to.equal(0n); - expect(await this.mock.nonces(this.other)).to.equal(0n); - - await this.mock.$_useNonce(this.sender); - - expect(await this.mock.nonces(this.sender)).to.equal(1n); - expect(await this.mock.nonces(this.other)).to.equal(0n); - }); - }); - - describe('_useCheckedNonce', function () { - it('increments a nonce', async function () { - const currentNonce = await this.mock.nonces(this.sender); - - expect(currentNonce).to.equal(0n); - - await this.mock.$_useCheckedNonce(this.sender, currentNonce); - - expect(await this.mock.nonces(this.sender)).to.equal(1n); - }); - - it("increments only sender's nonce", async function () { - const currentNonce = await this.mock.nonces(this.sender); - - expect(currentNonce).to.equal(0n); - expect(await this.mock.nonces(this.other)).to.equal(0n); - - await this.mock.$_useCheckedNonce(this.sender, currentNonce); - - expect(await this.mock.nonces(this.sender)).to.equal(1n); - expect(await this.mock.nonces(this.other)).to.equal(0n); - }); - - it('reverts when nonce is not the expected', async function () { - const currentNonce = await this.mock.nonces(this.sender); - - await expect(this.mock.$_useCheckedNonce(this.sender, currentNonce + 1n)) - .to.be.revertedWithCustomError(this.mock, 'InvalidAccountNonce') - .withArgs(this.sender, currentNonce); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/utils/Packing.t.sol b/lib/openzeppelin-contracts/test/utils/Packing.t.sol deleted file mode 100644 index 9531f1b..0000000 --- a/lib/openzeppelin-contracts/test/utils/Packing.t.sol +++ /dev/null @@ -1,681 +0,0 @@ -// SPDX-License-Identifier: MIT -// This file was procedurally generated from scripts/generate/templates/Packing.t.js. - -pragma solidity ^0.8.20; - -import {Test} from "forge-std/Test.sol"; -import {Packing} from "@openzeppelin/contracts/utils/Packing.sol"; - -contract PackingTest is Test { - using Packing for *; - - function testPack(bytes1 left, bytes1 right) external { - assertEq(left, Packing.pack_1_1(left, right).extract_2_1(0)); - assertEq(right, Packing.pack_1_1(left, right).extract_2_1(1)); - } - - function testPack(bytes2 left, bytes2 right) external { - assertEq(left, Packing.pack_2_2(left, right).extract_4_2(0)); - assertEq(right, Packing.pack_2_2(left, right).extract_4_2(2)); - } - - function testPack(bytes2 left, bytes4 right) external { - assertEq(left, Packing.pack_2_4(left, right).extract_6_2(0)); - assertEq(right, Packing.pack_2_4(left, right).extract_6_4(2)); - } - - function testPack(bytes2 left, bytes6 right) external { - assertEq(left, Packing.pack_2_6(left, right).extract_8_2(0)); - assertEq(right, Packing.pack_2_6(left, right).extract_8_6(2)); - } - - function testPack(bytes4 left, bytes2 right) external { - assertEq(left, Packing.pack_4_2(left, right).extract_6_4(0)); - assertEq(right, Packing.pack_4_2(left, right).extract_6_2(4)); - } - - function testPack(bytes4 left, bytes4 right) external { - assertEq(left, Packing.pack_4_4(left, right).extract_8_4(0)); - assertEq(right, Packing.pack_4_4(left, right).extract_8_4(4)); - } - - function testPack(bytes4 left, bytes8 right) external { - assertEq(left, Packing.pack_4_8(left, right).extract_12_4(0)); - assertEq(right, Packing.pack_4_8(left, right).extract_12_8(4)); - } - - function testPack(bytes4 left, bytes12 right) external { - assertEq(left, Packing.pack_4_12(left, right).extract_16_4(0)); - assertEq(right, Packing.pack_4_12(left, right).extract_16_12(4)); - } - - function testPack(bytes4 left, bytes16 right) external { - assertEq(left, Packing.pack_4_16(left, right).extract_20_4(0)); - assertEq(right, Packing.pack_4_16(left, right).extract_20_16(4)); - } - - function testPack(bytes4 left, bytes20 right) external { - assertEq(left, Packing.pack_4_20(left, right).extract_24_4(0)); - assertEq(right, Packing.pack_4_20(left, right).extract_24_20(4)); - } - - function testPack(bytes4 left, bytes24 right) external { - assertEq(left, Packing.pack_4_24(left, right).extract_28_4(0)); - assertEq(right, Packing.pack_4_24(left, right).extract_28_24(4)); - } - - function testPack(bytes4 left, bytes28 right) external { - assertEq(left, Packing.pack_4_28(left, right).extract_32_4(0)); - assertEq(right, Packing.pack_4_28(left, right).extract_32_28(4)); - } - - function testPack(bytes6 left, bytes2 right) external { - assertEq(left, Packing.pack_6_2(left, right).extract_8_6(0)); - assertEq(right, Packing.pack_6_2(left, right).extract_8_2(6)); - } - - function testPack(bytes6 left, bytes6 right) external { - assertEq(left, Packing.pack_6_6(left, right).extract_12_6(0)); - assertEq(right, Packing.pack_6_6(left, right).extract_12_6(6)); - } - - function testPack(bytes8 left, bytes4 right) external { - assertEq(left, Packing.pack_8_4(left, right).extract_12_8(0)); - assertEq(right, Packing.pack_8_4(left, right).extract_12_4(8)); - } - - function testPack(bytes8 left, bytes8 right) external { - assertEq(left, Packing.pack_8_8(left, right).extract_16_8(0)); - assertEq(right, Packing.pack_8_8(left, right).extract_16_8(8)); - } - - function testPack(bytes8 left, bytes12 right) external { - assertEq(left, Packing.pack_8_12(left, right).extract_20_8(0)); - assertEq(right, Packing.pack_8_12(left, right).extract_20_12(8)); - } - - function testPack(bytes8 left, bytes16 right) external { - assertEq(left, Packing.pack_8_16(left, right).extract_24_8(0)); - assertEq(right, Packing.pack_8_16(left, right).extract_24_16(8)); - } - - function testPack(bytes8 left, bytes20 right) external { - assertEq(left, Packing.pack_8_20(left, right).extract_28_8(0)); - assertEq(right, Packing.pack_8_20(left, right).extract_28_20(8)); - } - - function testPack(bytes8 left, bytes24 right) external { - assertEq(left, Packing.pack_8_24(left, right).extract_32_8(0)); - assertEq(right, Packing.pack_8_24(left, right).extract_32_24(8)); - } - - function testPack(bytes12 left, bytes4 right) external { - assertEq(left, Packing.pack_12_4(left, right).extract_16_12(0)); - assertEq(right, Packing.pack_12_4(left, right).extract_16_4(12)); - } - - function testPack(bytes12 left, bytes8 right) external { - assertEq(left, Packing.pack_12_8(left, right).extract_20_12(0)); - assertEq(right, Packing.pack_12_8(left, right).extract_20_8(12)); - } - - function testPack(bytes12 left, bytes12 right) external { - assertEq(left, Packing.pack_12_12(left, right).extract_24_12(0)); - assertEq(right, Packing.pack_12_12(left, right).extract_24_12(12)); - } - - function testPack(bytes12 left, bytes16 right) external { - assertEq(left, Packing.pack_12_16(left, right).extract_28_12(0)); - assertEq(right, Packing.pack_12_16(left, right).extract_28_16(12)); - } - - function testPack(bytes12 left, bytes20 right) external { - assertEq(left, Packing.pack_12_20(left, right).extract_32_12(0)); - assertEq(right, Packing.pack_12_20(left, right).extract_32_20(12)); - } - - function testPack(bytes16 left, bytes4 right) external { - assertEq(left, Packing.pack_16_4(left, right).extract_20_16(0)); - assertEq(right, Packing.pack_16_4(left, right).extract_20_4(16)); - } - - function testPack(bytes16 left, bytes8 right) external { - assertEq(left, Packing.pack_16_8(left, right).extract_24_16(0)); - assertEq(right, Packing.pack_16_8(left, right).extract_24_8(16)); - } - - function testPack(bytes16 left, bytes12 right) external { - assertEq(left, Packing.pack_16_12(left, right).extract_28_16(0)); - assertEq(right, Packing.pack_16_12(left, right).extract_28_12(16)); - } - - function testPack(bytes16 left, bytes16 right) external { - assertEq(left, Packing.pack_16_16(left, right).extract_32_16(0)); - assertEq(right, Packing.pack_16_16(left, right).extract_32_16(16)); - } - - function testPack(bytes20 left, bytes4 right) external { - assertEq(left, Packing.pack_20_4(left, right).extract_24_20(0)); - assertEq(right, Packing.pack_20_4(left, right).extract_24_4(20)); - } - - function testPack(bytes20 left, bytes8 right) external { - assertEq(left, Packing.pack_20_8(left, right).extract_28_20(0)); - assertEq(right, Packing.pack_20_8(left, right).extract_28_8(20)); - } - - function testPack(bytes20 left, bytes12 right) external { - assertEq(left, Packing.pack_20_12(left, right).extract_32_20(0)); - assertEq(right, Packing.pack_20_12(left, right).extract_32_12(20)); - } - - function testPack(bytes24 left, bytes4 right) external { - assertEq(left, Packing.pack_24_4(left, right).extract_28_24(0)); - assertEq(right, Packing.pack_24_4(left, right).extract_28_4(24)); - } - - function testPack(bytes24 left, bytes8 right) external { - assertEq(left, Packing.pack_24_8(left, right).extract_32_24(0)); - assertEq(right, Packing.pack_24_8(left, right).extract_32_8(24)); - } - - function testPack(bytes28 left, bytes4 right) external { - assertEq(left, Packing.pack_28_4(left, right).extract_32_28(0)); - assertEq(right, Packing.pack_28_4(left, right).extract_32_4(28)); - } - - function testReplace(bytes2 container, bytes1 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 1)); - - bytes1 oldValue = container.extract_2_1(offset); - - assertEq(newValue, container.replace_2_1(newValue, offset).extract_2_1(offset)); - assertEq(container, container.replace_2_1(newValue, offset).replace_2_1(oldValue, offset)); - } - - function testReplace(bytes4 container, bytes1 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 3)); - - bytes1 oldValue = container.extract_4_1(offset); - - assertEq(newValue, container.replace_4_1(newValue, offset).extract_4_1(offset)); - assertEq(container, container.replace_4_1(newValue, offset).replace_4_1(oldValue, offset)); - } - - function testReplace(bytes4 container, bytes2 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 2)); - - bytes2 oldValue = container.extract_4_2(offset); - - assertEq(newValue, container.replace_4_2(newValue, offset).extract_4_2(offset)); - assertEq(container, container.replace_4_2(newValue, offset).replace_4_2(oldValue, offset)); - } - - function testReplace(bytes6 container, bytes1 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 5)); - - bytes1 oldValue = container.extract_6_1(offset); - - assertEq(newValue, container.replace_6_1(newValue, offset).extract_6_1(offset)); - assertEq(container, container.replace_6_1(newValue, offset).replace_6_1(oldValue, offset)); - } - - function testReplace(bytes6 container, bytes2 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 4)); - - bytes2 oldValue = container.extract_6_2(offset); - - assertEq(newValue, container.replace_6_2(newValue, offset).extract_6_2(offset)); - assertEq(container, container.replace_6_2(newValue, offset).replace_6_2(oldValue, offset)); - } - - function testReplace(bytes6 container, bytes4 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 2)); - - bytes4 oldValue = container.extract_6_4(offset); - - assertEq(newValue, container.replace_6_4(newValue, offset).extract_6_4(offset)); - assertEq(container, container.replace_6_4(newValue, offset).replace_6_4(oldValue, offset)); - } - - function testReplace(bytes8 container, bytes1 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 7)); - - bytes1 oldValue = container.extract_8_1(offset); - - assertEq(newValue, container.replace_8_1(newValue, offset).extract_8_1(offset)); - assertEq(container, container.replace_8_1(newValue, offset).replace_8_1(oldValue, offset)); - } - - function testReplace(bytes8 container, bytes2 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 6)); - - bytes2 oldValue = container.extract_8_2(offset); - - assertEq(newValue, container.replace_8_2(newValue, offset).extract_8_2(offset)); - assertEq(container, container.replace_8_2(newValue, offset).replace_8_2(oldValue, offset)); - } - - function testReplace(bytes8 container, bytes4 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 4)); - - bytes4 oldValue = container.extract_8_4(offset); - - assertEq(newValue, container.replace_8_4(newValue, offset).extract_8_4(offset)); - assertEq(container, container.replace_8_4(newValue, offset).replace_8_4(oldValue, offset)); - } - - function testReplace(bytes8 container, bytes6 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 2)); - - bytes6 oldValue = container.extract_8_6(offset); - - assertEq(newValue, container.replace_8_6(newValue, offset).extract_8_6(offset)); - assertEq(container, container.replace_8_6(newValue, offset).replace_8_6(oldValue, offset)); - } - - function testReplace(bytes12 container, bytes1 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 11)); - - bytes1 oldValue = container.extract_12_1(offset); - - assertEq(newValue, container.replace_12_1(newValue, offset).extract_12_1(offset)); - assertEq(container, container.replace_12_1(newValue, offset).replace_12_1(oldValue, offset)); - } - - function testReplace(bytes12 container, bytes2 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 10)); - - bytes2 oldValue = container.extract_12_2(offset); - - assertEq(newValue, container.replace_12_2(newValue, offset).extract_12_2(offset)); - assertEq(container, container.replace_12_2(newValue, offset).replace_12_2(oldValue, offset)); - } - - function testReplace(bytes12 container, bytes4 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 8)); - - bytes4 oldValue = container.extract_12_4(offset); - - assertEq(newValue, container.replace_12_4(newValue, offset).extract_12_4(offset)); - assertEq(container, container.replace_12_4(newValue, offset).replace_12_4(oldValue, offset)); - } - - function testReplace(bytes12 container, bytes6 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 6)); - - bytes6 oldValue = container.extract_12_6(offset); - - assertEq(newValue, container.replace_12_6(newValue, offset).extract_12_6(offset)); - assertEq(container, container.replace_12_6(newValue, offset).replace_12_6(oldValue, offset)); - } - - function testReplace(bytes12 container, bytes8 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 4)); - - bytes8 oldValue = container.extract_12_8(offset); - - assertEq(newValue, container.replace_12_8(newValue, offset).extract_12_8(offset)); - assertEq(container, container.replace_12_8(newValue, offset).replace_12_8(oldValue, offset)); - } - - function testReplace(bytes16 container, bytes1 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 15)); - - bytes1 oldValue = container.extract_16_1(offset); - - assertEq(newValue, container.replace_16_1(newValue, offset).extract_16_1(offset)); - assertEq(container, container.replace_16_1(newValue, offset).replace_16_1(oldValue, offset)); - } - - function testReplace(bytes16 container, bytes2 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 14)); - - bytes2 oldValue = container.extract_16_2(offset); - - assertEq(newValue, container.replace_16_2(newValue, offset).extract_16_2(offset)); - assertEq(container, container.replace_16_2(newValue, offset).replace_16_2(oldValue, offset)); - } - - function testReplace(bytes16 container, bytes4 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 12)); - - bytes4 oldValue = container.extract_16_4(offset); - - assertEq(newValue, container.replace_16_4(newValue, offset).extract_16_4(offset)); - assertEq(container, container.replace_16_4(newValue, offset).replace_16_4(oldValue, offset)); - } - - function testReplace(bytes16 container, bytes6 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 10)); - - bytes6 oldValue = container.extract_16_6(offset); - - assertEq(newValue, container.replace_16_6(newValue, offset).extract_16_6(offset)); - assertEq(container, container.replace_16_6(newValue, offset).replace_16_6(oldValue, offset)); - } - - function testReplace(bytes16 container, bytes8 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 8)); - - bytes8 oldValue = container.extract_16_8(offset); - - assertEq(newValue, container.replace_16_8(newValue, offset).extract_16_8(offset)); - assertEq(container, container.replace_16_8(newValue, offset).replace_16_8(oldValue, offset)); - } - - function testReplace(bytes16 container, bytes12 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 4)); - - bytes12 oldValue = container.extract_16_12(offset); - - assertEq(newValue, container.replace_16_12(newValue, offset).extract_16_12(offset)); - assertEq(container, container.replace_16_12(newValue, offset).replace_16_12(oldValue, offset)); - } - - function testReplace(bytes20 container, bytes1 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 19)); - - bytes1 oldValue = container.extract_20_1(offset); - - assertEq(newValue, container.replace_20_1(newValue, offset).extract_20_1(offset)); - assertEq(container, container.replace_20_1(newValue, offset).replace_20_1(oldValue, offset)); - } - - function testReplace(bytes20 container, bytes2 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 18)); - - bytes2 oldValue = container.extract_20_2(offset); - - assertEq(newValue, container.replace_20_2(newValue, offset).extract_20_2(offset)); - assertEq(container, container.replace_20_2(newValue, offset).replace_20_2(oldValue, offset)); - } - - function testReplace(bytes20 container, bytes4 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 16)); - - bytes4 oldValue = container.extract_20_4(offset); - - assertEq(newValue, container.replace_20_4(newValue, offset).extract_20_4(offset)); - assertEq(container, container.replace_20_4(newValue, offset).replace_20_4(oldValue, offset)); - } - - function testReplace(bytes20 container, bytes6 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 14)); - - bytes6 oldValue = container.extract_20_6(offset); - - assertEq(newValue, container.replace_20_6(newValue, offset).extract_20_6(offset)); - assertEq(container, container.replace_20_6(newValue, offset).replace_20_6(oldValue, offset)); - } - - function testReplace(bytes20 container, bytes8 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 12)); - - bytes8 oldValue = container.extract_20_8(offset); - - assertEq(newValue, container.replace_20_8(newValue, offset).extract_20_8(offset)); - assertEq(container, container.replace_20_8(newValue, offset).replace_20_8(oldValue, offset)); - } - - function testReplace(bytes20 container, bytes12 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 8)); - - bytes12 oldValue = container.extract_20_12(offset); - - assertEq(newValue, container.replace_20_12(newValue, offset).extract_20_12(offset)); - assertEq(container, container.replace_20_12(newValue, offset).replace_20_12(oldValue, offset)); - } - - function testReplace(bytes20 container, bytes16 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 4)); - - bytes16 oldValue = container.extract_20_16(offset); - - assertEq(newValue, container.replace_20_16(newValue, offset).extract_20_16(offset)); - assertEq(container, container.replace_20_16(newValue, offset).replace_20_16(oldValue, offset)); - } - - function testReplace(bytes24 container, bytes1 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 23)); - - bytes1 oldValue = container.extract_24_1(offset); - - assertEq(newValue, container.replace_24_1(newValue, offset).extract_24_1(offset)); - assertEq(container, container.replace_24_1(newValue, offset).replace_24_1(oldValue, offset)); - } - - function testReplace(bytes24 container, bytes2 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 22)); - - bytes2 oldValue = container.extract_24_2(offset); - - assertEq(newValue, container.replace_24_2(newValue, offset).extract_24_2(offset)); - assertEq(container, container.replace_24_2(newValue, offset).replace_24_2(oldValue, offset)); - } - - function testReplace(bytes24 container, bytes4 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 20)); - - bytes4 oldValue = container.extract_24_4(offset); - - assertEq(newValue, container.replace_24_4(newValue, offset).extract_24_4(offset)); - assertEq(container, container.replace_24_4(newValue, offset).replace_24_4(oldValue, offset)); - } - - function testReplace(bytes24 container, bytes6 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 18)); - - bytes6 oldValue = container.extract_24_6(offset); - - assertEq(newValue, container.replace_24_6(newValue, offset).extract_24_6(offset)); - assertEq(container, container.replace_24_6(newValue, offset).replace_24_6(oldValue, offset)); - } - - function testReplace(bytes24 container, bytes8 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 16)); - - bytes8 oldValue = container.extract_24_8(offset); - - assertEq(newValue, container.replace_24_8(newValue, offset).extract_24_8(offset)); - assertEq(container, container.replace_24_8(newValue, offset).replace_24_8(oldValue, offset)); - } - - function testReplace(bytes24 container, bytes12 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 12)); - - bytes12 oldValue = container.extract_24_12(offset); - - assertEq(newValue, container.replace_24_12(newValue, offset).extract_24_12(offset)); - assertEq(container, container.replace_24_12(newValue, offset).replace_24_12(oldValue, offset)); - } - - function testReplace(bytes24 container, bytes16 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 8)); - - bytes16 oldValue = container.extract_24_16(offset); - - assertEq(newValue, container.replace_24_16(newValue, offset).extract_24_16(offset)); - assertEq(container, container.replace_24_16(newValue, offset).replace_24_16(oldValue, offset)); - } - - function testReplace(bytes24 container, bytes20 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 4)); - - bytes20 oldValue = container.extract_24_20(offset); - - assertEq(newValue, container.replace_24_20(newValue, offset).extract_24_20(offset)); - assertEq(container, container.replace_24_20(newValue, offset).replace_24_20(oldValue, offset)); - } - - function testReplace(bytes28 container, bytes1 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 27)); - - bytes1 oldValue = container.extract_28_1(offset); - - assertEq(newValue, container.replace_28_1(newValue, offset).extract_28_1(offset)); - assertEq(container, container.replace_28_1(newValue, offset).replace_28_1(oldValue, offset)); - } - - function testReplace(bytes28 container, bytes2 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 26)); - - bytes2 oldValue = container.extract_28_2(offset); - - assertEq(newValue, container.replace_28_2(newValue, offset).extract_28_2(offset)); - assertEq(container, container.replace_28_2(newValue, offset).replace_28_2(oldValue, offset)); - } - - function testReplace(bytes28 container, bytes4 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 24)); - - bytes4 oldValue = container.extract_28_4(offset); - - assertEq(newValue, container.replace_28_4(newValue, offset).extract_28_4(offset)); - assertEq(container, container.replace_28_4(newValue, offset).replace_28_4(oldValue, offset)); - } - - function testReplace(bytes28 container, bytes6 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 22)); - - bytes6 oldValue = container.extract_28_6(offset); - - assertEq(newValue, container.replace_28_6(newValue, offset).extract_28_6(offset)); - assertEq(container, container.replace_28_6(newValue, offset).replace_28_6(oldValue, offset)); - } - - function testReplace(bytes28 container, bytes8 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 20)); - - bytes8 oldValue = container.extract_28_8(offset); - - assertEq(newValue, container.replace_28_8(newValue, offset).extract_28_8(offset)); - assertEq(container, container.replace_28_8(newValue, offset).replace_28_8(oldValue, offset)); - } - - function testReplace(bytes28 container, bytes12 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 16)); - - bytes12 oldValue = container.extract_28_12(offset); - - assertEq(newValue, container.replace_28_12(newValue, offset).extract_28_12(offset)); - assertEq(container, container.replace_28_12(newValue, offset).replace_28_12(oldValue, offset)); - } - - function testReplace(bytes28 container, bytes16 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 12)); - - bytes16 oldValue = container.extract_28_16(offset); - - assertEq(newValue, container.replace_28_16(newValue, offset).extract_28_16(offset)); - assertEq(container, container.replace_28_16(newValue, offset).replace_28_16(oldValue, offset)); - } - - function testReplace(bytes28 container, bytes20 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 8)); - - bytes20 oldValue = container.extract_28_20(offset); - - assertEq(newValue, container.replace_28_20(newValue, offset).extract_28_20(offset)); - assertEq(container, container.replace_28_20(newValue, offset).replace_28_20(oldValue, offset)); - } - - function testReplace(bytes28 container, bytes24 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 4)); - - bytes24 oldValue = container.extract_28_24(offset); - - assertEq(newValue, container.replace_28_24(newValue, offset).extract_28_24(offset)); - assertEq(container, container.replace_28_24(newValue, offset).replace_28_24(oldValue, offset)); - } - - function testReplace(bytes32 container, bytes1 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 31)); - - bytes1 oldValue = container.extract_32_1(offset); - - assertEq(newValue, container.replace_32_1(newValue, offset).extract_32_1(offset)); - assertEq(container, container.replace_32_1(newValue, offset).replace_32_1(oldValue, offset)); - } - - function testReplace(bytes32 container, bytes2 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 30)); - - bytes2 oldValue = container.extract_32_2(offset); - - assertEq(newValue, container.replace_32_2(newValue, offset).extract_32_2(offset)); - assertEq(container, container.replace_32_2(newValue, offset).replace_32_2(oldValue, offset)); - } - - function testReplace(bytes32 container, bytes4 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 28)); - - bytes4 oldValue = container.extract_32_4(offset); - - assertEq(newValue, container.replace_32_4(newValue, offset).extract_32_4(offset)); - assertEq(container, container.replace_32_4(newValue, offset).replace_32_4(oldValue, offset)); - } - - function testReplace(bytes32 container, bytes6 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 26)); - - bytes6 oldValue = container.extract_32_6(offset); - - assertEq(newValue, container.replace_32_6(newValue, offset).extract_32_6(offset)); - assertEq(container, container.replace_32_6(newValue, offset).replace_32_6(oldValue, offset)); - } - - function testReplace(bytes32 container, bytes8 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 24)); - - bytes8 oldValue = container.extract_32_8(offset); - - assertEq(newValue, container.replace_32_8(newValue, offset).extract_32_8(offset)); - assertEq(container, container.replace_32_8(newValue, offset).replace_32_8(oldValue, offset)); - } - - function testReplace(bytes32 container, bytes12 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 20)); - - bytes12 oldValue = container.extract_32_12(offset); - - assertEq(newValue, container.replace_32_12(newValue, offset).extract_32_12(offset)); - assertEq(container, container.replace_32_12(newValue, offset).replace_32_12(oldValue, offset)); - } - - function testReplace(bytes32 container, bytes16 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 16)); - - bytes16 oldValue = container.extract_32_16(offset); - - assertEq(newValue, container.replace_32_16(newValue, offset).extract_32_16(offset)); - assertEq(container, container.replace_32_16(newValue, offset).replace_32_16(oldValue, offset)); - } - - function testReplace(bytes32 container, bytes20 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 12)); - - bytes20 oldValue = container.extract_32_20(offset); - - assertEq(newValue, container.replace_32_20(newValue, offset).extract_32_20(offset)); - assertEq(container, container.replace_32_20(newValue, offset).replace_32_20(oldValue, offset)); - } - - function testReplace(bytes32 container, bytes24 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 8)); - - bytes24 oldValue = container.extract_32_24(offset); - - assertEq(newValue, container.replace_32_24(newValue, offset).extract_32_24(offset)); - assertEq(container, container.replace_32_24(newValue, offset).replace_32_24(oldValue, offset)); - } - - function testReplace(bytes32 container, bytes28 newValue, uint8 offset) external { - offset = uint8(bound(offset, 0, 4)); - - bytes28 oldValue = container.extract_32_28(offset); - - assertEq(newValue, container.replace_32_28(newValue, offset).extract_32_28(offset)); - assertEq(container, container.replace_32_28(newValue, offset).replace_32_28(oldValue, offset)); - } -} diff --git a/lib/openzeppelin-contracts/test/utils/Packing.test.js b/lib/openzeppelin-contracts/test/utils/Packing.test.js deleted file mode 100644 index dd36f45..0000000 --- a/lib/openzeppelin-contracts/test/utils/Packing.test.js +++ /dev/null @@ -1,70 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { forceDeployCode } = require('../helpers/deploy'); -const { product } = require('../helpers/iterate'); -const { SIZES } = require('../../scripts/generate/templates/Packing.opts'); - -async function fixture() { - return { mock: await forceDeployCode('$Packing') }; -} - -describe('Packing', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('pack', function () { - for (const [size1, size2] of product(SIZES, SIZES).filter(([size1, size2]) => SIZES.includes(size1 + size2))) { - const value1 = ethers.hexlify(ethers.randomBytes(size1)); - const value2 = ethers.hexlify(ethers.randomBytes(size2)); - const packed = ethers.concat([value1, value2]); - - it(`pack bytes${size1} + bytes${size2} => bytes${size1 + size2}`, async function () { - expect(await this.mock[`$pack_${size1}_${size2}`](value1, value2)).to.equal(packed); - expect(await this.mock[`$extract_${size1 + size2}_${size1}`](packed, 0)).to.equal(value1); - expect(await this.mock[`$extract_${size1 + size2}_${size2}`](packed, size1)).to.equal(value2); - }); - } - }); - - describe('extract / replace', function () { - for (const [size1, size2] of product(SIZES, SIZES).filter(([size1, size2]) => size1 > size2)) { - const MAX_OFFSET = size1 - size2; - const offset = ethers.toNumber(ethers.randomBytes(1)) % (MAX_OFFSET + 1); - const outer = ethers.randomBytes(size1); - const value = ethers.randomBytes(size2); - - it(`extract bytes${size2} from bytes${size1}`, async function () { - expect(await this.mock[`$extract_${size1}_${size2}`](outer, offset)).to.equal( - ethers.hexlify(outer.slice(offset, offset + size2)), - ); - - await expect(this.mock[`$extract_${size1}_${size2}`](outer, MAX_OFFSET)).to.not.be.revertedWithCustomError( - this.mock, - 'OutOfRangeAccess', - ); - - await expect(this.mock[`$extract_${size1}_${size2}`](outer, MAX_OFFSET + 1)).to.be.revertedWithCustomError( - this.mock, - 'OutOfRangeAccess', - ); - }); - - it(`replace bytes${size2} from bytes${size1}`, async function () { - expect(await this.mock[`$replace_${size1}_${size2}`](outer, value, offset)).to.equal( - ethers.concat([outer.slice(0, offset), value, outer.slice(offset + size2)]), - ); - - await expect( - this.mock[`$replace_${size1}_${size2}`](outer, value, MAX_OFFSET), - ).to.not.be.revertedWithCustomError(this.mock, 'OutOfRangeAccess'); - - await expect( - this.mock[`$replace_${size1}_${size2}`](outer, value, MAX_OFFSET + 1), - ).to.be.revertedWithCustomError(this.mock, 'OutOfRangeAccess'); - }); - } - }); -}); diff --git a/lib/openzeppelin-contracts/test/utils/Panic.test.js b/lib/openzeppelin-contracts/test/utils/Panic.test.js deleted file mode 100644 index 49673c7..0000000 --- a/lib/openzeppelin-contracts/test/utils/Panic.test.js +++ /dev/null @@ -1,37 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); - -async function fixture() { - return { mock: await ethers.deployContract('$Panic') }; -} - -describe('Panic', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - for (const [name, code] of Object.entries({ - GENERIC: 0x0, - ASSERT: PANIC_CODES.ASSERTION_ERROR, - UNDER_OVERFLOW: PANIC_CODES.ARITHMETIC_OVERFLOW, - DIVISION_BY_ZERO: PANIC_CODES.DIVISION_BY_ZERO, - ENUM_CONVERSION_ERROR: PANIC_CODES.ENUM_CONVERSION_OUT_OF_BOUNDS, - STORAGE_ENCODING_ERROR: PANIC_CODES.INCORRECTLY_ENCODED_STORAGE_BYTE_ARRAY, - EMPTY_ARRAY_POP: PANIC_CODES.POP_ON_EMPTY_ARRAY, - ARRAY_OUT_OF_BOUNDS: PANIC_CODES.ARRAY_ACCESS_OUT_OF_BOUNDS, - RESOURCE_ERROR: PANIC_CODES.TOO_MUCH_MEMORY_ALLOCATED, - INVALID_INTERNAL_FUNCTION: PANIC_CODES.ZERO_INITIALIZED_VARIABLE, - })) { - describe(`${name} (${ethers.toBeHex(code)})`, function () { - it('exposes panic code as constant', async function () { - expect(await this.mock.getFunction(`$${name}`)()).to.equal(code); - }); - - it('reverts with panic when called', async function () { - await expect(this.mock.$panic(code)).to.be.revertedWithPanic(code); - }); - }); - } -}); diff --git a/lib/openzeppelin-contracts/test/utils/Pausable.test.js b/lib/openzeppelin-contracts/test/utils/Pausable.test.js deleted file mode 100644 index 67d74a0..0000000 --- a/lib/openzeppelin-contracts/test/utils/Pausable.test.js +++ /dev/null @@ -1,90 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -async function fixture() { - const [pauser] = await ethers.getSigners(); - - const mock = await ethers.deployContract('PausableMock'); - - return { pauser, mock }; -} - -describe('Pausable', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('when unpaused', function () { - beforeEach(async function () { - expect(await this.mock.paused()).to.be.false; - }); - - it('can perform normal process in non-pause', async function () { - expect(await this.mock.count()).to.equal(0n); - - await this.mock.normalProcess(); - expect(await this.mock.count()).to.equal(1n); - }); - - it('cannot take drastic measure in non-pause', async function () { - await expect(this.mock.drasticMeasure()).to.be.revertedWithCustomError(this.mock, 'ExpectedPause'); - - expect(await this.mock.drasticMeasureTaken()).to.be.false; - }); - - describe('when paused', function () { - beforeEach(async function () { - this.tx = await this.mock.pause(); - }); - - it('emits a Paused event', async function () { - await expect(this.tx).to.emit(this.mock, 'Paused').withArgs(this.pauser); - }); - - it('cannot perform normal process in pause', async function () { - await expect(this.mock.normalProcess()).to.be.revertedWithCustomError(this.mock, 'EnforcedPause'); - }); - - it('can take a drastic measure in a pause', async function () { - await this.mock.drasticMeasure(); - expect(await this.mock.drasticMeasureTaken()).to.be.true; - }); - - it('reverts when re-pausing', async function () { - await expect(this.mock.pause()).to.be.revertedWithCustomError(this.mock, 'EnforcedPause'); - }); - - describe('unpausing', function () { - it('is unpausable by the pauser', async function () { - await this.mock.unpause(); - expect(await this.mock.paused()).to.be.false; - }); - - describe('when unpaused', function () { - beforeEach(async function () { - this.tx = await this.mock.unpause(); - }); - - it('emits an Unpaused event', async function () { - await expect(this.tx).to.emit(this.mock, 'Unpaused').withArgs(this.pauser); - }); - - it('should resume allowing normal process', async function () { - expect(await this.mock.count()).to.equal(0n); - await this.mock.normalProcess(); - expect(await this.mock.count()).to.equal(1n); - }); - - it('should prevent drastic measure', async function () { - await expect(this.mock.drasticMeasure()).to.be.revertedWithCustomError(this.mock, 'ExpectedPause'); - }); - - it('reverts when re-unpausing', async function () { - await expect(this.mock.unpause()).to.be.revertedWithCustomError(this.mock, 'ExpectedPause'); - }); - }); - }); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/utils/ReentrancyGuard.test.js b/lib/openzeppelin-contracts/test/utils/ReentrancyGuard.test.js deleted file mode 100644 index c441856..0000000 --- a/lib/openzeppelin-contracts/test/utils/ReentrancyGuard.test.js +++ /dev/null @@ -1,50 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -for (const variant of ['', 'Transient']) { - describe(`Reentrancy${variant}Guard`, function () { - async function fixture() { - const name = `Reentrancy${variant}Mock`; - const mock = await ethers.deployContract(name); - return { name, mock }; - } - - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - it('nonReentrant function can be called', async function () { - expect(await this.mock.counter()).to.equal(0n); - await this.mock.callback(); - expect(await this.mock.counter()).to.equal(1n); - }); - - it('does not allow remote callback', async function () { - const attacker = await ethers.deployContract('ReentrancyAttack'); - await expect(this.mock.countAndCall(attacker)).to.be.revertedWith('ReentrancyAttack: failed call'); - }); - - it('_reentrancyGuardEntered should be true when guarded', async function () { - await this.mock.guardedCheckEntered(); - }); - - it('_reentrancyGuardEntered should be false when unguarded', async function () { - await this.mock.unguardedCheckNotEntered(); - }); - - // 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 expect(this.mock.countLocalRecursive(10n)).to.be.revertedWithCustomError( - this.mock, - 'ReentrancyGuardReentrantCall', - ); - }); - - it('does not allow indirect local recursion', async function () { - await expect(this.mock.countThisRecursive(10n)).to.be.revertedWith(`${this.name}: failed call`); - }); - }); -} diff --git a/lib/openzeppelin-contracts/test/utils/ShortStrings.t.sol b/lib/openzeppelin-contracts/test/utils/ShortStrings.t.sol deleted file mode 100644 index 4aeafd7..0000000 --- a/lib/openzeppelin-contracts/test/utils/ShortStrings.t.sol +++ /dev/null @@ -1,109 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {Test} from "forge-std/Test.sol"; -import {SymTest} from "halmos-cheatcodes/SymTest.sol"; - -import {ShortStrings, ShortString} from "@openzeppelin/contracts/utils/ShortStrings.sol"; - -contract ShortStringsTest is Test, SymTest { - string _fallback; - - function testRoundtripShort(string memory input) external { - vm.assume(_isShort(input)); - _assertRoundtripShort(input); - } - - function symbolicRoundtripShort() external { - string memory input = svm.createString(31, "RoundtripShortInput"); - _assertRoundtripShort(input); - } - - function testRoundtripWithFallback(string memory input, string memory fallbackInitial) external { - _assertRoundtripWithFallback(input, fallbackInitial); - } - - function symbolicRoundtripWithFallbackLong() external { - string memory input = svm.createString(256, "RoundtripWithFallbackInput"); - string memory fallbackInitial = svm.createString(256, "RoundtripWithFallbackFallbackInitial"); - _assertRoundtripWithFallback(input, fallbackInitial); - } - - function symbolicRoundtripWithFallbackShort() external { - string memory input = svm.createString(31, "RoundtripWithFallbackInput"); - string memory fallbackInitial = svm.createString(31, "RoundtripWithFallbackFallbackInitial"); - _assertRoundtripWithFallback(input, fallbackInitial); - } - - function testRevertLong(string memory input) external { - vm.assume(!_isShort(input)); - _assertRevertLong(input); - } - - function testLengthShort(string memory input) external { - vm.assume(_isShort(input)); - _assertLengthShort(input); - } - - function symbolicLengthShort() external { - string memory input = svm.createString(31, "LengthShortInput"); - _assertLengthShort(input); - } - - function testLengthWithFallback(string memory input, string memory fallbackInitial) external { - _fallback = fallbackInitial; - _assertLengthWithFallback(input); - } - - function symbolicLengthWithFallback() external { - uint256 length = 256; - string memory input = svm.createString(length, "LengthWithFallbackInput"); - string memory fallbackInitial = svm.createString(length, "LengthWithFallbackFallbackInitial"); - _fallback = fallbackInitial; - _assertLengthWithFallback(input); - } - - /// Assertions - - function _assertRoundtripShort(string memory input) internal { - ShortString short = ShortStrings.toShortString(input); - string memory output = ShortStrings.toString(short); - assertEq(input, output); - } - - function _assertRoundtripWithFallback(string memory input, string memory fallbackInitial) internal { - _fallback = fallbackInitial; // Make sure that the initial value has no effect - ShortString short = ShortStrings.toShortStringWithFallback(input, _fallback); - string memory output = ShortStrings.toStringWithFallback(short, _fallback); - assertEq(input, output); - } - - function _assertRevertLong(string memory input) internal { - vm.expectRevert(abi.encodeWithSelector(ShortStrings.StringTooLong.selector, input)); - this.toShortString(input); - } - - function _assertLengthShort(string memory input) internal { - ShortString short = ShortStrings.toShortString(input); - uint256 shortLength = ShortStrings.byteLength(short); - uint256 inputLength = bytes(input).length; - assertEq(inputLength, shortLength); - } - - function _assertLengthWithFallback(string memory input) internal { - uint256 inputLength = bytes(input).length; - ShortString short = ShortStrings.toShortStringWithFallback(input, _fallback); - uint256 shortLength = ShortStrings.byteLengthWithFallback(short, _fallback); - assertEq(inputLength, shortLength); - } - - /// Helpers - function toShortString(string memory input) external pure returns (ShortString) { - return ShortStrings.toShortString(input); - } - - function _isShort(string memory input) internal pure returns (bool) { - return bytes(input).length < 32; - } -} diff --git a/lib/openzeppelin-contracts/test/utils/ShortStrings.test.js b/lib/openzeppelin-contracts/test/utils/ShortStrings.test.js deleted file mode 100644 index cb1a06a..0000000 --- a/lib/openzeppelin-contracts/test/utils/ShortStrings.test.js +++ /dev/null @@ -1,64 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const FALLBACK_SENTINEL = ethers.zeroPadValue('0xFF', 32); - -const length = sstr => parseInt(sstr.slice(64), 16); -const decode = sstr => ethers.toUtf8String(sstr).slice(0, length(sstr)); -const encode = str => - str.length < 32 - ? ethers.concat([ - ethers.encodeBytes32String(str).slice(0, -2), - ethers.zeroPadValue(ethers.toBeArray(str.length), 1), - ]) - : FALLBACK_SENTINEL; - -async function fixture() { - const mock = await ethers.deployContract('$ShortStrings'); - return { mock }; -} - -describe('ShortStrings', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - for (const str of [0, 1, 16, 31, 32, 64, 1024].map(length => 'a'.repeat(length))) { - describe(`with string length ${str.length}`, function () { - it('encode / decode', async function () { - if (str.length < 32) { - const encoded = await this.mock.$toShortString(str); - expect(encoded).to.equal(encode(str)); - expect(decode(encoded)).to.equal(str); - - expect(await this.mock.$byteLength(encoded)).to.equal(str.length); - expect(await this.mock.$toString(encoded)).to.equal(str); - } else { - await expect(this.mock.$toShortString(str)) - .to.be.revertedWithCustomError(this.mock, 'StringTooLong') - .withArgs(str); - } - }); - - it('set / get with fallback', async function () { - const short = await this.mock - .$toShortStringWithFallback(str, 0) - .then(tx => tx.wait()) - .then(receipt => receipt.logs.find(ev => ev.fragment.name == 'return$toShortStringWithFallback').args[0]); - - expect(short).to.equal(encode(str)); - - const promise = this.mock.$toString(short); - if (str.length < 32) { - expect(await promise).to.equal(str); - } else { - await expect(promise).to.be.revertedWithCustomError(this.mock, 'InvalidShortString'); - } - - expect(await this.mock.$byteLengthWithFallback(short, 0)).to.equal(str.length); - expect(await this.mock.$toStringWithFallback(short, 0)).to.equal(str); - }); - }); - } -}); diff --git a/lib/openzeppelin-contracts/test/utils/SlotDerivation.t.sol b/lib/openzeppelin-contracts/test/utils/SlotDerivation.t.sol deleted file mode 100644 index 300a58b..0000000 --- a/lib/openzeppelin-contracts/test/utils/SlotDerivation.t.sol +++ /dev/null @@ -1,228 +0,0 @@ -// SPDX-License-Identifier: MIT -// This file was procedurally generated from scripts/generate/templates/SlotDerivation.t.js. - -pragma solidity ^0.8.20; - -import {Test} from "forge-std/Test.sol"; -import {SymTest} from "halmos-cheatcodes/SymTest.sol"; -import {SlotDerivation} from "@openzeppelin/contracts/utils/SlotDerivation.sol"; - -contract SlotDerivationTest is Test, SymTest { - using SlotDerivation for bytes32; - - bytes[] private _array; - - function symbolicDeriveArray(uint256 length, uint256 offset) public { - vm.assume(length > 0); - vm.assume(offset < length); - _assertDeriveArray(length, offset); - } - - function testDeriveArray(uint256 length, uint256 offset) public { - length = bound(length, 1, type(uint256).max); - offset = bound(offset, 0, length - 1); - _assertDeriveArray(length, offset); - } - - function _assertDeriveArray(uint256 length, uint256 offset) public { - bytes32 baseSlot; - assembly { - baseSlot := _array.slot - sstore(baseSlot, length) // store length so solidity access does not revert - } - - bytes storage derived = _array[offset]; - bytes32 derivedSlot; - assembly { - derivedSlot := derived.slot - } - - assertEq(baseSlot.deriveArray().offset(offset), derivedSlot); - } - - mapping(address => bytes) private _addressMapping; - - function testSymbolicDeriveMappingAddress(address key) public { - bytes32 baseSlot; - assembly { - baseSlot := _addressMapping.slot - } - - bytes storage derived = _addressMapping[key]; - bytes32 derivedSlot; - assembly { - derivedSlot := derived.slot - } - - assertEq(baseSlot.deriveMapping(key), derivedSlot); - } - - mapping(bool => bytes) private _boolMapping; - - function testSymbolicDeriveMappingBoolean(bool key) public { - bytes32 baseSlot; - assembly { - baseSlot := _boolMapping.slot - } - - bytes storage derived = _boolMapping[key]; - bytes32 derivedSlot; - assembly { - derivedSlot := derived.slot - } - - assertEq(baseSlot.deriveMapping(key), derivedSlot); - } - - mapping(bytes32 => bytes) private _bytes32Mapping; - - function testSymbolicDeriveMappingBytes32(bytes32 key) public { - bytes32 baseSlot; - assembly { - baseSlot := _bytes32Mapping.slot - } - - bytes storage derived = _bytes32Mapping[key]; - bytes32 derivedSlot; - assembly { - derivedSlot := derived.slot - } - - assertEq(baseSlot.deriveMapping(key), derivedSlot); - } - - mapping(bytes4 => bytes) private _bytes4Mapping; - - function testSymbolicDeriveMappingBytes4(bytes4 key) public { - bytes32 baseSlot; - assembly { - baseSlot := _bytes4Mapping.slot - } - - bytes storage derived = _bytes4Mapping[key]; - bytes32 derivedSlot; - assembly { - derivedSlot := derived.slot - } - - assertEq(baseSlot.deriveMapping(key), derivedSlot); - } - - mapping(uint256 => bytes) private _uint256Mapping; - - function testSymbolicDeriveMappingUint256(uint256 key) public { - bytes32 baseSlot; - assembly { - baseSlot := _uint256Mapping.slot - } - - bytes storage derived = _uint256Mapping[key]; - bytes32 derivedSlot; - assembly { - derivedSlot := derived.slot - } - - assertEq(baseSlot.deriveMapping(key), derivedSlot); - } - - mapping(uint32 => bytes) private _uint32Mapping; - - function testSymbolicDeriveMappingUint32(uint32 key) public { - bytes32 baseSlot; - assembly { - baseSlot := _uint32Mapping.slot - } - - bytes storage derived = _uint32Mapping[key]; - bytes32 derivedSlot; - assembly { - derivedSlot := derived.slot - } - - assertEq(baseSlot.deriveMapping(key), derivedSlot); - } - - mapping(int256 => bytes) private _int256Mapping; - - function testSymbolicDeriveMappingInt256(int256 key) public { - bytes32 baseSlot; - assembly { - baseSlot := _int256Mapping.slot - } - - bytes storage derived = _int256Mapping[key]; - bytes32 derivedSlot; - assembly { - derivedSlot := derived.slot - } - - assertEq(baseSlot.deriveMapping(key), derivedSlot); - } - - mapping(int32 => bytes) private _int32Mapping; - - function testSymbolicDeriveMappingInt32(int32 key) public { - bytes32 baseSlot; - assembly { - baseSlot := _int32Mapping.slot - } - - bytes storage derived = _int32Mapping[key]; - bytes32 derivedSlot; - assembly { - derivedSlot := derived.slot - } - - assertEq(baseSlot.deriveMapping(key), derivedSlot); - } - - mapping(string => bytes) private _stringMapping; - - function testDeriveMappingString(string memory key) public { - _assertDeriveMappingString(key); - } - - function symbolicDeriveMappingString() public { - _assertDeriveMappingString(svm.createString(256, "DeriveMappingStringInput")); - } - - function _assertDeriveMappingString(string memory key) internal { - bytes32 baseSlot; - assembly { - baseSlot := _stringMapping.slot - } - - bytes storage derived = _stringMapping[key]; - bytes32 derivedSlot; - assembly { - derivedSlot := derived.slot - } - - assertEq(baseSlot.deriveMapping(key), derivedSlot); - } - - mapping(bytes => bytes) private _bytesMapping; - - function testDeriveMappingBytes(bytes memory key) public { - _assertDeriveMappingBytes(key); - } - - function symbolicDeriveMappingBytes() public { - _assertDeriveMappingBytes(svm.createBytes(256, "DeriveMappingBytesInput")); - } - - function _assertDeriveMappingBytes(bytes memory key) internal { - bytes32 baseSlot; - assembly { - baseSlot := _bytesMapping.slot - } - - bytes storage derived = _bytesMapping[key]; - bytes32 derivedSlot; - assembly { - derivedSlot := derived.slot - } - - assertEq(baseSlot.deriveMapping(key), derivedSlot); - } -} diff --git a/lib/openzeppelin-contracts/test/utils/SlotDerivation.test.js b/lib/openzeppelin-contracts/test/utils/SlotDerivation.test.js deleted file mode 100644 index 22582b3..0000000 --- a/lib/openzeppelin-contracts/test/utils/SlotDerivation.test.js +++ /dev/null @@ -1,58 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { erc7201Slot } = require('../helpers/storage'); -const { generators } = require('../helpers/random'); - -async function fixture() { - const [account] = await ethers.getSigners(); - const mock = await ethers.deployContract('$SlotDerivation'); - return { mock, account }; -} - -describe('SlotDerivation', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('namespaces', function () { - const namespace = 'example.main'; - - it('erc-7201', async function () { - expect(await this.mock.$erc7201Slot(namespace)).to.equal(erc7201Slot(namespace)); - }); - }); - - describe('derivation', function () { - it('offset', async function () { - const base = generators.bytes32(); - const offset = generators.uint256(); - expect(await this.mock.$offset(base, offset)).to.equal((ethers.toBigInt(base) + offset) & ethers.MaxUint256); - }); - - it('array', async function () { - const base = generators.bytes32(); - expect(await this.mock.$deriveArray(base)).to.equal(ethers.keccak256(base)); - }); - - describe('mapping', function () { - for (const { type, key, isValueType } of [ - { type: 'bool', key: true, isValueType: true }, - { type: 'address', key: generators.address(), isValueType: true }, - { type: 'bytes32', key: generators.bytes32(), isValueType: true }, - { type: 'uint256', key: generators.uint256(), isValueType: true }, - { type: 'int256', key: generators.int256(), isValueType: true }, - { type: 'bytes', key: generators.hexBytes(128), isValueType: false }, - { type: 'string', key: 'lorem ipsum', isValueType: false }, - ]) { - it(type, async function () { - const base = generators.bytes32(); - const expected = isValueType - ? ethers.keccak256(ethers.AbiCoder.defaultAbiCoder().encode([type, 'bytes32'], [key, base])) - : ethers.solidityPackedKeccak256([type, 'bytes32'], [key, base]); - expect(await this.mock[`$deriveMapping(bytes32,${type})`](base, key)).to.equal(expected); - }); - } - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/utils/StorageSlot.test.js b/lib/openzeppelin-contracts/test/utils/StorageSlot.test.js deleted file mode 100644 index 35e83e2..0000000 --- a/lib/openzeppelin-contracts/test/utils/StorageSlot.test.js +++ /dev/null @@ -1,106 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { generators } = require('../helpers/random'); - -const slot = ethers.id('some.storage.slot'); -const otherSlot = ethers.id('some.other.storage.slot'); - -const TYPES = [ - { name: 'Boolean', type: 'bool', value: true, isValueType: true, zero: false }, - { name: 'Address', type: 'address', value: generators.address(), isValueType: true, zero: generators.address.zero }, - { name: 'Bytes32', type: 'bytes32', value: generators.bytes32(), isValueType: true, zero: generators.bytes32.zero }, - { name: 'Uint256', type: 'uint256', value: generators.uint256(), isValueType: true, zero: generators.uint256.zero }, - { name: 'Int256', type: 'int256', value: generators.int256(), isValueType: true, zero: generators.int256.zero }, - { name: 'Bytes', type: 'bytes', value: generators.hexBytes(128), isValueType: false, zero: generators.hexBytes.zero }, - { name: 'String', type: 'string', value: 'lorem ipsum', isValueType: false, zero: '' }, -]; - -async function fixture() { - return { mock: await ethers.deployContract('StorageSlotMock') }; -} - -describe('StorageSlot', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - for (const { name, type, value, zero } of TYPES) { - describe(`${type} storage slot`, function () { - it('set', async function () { - await this.mock.getFunction(`set${name}Slot`)(slot, value); - }); - - describe('get', function () { - beforeEach(async function () { - await this.mock.getFunction(`set${name}Slot`)(slot, value); - }); - - it('from right slot', async function () { - expect(await this.mock.getFunction(`get${name}Slot`)(slot)).to.equal(value); - }); - - it('from other slot', async function () { - expect(await this.mock.getFunction(`get${name}Slot`)(otherSlot)).to.equal(zero); - }); - }); - }); - } - - for (const { name, type, value, zero } of TYPES.filter(type => !type.isValueType)) { - describe(`${type} storage pointer`, function () { - it('set', async function () { - await this.mock.getFunction(`set${name}Storage`)(slot, value); - }); - - describe('get', function () { - beforeEach(async function () { - await this.mock.getFunction(`set${name}Storage`)(slot, value); - }); - - it('from right slot', async function () { - expect(await this.mock.getFunction(`${type}Map`)(slot)).to.equal(value); - expect(await this.mock.getFunction(`get${name}Storage`)(slot)).to.equal(value); - }); - - it('from other slot', async function () { - expect(await this.mock.getFunction(`${type}Map`)(otherSlot)).to.equal(zero); - expect(await this.mock.getFunction(`get${name}Storage`)(otherSlot)).to.equal(zero); - }); - }); - }); - } - - for (const { name, type, value, zero } of TYPES.filter(type => type.isValueType)) { - describe(`${type} transient slot`, function () { - const load = `tload${name}(bytes32)`; - const store = `tstore(bytes32,${type})`; - const event = `${name}Value`; - - it('load', async function () { - await expect(this.mock[load](slot)).to.emit(this.mock, event).withArgs(slot, zero); - }); - - it('store and load (2 txs)', async function () { - await this.mock[store](slot, value); - await expect(this.mock[load](slot)).to.emit(this.mock, event).withArgs(slot, zero); - }); - - it('store and load (batched)', async function () { - await expect( - this.mock.multicall([ - this.mock.interface.encodeFunctionData(store, [slot, value]), - this.mock.interface.encodeFunctionData(load, [slot]), - this.mock.interface.encodeFunctionData(load, [otherSlot]), - ]), - ) - .to.emit(this.mock, event) - .withArgs(slot, value) - .to.emit(this.mock, event) - .withArgs(otherSlot, zero); - - await expect(this.mock[load](slot)).to.emit(this.mock, event).withArgs(slot, zero); - }); - }); - } -}); diff --git a/lib/openzeppelin-contracts/test/utils/Strings.test.js b/lib/openzeppelin-contracts/test/utils/Strings.test.js deleted file mode 100644 index 6353fd8..0000000 --- a/lib/openzeppelin-contracts/test/utils/Strings.test.js +++ /dev/null @@ -1,180 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -async function fixture() { - const mock = await ethers.deployContract('$Strings'); - return { mock }; -} - -describe('Strings', function () { - before(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('toString', function () { - const values = [ - 0n, - 7n, - 10n, - 99n, - 100n, - 101n, - 123n, - 4132n, - 12345n, - 1234567n, - 1234567890n, - 123456789012345n, - 12345678901234567890n, - 123456789012345678901234567890n, - 1234567890123456789012345678901234567890n, - 12345678901234567890123456789012345678901234567890n, - 123456789012345678901234567890123456789012345678901234567890n, - 1234567890123456789012345678901234567890123456789012345678901234567890n, - ]; - - describe('uint256', function () { - it('converts MAX_UINT256', async function () { - const value = ethers.MaxUint256; - expect(await this.mock.$toString(value)).to.equal(value.toString(10)); - }); - - for (const value of values) { - it(`converts ${value}`, async function () { - expect(await this.mock.$toString(value)).to.equal(value); - }); - } - }); - - describe('int256', function () { - it('converts MAX_INT256', async function () { - const value = ethers.MaxInt256; - expect(await this.mock.$toStringSigned(value)).to.equal(value.toString(10)); - }); - - it('converts MIN_INT256', async function () { - const value = ethers.MinInt256; - expect(await this.mock.$toStringSigned(value)).to.equal(value.toString(10)); - }); - - for (const value of values) { - it(`convert ${value}`, async function () { - expect(await this.mock.$toStringSigned(value)).to.equal(value); - }); - - it(`convert negative ${value}`, async function () { - const negated = -value; - expect(await this.mock.$toStringSigned(negated)).to.equal(negated.toString(10)); - }); - } - }); - }); - - describe('toHexString', function () { - it('converts 0', async function () { - expect(await this.mock.getFunction('$toHexString(uint256)')(0n)).to.equal('0x00'); - }); - - it('converts a positive number', async function () { - expect(await this.mock.getFunction('$toHexString(uint256)')(0x4132n)).to.equal('0x4132'); - }); - - it('converts MAX_UINT256', async function () { - expect(await this.mock.getFunction('$toHexString(uint256)')(ethers.MaxUint256)).to.equal( - `0x${ethers.MaxUint256.toString(16)}`, - ); - }); - }); - - describe('toHexString fixed', function () { - it('converts a positive number (long)', async function () { - expect(await this.mock.getFunction('$toHexString(uint256,uint256)')(0x4132n, 32n)).to.equal( - '0x0000000000000000000000000000000000000000000000000000000000004132', - ); - }); - - it('converts a positive number (short)', async function () { - const length = 1n; - await expect(this.mock.getFunction('$toHexString(uint256,uint256)')(0x4132n, length)) - .to.be.revertedWithCustomError(this.mock, `StringsInsufficientHexLength`) - .withArgs(0x4132, length); - }); - - it('converts MAX_UINT256', async function () { - expect(await this.mock.getFunction('$toHexString(uint256,uint256)')(ethers.MaxUint256, 32n)).to.equal( - `0x${ethers.MaxUint256.toString(16)}`, - ); - }); - }); - - describe('addresses', function () { - const addresses = [ - '0xa9036907dccae6a1e0033479b12e837e5cf5a02f', // Random address - '0x0000e0ca771e21bd00057f54a68c30d400000000', // Leading and trailing zeros - // EIP-55 reference - '0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed', - '0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359', - '0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB', - '0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb', - '0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359', - '0x52908400098527886E0F7030069857D2E4169EE7', - '0x8617E340B3D01FA5F11F306F4090FD50E238070D', - '0xde709f2102306220921060314715629080e2fb77', - '0x27b1fdb04752bbc536007a920d24acb045561c26', - '0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed', - '0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359', - '0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB', - '0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb', - ]; - - describe('toHexString', function () { - for (const addr of addresses) { - it(`converts ${addr}`, async function () { - expect(await this.mock.getFunction('$toHexString(address)')(addr)).to.equal(addr.toLowerCase()); - }); - } - }); - - describe('toChecksumHexString', function () { - for (const addr of addresses) { - it(`converts ${addr}`, async function () { - expect(await this.mock.getFunction('$toChecksumHexString(address)')(addr)).to.equal( - ethers.getAddress(addr.toLowerCase()), - ); - }); - } - }); - }); - - describe('equal', function () { - it('compares two empty strings', async function () { - expect(await this.mock.$equal('', '')).to.be.true; - }); - - it('compares two equal strings', async function () { - expect(await this.mock.$equal('a', 'a')).to.be.true; - }); - - it('compares two different strings', async function () { - expect(await this.mock.$equal('a', 'b')).to.be.false; - }); - - it('compares two different strings of different lengths', async function () { - expect(await this.mock.$equal('a', 'aa')).to.be.false; - expect(await this.mock.$equal('aa', 'a')).to.be.false; - }); - - it('compares two different large strings', async function () { - const str1 = 'a'.repeat(201); - const str2 = 'a'.repeat(200) + 'b'; - expect(await this.mock.$equal(str1, str2)).to.be.false; - }); - - it('compares two equal large strings', async function () { - const str1 = 'a'.repeat(201); - const str2 = 'a'.repeat(201); - expect(await this.mock.$equal(str1, str2)).to.be.true; - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/utils/cryptography/ECDSA.test.js b/lib/openzeppelin-contracts/test/utils/cryptography/ECDSA.test.js deleted file mode 100644 index 6b24bdb..0000000 --- a/lib/openzeppelin-contracts/test/utils/cryptography/ECDSA.test.js +++ /dev/null @@ -1,213 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const TEST_MESSAGE = ethers.id('OpenZeppelin'); -const WRONG_MESSAGE = ethers.id('Nope'); -const NON_HASH_MESSAGE = '0xabcd'; - -async function fixture() { - const [signer] = await ethers.getSigners(); - const mock = await ethers.deployContract('$ECDSA'); - return { signer, mock }; -} - -describe('ECDSA', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('recover with invalid signature', function () { - it('with short signature', async function () { - await expect(this.mock.$recover(TEST_MESSAGE, '0x1234')) - .to.be.revertedWithCustomError(this.mock, 'ECDSAInvalidSignatureLength') - .withArgs(2); - }); - - it('with long signature', async function () { - await expect( - // eslint-disable-next-line max-len - this.mock.$recover( - TEST_MESSAGE, - '0x01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789', - ), - ) - .to.be.revertedWithCustomError(this.mock, 'ECDSAInvalidSignatureLength') - .withArgs(85); - }); - }); - - describe('recover with valid signature', function () { - describe('using .sign', function () { - it('returns signer address with correct signature', async function () { - // Create the signature - const signature = await this.signer.signMessage(TEST_MESSAGE); - - // Recover the signer address from the generated message and signature. - expect(await this.mock.$recover(ethers.hashMessage(TEST_MESSAGE), signature)).to.equal(this.signer); - }); - - it('returns signer address with correct signature for arbitrary length message', async function () { - // Create the signature - const signature = await this.signer.signMessage(NON_HASH_MESSAGE); - - // Recover the signer address from the generated message and signature. - expect(await this.mock.$recover(ethers.hashMessage(NON_HASH_MESSAGE), signature)).to.equal(this.signer); - }); - - it('returns a different address', async function () { - const signature = await this.signer.signMessage(TEST_MESSAGE); - expect(await this.mock.$recover(WRONG_MESSAGE, signature)).to.not.be.equal(this.signer); - }); - - it('reverts with invalid signature', async function () { - // eslint-disable-next-line max-len - const signature = - '0x332ce75a821c982f9127538858900d87d3ec1f9f737338ad67cad133fa48feff48e6fa0c18abc62e42820f05943e47af3e9fbe306ce74d64094bdf1691ee53e01c'; - await expect(this.mock.$recover(TEST_MESSAGE, signature)).to.be.revertedWithCustomError( - this.mock, - 'ECDSAInvalidSignature', - ); - }); - }); - - describe('with v=27 signature', function () { - const signer = '0x2cc1166f6212628A0deEf2B33BEFB2187D35b86c'; - // eslint-disable-next-line max-len - const signatureWithoutV = - '0x5d99b6f7f6d1f73d1a26497f2b1c89b24c0993913f86e9a2d02cd69887d9c94f3c880358579d811b21dd1b7fd9bb01c1d81d10e69f0384e675c32b39643be892'; - - it('works with correct v value', async function () { - const v = '0x1b'; // 27 = 1b. - const signature = ethers.concat([signatureWithoutV, v]); - expect(await this.mock.$recover(TEST_MESSAGE, signature)).to.equal(signer); - - const { r, s, yParityAndS: vs } = ethers.Signature.from(signature); - expect(await this.mock.getFunction('$recover(bytes32,uint8,bytes32,bytes32)')(TEST_MESSAGE, v, r, s)).to.equal( - signer, - ); - - expect(await this.mock.getFunction('$recover(bytes32,bytes32,bytes32)')(TEST_MESSAGE, r, vs)).to.equal(signer); - }); - - it('rejects incorrect v value', async function () { - const v = '0x1c'; // 28 = 1c. - const signature = ethers.concat([signatureWithoutV, v]); - expect(await this.mock.$recover(TEST_MESSAGE, signature)).to.not.equal(signer); - - const { r, s, yParityAndS: vs } = ethers.Signature.from(signature); - expect( - await this.mock.getFunction('$recover(bytes32,uint8,bytes32,bytes32)')(TEST_MESSAGE, v, r, s), - ).to.not.equal(signer); - - expect(await this.mock.getFunction('$recover(bytes32,bytes32,bytes32)')(TEST_MESSAGE, r, vs)).to.not.equal( - signer, - ); - }); - - it('reverts wrong v values', async function () { - for (const v of ['0x00', '0x01']) { - const signature = ethers.concat([signatureWithoutV, v]); - await expect(this.mock.$recover(TEST_MESSAGE, signature)).to.be.revertedWithCustomError( - this.mock, - 'ECDSAInvalidSignature', - ); - - const { r, s } = ethers.Signature.from(signature); - await expect( - this.mock.getFunction('$recover(bytes32,uint8,bytes32,bytes32)')(TEST_MESSAGE, v, r, s), - ).to.be.revertedWithCustomError(this.mock, 'ECDSAInvalidSignature'); - } - }); - - it('rejects short EIP2098 format', async function () { - const v = '0x1b'; // 27 = 1b. - const signature = ethers.concat([signatureWithoutV, v]); - - const { compactSerialized } = ethers.Signature.from(signature); - await expect(this.mock.$recover(TEST_MESSAGE, compactSerialized)) - .to.be.revertedWithCustomError(this.mock, 'ECDSAInvalidSignatureLength') - .withArgs(64); - }); - }); - - describe('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 = '0x1c'; // 28 = 1c. - const signature = ethers.concat([signatureWithoutV, v]); - expect(await this.mock.$recover(TEST_MESSAGE, signature)).to.equal(signer); - - const { r, s, yParityAndS: vs } = ethers.Signature.from(signature); - expect(await this.mock.getFunction('$recover(bytes32,uint8,bytes32,bytes32)')(TEST_MESSAGE, v, r, s)).to.equal( - signer, - ); - - expect(await this.mock.getFunction('$recover(bytes32,bytes32,bytes32)')(TEST_MESSAGE, r, vs)).to.equal(signer); - }); - - it('rejects incorrect v value', async function () { - const v = '0x1b'; // 27 = 1b. - const signature = ethers.concat([signatureWithoutV, v]); - expect(await this.mock.$recover(TEST_MESSAGE, signature)).to.not.equal(signer); - - const { r, s, yParityAndS: vs } = ethers.Signature.from(signature); - expect( - await this.mock.getFunction('$recover(bytes32,uint8,bytes32,bytes32)')(TEST_MESSAGE, v, r, s), - ).to.not.equal(signer); - - expect(await this.mock.getFunction('$recover(bytes32,bytes32,bytes32)')(TEST_MESSAGE, r, vs)).to.not.equal( - signer, - ); - }); - - it('reverts invalid v values', async function () { - for (const v of ['0x00', '0x01']) { - const signature = ethers.concat([signatureWithoutV, v]); - await expect(this.mock.$recover(TEST_MESSAGE, signature)).to.be.revertedWithCustomError( - this.mock, - 'ECDSAInvalidSignature', - ); - - const { r, s } = ethers.Signature.from(signature); - await expect( - this.mock.getFunction('$recover(bytes32,uint8,bytes32,bytes32)')(TEST_MESSAGE, v, r, s), - ).to.be.revertedWithCustomError(this.mock, 'ECDSAInvalidSignature'); - } - }); - - it('rejects short EIP2098 format', async function () { - const v = '0x1b'; // 28 = 1b. - const signature = ethers.concat([signatureWithoutV, v]); - - const { compactSerialized } = ethers.Signature.from(signature); - await expect(this.mock.$recover(TEST_MESSAGE, compactSerialized)) - .to.be.revertedWithCustomError(this.mock, 'ECDSAInvalidSignatureLength') - .withArgs(64); - }); - }); - - it('reverts with high-s value signature', async function () { - const message = '0xb94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9'; - // eslint-disable-next-line max-len - const highSSignature = - '0xe742ff452d41413616a5bf43fe15dd88294e983d3d36206c2712f39083d638bde0a0fc89be718fbc1033e1d30d78be1c68081562ed2e97af876f286f3453231d1b'; - - const r = ethers.dataSlice(highSSignature, 0, 32); - const s = ethers.dataSlice(highSSignature, 32, 64); - const v = ethers.dataSlice(highSSignature, 64, 65); - - await expect(this.mock.$recover(message, highSSignature)) - .to.be.revertedWithCustomError(this.mock, 'ECDSAInvalidSignatureS') - .withArgs(s); - await expect(this.mock.getFunction('$recover(bytes32,uint8,bytes32,bytes32)')(TEST_MESSAGE, v, r, s)) - .to.be.revertedWithCustomError(this.mock, 'ECDSAInvalidSignatureS') - .withArgs(s); - expect(() => ethers.Signature.from(highSSignature)).to.throw('non-canonical s'); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/utils/cryptography/EIP712.test.js b/lib/openzeppelin-contracts/test/utils/cryptography/EIP712.test.js deleted file mode 100644 index 2b6e7fa..0000000 --- a/lib/openzeppelin-contracts/test/utils/cryptography/EIP712.test.js +++ /dev/null @@ -1,105 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { getDomain, domainSeparator, hashTypedData } = require('../../helpers/eip712'); -const { formatType } = require('../../helpers/eip712-types'); - -const LENGTHS = { - short: ['A Name', '1'], - long: ['A'.repeat(40), 'B'.repeat(40)], -}; - -const fixture = async () => { - const [from, to] = await ethers.getSigners(); - - const lengths = {}; - for (const [shortOrLong, [name, version]] of Object.entries(LENGTHS)) { - lengths[shortOrLong] = { name, version }; - lengths[shortOrLong].eip712 = await ethers.deployContract('$EIP712Verifier', [name, version]); - lengths[shortOrLong].domain = { - name, - version, - chainId: await ethers.provider.getNetwork().then(({ chainId }) => chainId), - verifyingContract: lengths[shortOrLong].eip712.target, - }; - } - - return { from, to, lengths }; -}; - -describe('EIP712', function () { - for (const [shortOrLong, [name, version]] of Object.entries(LENGTHS)) { - describe(`with ${shortOrLong} name and version`, function () { - beforeEach('deploying', async function () { - Object.assign(this, await loadFixture(fixture)); - Object.assign(this, this.lengths[shortOrLong]); - }); - - describe('domain separator', function () { - it('is internally available', async function () { - const expected = await domainSeparator(this.domain); - - expect(await this.eip712.$_domainSeparatorV4()).to.equal(expected); - }); - - it("can be rebuilt using EIP-5267's eip712Domain", async function () { - const rebuildDomain = await getDomain(this.eip712); - expect(rebuildDomain).to.be.deep.equal(this.domain); - }); - - if (shortOrLong === 'short') { - // Long strings are in storage, and the proxy will not be properly initialized unless - // the upgradeable contract variant is used and the initializer is invoked. - - it('adjusts when behind proxy', async function () { - const factory = await ethers.deployContract('$Clones'); - - const clone = await factory - .$clone(this.eip712) - .then(tx => tx.wait()) - .then(receipt => receipt.logs.find(ev => ev.fragment.name == 'return$clone_address').args.instance) - .then(address => ethers.getContractAt('$EIP712Verifier', address)); - - const expectedDomain = { ...this.domain, verifyingContract: clone.target }; - expect(await getDomain(clone)).to.be.deep.equal(expectedDomain); - - const expectedSeparator = await domainSeparator(expectedDomain); - expect(await clone.$_domainSeparatorV4()).to.equal(expectedSeparator); - }); - } - }); - - it('hash digest', async function () { - const structhash = ethers.hexlify(ethers.randomBytes(32)); - expect(await this.eip712.$_hashTypedDataV4(structhash)).to.equal(hashTypedData(this.domain, structhash)); - }); - - it('digest', async function () { - const types = { - Mail: formatType({ - to: 'address', - contents: 'string', - }), - }; - - const message = { - to: this.to.address, - contents: 'very interesting', - }; - - const signature = await this.from.signTypedData(this.domain, types, message); - - await expect(this.eip712.verify(signature, this.from.address, message.to, message.contents)).to.not.be.reverted; - }); - - it('name', async function () { - expect(await this.eip712.$_EIP712Name()).to.equal(name); - }); - - it('version', async function () { - expect(await this.eip712.$_EIP712Version()).to.equal(version); - }); - }); - } -}); diff --git a/lib/openzeppelin-contracts/test/utils/cryptography/MerkleProof.test.js b/lib/openzeppelin-contracts/test/utils/cryptography/MerkleProof.test.js deleted file mode 100644 index 93ee964..0000000 --- a/lib/openzeppelin-contracts/test/utils/cryptography/MerkleProof.test.js +++ /dev/null @@ -1,213 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); -const { SimpleMerkleTree } = require('@openzeppelin/merkle-tree'); - -// generate bytes32 leaves from a string -const toLeaves = (str, separator = '') => str.split(separator).map(e => ethers.keccak256(ethers.toUtf8Bytes(e))); -// internal node hashes -const concatSorted = (...elements) => Buffer.concat(elements.map(ethers.getBytes).sort(Buffer.compare)); -const defaultHash = (a, b) => ethers.keccak256(concatSorted(a, b)); -const customHash = (a, b) => ethers.sha256(concatSorted(a, b)); - -describe('MerkleProof', function () { - for (const { title, contractName, nodeHash } of [ - { title: 'default hash', contractName: '$MerkleProof', nodeHash: defaultHash }, - { title: 'custom hash', contractName: '$MerkleProofCustomHashMock', nodeHash: customHash }, - ]) { - describe(title, function () { - // stateless: no need for a fixture, just use before - before(async function () { - this.mock = await ethers.deployContract(contractName); - this.makeTree = str => SimpleMerkleTree.of(toLeaves(str), { nodeHash }); - }); - - describe('verify', function () { - it('returns true for a valid Merkle proof', async function () { - const merkleTree = this.makeTree('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='); - - const root = merkleTree.root; - const hash = merkleTree.at(0); - const proof = merkleTree.getProof(0); - - expect(await this.mock.$processProof(proof, hash)).to.equal(root); - expect(await this.mock.$processProofCalldata(proof, hash)).to.equal(root); - expect(await this.mock.$verify(proof, root, hash)).to.be.true; - expect(await this.mock.$verifyCalldata(proof, root, hash)).to.be.true; - - // For demonstration, it is also possible to create valid proofs for certain 64-byte values *not* in elements: - const noSuchLeaf = nodeHash(hash, proof.at(0)); - - expect(await this.mock.$processProof(proof.slice(1), noSuchLeaf)).to.equal(root); - expect(await this.mock.$processProofCalldata(proof.slice(1), noSuchLeaf)).to.equal(root); - expect(await this.mock.$verify(proof.slice(1), root, noSuchLeaf)).to.be.true; - expect(await this.mock.$verifyCalldata(proof.slice(1), root, noSuchLeaf)).to.be.true; - }); - - it('returns false for an invalid Merkle proof', async function () { - const correctMerkleTree = this.makeTree('abc'); - const otherMerkleTree = this.makeTree('def'); - - const root = correctMerkleTree.root; - const hash = correctMerkleTree.at(0); - const proof = otherMerkleTree.getProof(0); - - expect(await this.mock.$processProof(proof, hash)).to.not.equal(root); - expect(await this.mock.$processProofCalldata(proof, hash)).to.not.equal(root); - expect(await this.mock.$verify(proof, root, hash)).to.be.false; - expect(await this.mock.$verifyCalldata(proof, root, hash)).to.be.false; - }); - - it('returns false for a Merkle proof of invalid length', async function () { - const merkleTree = this.makeTree('abc'); - - const root = merkleTree.root; - const hash = merkleTree.at(0); - const proof = merkleTree.getProof(0); - const badProof = proof.slice(0, -1); - - expect(await this.mock.$processProof(badProof, hash)).to.not.equal(root); - expect(await this.mock.$processProofCalldata(badProof, hash)).to.not.equal(root); - expect(await this.mock.$verify(badProof, root, hash)).to.be.false; - expect(await this.mock.$verifyCalldata(badProof, root, hash)).to.be.false; - }); - }); - - describe('multiProofVerify', function () { - it('returns true for a valid Merkle multi proof', async function () { - const merkleTree = this.makeTree('abcdef'); - - const root = merkleTree.root; - const { proof, proofFlags, leaves } = merkleTree.getMultiProof(toLeaves('bdf')); - const hashes = leaves.map(e => merkleTree.leafHash(e)); - - expect(await this.mock.$processMultiProof(proof, proofFlags, hashes)).to.equal(root); - expect(await this.mock.$processMultiProofCalldata(proof, proofFlags, hashes)).to.equal(root); - expect(await this.mock.$multiProofVerify(proof, proofFlags, root, hashes)).to.be.true; - expect(await this.mock.$multiProofVerifyCalldata(proof, proofFlags, root, hashes)).to.be.true; - }); - - it('returns false for an invalid Merkle multi proof', async function () { - const merkleTree = this.makeTree('abcdef'); - const otherMerkleTree = this.makeTree('ghi'); - - const root = merkleTree.root; - const { proof, proofFlags, leaves } = otherMerkleTree.getMultiProof(toLeaves('ghi')); - const hashes = leaves.map(e => merkleTree.leafHash(e)); - - expect(await this.mock.$processMultiProof(proof, proofFlags, hashes)).to.not.equal(root); - expect(await this.mock.$processMultiProofCalldata(proof, proofFlags, hashes)).to.not.equal(root); - expect(await this.mock.$multiProofVerify(proof, proofFlags, root, hashes)).to.be.false; - expect(await this.mock.$multiProofVerifyCalldata(proof, proofFlags, root, hashes)).to.be.false; - }); - - it('revert with invalid multi proof #1', async function () { - const merkleTree = this.makeTree('abcd'); - - const root = merkleTree.root; - const hashA = merkleTree.at(0); - const hashB = merkleTree.at(1); - const hashCD = nodeHash(merkleTree.at(2), merkleTree.at(3)); - const hashE = ethers.randomBytes(32); // incorrect (not part of the tree) - const fill = ethers.randomBytes(32); - - await expect( - this.mock.$processMultiProof([hashB, fill, hashCD], [false, false, false], [hashA, hashE]), - ).to.be.revertedWithCustomError(this.mock, 'MerkleProofInvalidMultiproof'); - - await expect( - this.mock.$processMultiProofCalldata([hashB, fill, hashCD], [false, false, false], [hashA, hashE]), - ).to.be.revertedWithCustomError(this.mock, 'MerkleProofInvalidMultiproof'); - - await expect( - this.mock.$multiProofVerify([hashB, fill, hashCD], [false, false, false], root, [hashA, hashE]), - ).to.be.revertedWithCustomError(this.mock, 'MerkleProofInvalidMultiproof'); - - await expect( - this.mock.$multiProofVerifyCalldata([hashB, fill, hashCD], [false, false, false], root, [hashA, hashE]), - ).to.be.revertedWithCustomError(this.mock, 'MerkleProofInvalidMultiproof'); - }); - - it('revert with invalid multi proof #2', async function () { - const merkleTree = this.makeTree('abcd'); - - const root = merkleTree.root; - const hashA = merkleTree.at(0); - const hashB = merkleTree.at(1); - const hashCD = nodeHash(merkleTree.at(2), merkleTree.at(3)); - const hashE = ethers.randomBytes(32); // incorrect (not part of the tree) - const fill = ethers.randomBytes(32); - - await expect( - this.mock.$processMultiProof([hashB, fill, hashCD], [false, false, false, false], [hashE, hashA]), - ).to.be.revertedWithPanic(PANIC_CODES.ARRAY_ACCESS_OUT_OF_BOUNDS); - - await expect( - this.mock.$processMultiProofCalldata([hashB, fill, hashCD], [false, false, false, false], [hashE, hashA]), - ).to.be.revertedWithPanic(PANIC_CODES.ARRAY_ACCESS_OUT_OF_BOUNDS); - - await expect( - this.mock.$multiProofVerify([hashB, fill, hashCD], [false, false, false, false], root, [hashE, hashA]), - ).to.be.revertedWithPanic(PANIC_CODES.ARRAY_ACCESS_OUT_OF_BOUNDS); - - await expect( - this.mock.$multiProofVerifyCalldata([hashB, fill, hashCD], [false, false, false, false], root, [ - hashE, - hashA, - ]), - ).to.be.revertedWithPanic(PANIC_CODES.ARRAY_ACCESS_OUT_OF_BOUNDS); - }); - - it('limit case: works for tree containing a single leaf', async function () { - const merkleTree = this.makeTree('a'); - - const root = merkleTree.root; - const { proof, proofFlags, leaves } = merkleTree.getMultiProof(toLeaves('a')); - const hashes = leaves.map(e => merkleTree.leafHash(e)); - - expect(await this.mock.$processMultiProof(proof, proofFlags, hashes)).to.equal(root); - expect(await this.mock.$processMultiProofCalldata(proof, proofFlags, hashes)).to.equal(root); - expect(await this.mock.$multiProofVerify(proof, proofFlags, root, hashes)).to.be.true; - expect(await this.mock.$multiProofVerifyCalldata(proof, proofFlags, root, hashes)).to.be.true; - }); - - it('limit case: can prove empty leaves', async function () { - const merkleTree = this.makeTree('abcd'); - - const root = merkleTree.root; - expect(await this.mock.$processMultiProof([root], [], [])).to.equal(root); - expect(await this.mock.$processMultiProofCalldata([root], [], [])).to.equal(root); - expect(await this.mock.$multiProofVerify([root], [], root, [])).to.be.true; - expect(await this.mock.$multiProofVerifyCalldata([root], [], root, [])).to.be.true; - }); - - it('reverts processing manipulated proofs with a zero-value node at depth 1', async function () { - // Create a merkle tree that contains a zero leaf at depth 1 - const leave = ethers.id('real leaf'); - const root = nodeHash(leave, ethers.ZeroHash); - - // Now we can pass any **malicious** fake leaves as valid! - const maliciousLeaves = ['malicious', 'leaves'].map(ethers.id).map(ethers.toBeArray).sort(Buffer.compare); - const maliciousProof = [leave, leave]; - const maliciousProofFlags = [true, true, false]; - - await expect( - this.mock.$processMultiProof(maliciousProof, maliciousProofFlags, maliciousLeaves), - ).to.be.revertedWithCustomError(this.mock, 'MerkleProofInvalidMultiproof'); - - await expect( - this.mock.$processMultiProofCalldata(maliciousProof, maliciousProofFlags, maliciousLeaves), - ).to.be.revertedWithCustomError(this.mock, 'MerkleProofInvalidMultiproof'); - - await expect( - this.mock.$multiProofVerify(maliciousProof, maliciousProofFlags, root, maliciousLeaves), - ).to.be.revertedWithCustomError(this.mock, 'MerkleProofInvalidMultiproof'); - - await expect( - this.mock.$multiProofVerifyCalldata(maliciousProof, maliciousProofFlags, root, maliciousLeaves), - ).to.be.revertedWithCustomError(this.mock, 'MerkleProofInvalidMultiproof'); - }); - }); - }); - } -}); diff --git a/lib/openzeppelin-contracts/test/utils/cryptography/MessageHashUtils.test.js b/lib/openzeppelin-contracts/test/utils/cryptography/MessageHashUtils.test.js deleted file mode 100644 index f20f5a3..0000000 --- a/lib/openzeppelin-contracts/test/utils/cryptography/MessageHashUtils.test.js +++ /dev/null @@ -1,68 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { domainSeparator, hashTypedData } = require('../../helpers/eip712'); - -async function fixture() { - const mock = await ethers.deployContract('$MessageHashUtils'); - return { mock }; -} - -describe('MessageHashUtils', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('toEthSignedMessageHash', function () { - it('prefixes bytes32 data correctly', async function () { - const message = ethers.randomBytes(32); - const expectedHash = ethers.hashMessage(message); - - expect(await this.mock.getFunction('$toEthSignedMessageHash(bytes32)')(message)).to.equal(expectedHash); - }); - - it('prefixes dynamic length data correctly', async function () { - const message = ethers.randomBytes(128); - const expectedHash = ethers.hashMessage(message); - - expect(await this.mock.getFunction('$toEthSignedMessageHash(bytes)')(message)).to.equal(expectedHash); - }); - - it('version match for bytes32', async function () { - const message = ethers.randomBytes(32); - const fixed = await this.mock.getFunction('$toEthSignedMessageHash(bytes32)')(message); - const dynamic = await this.mock.getFunction('$toEthSignedMessageHash(bytes)')(message); - - expect(fixed).to.equal(dynamic); - }); - }); - - describe('toDataWithIntendedValidatorHash', function () { - it('returns the digest correctly', async function () { - const verifier = ethers.Wallet.createRandom().address; - const message = ethers.randomBytes(128); - const expectedHash = ethers.solidityPackedKeccak256( - ['string', 'address', 'bytes'], - ['\x19\x00', verifier, message], - ); - - expect(await this.mock.$toDataWithIntendedValidatorHash(verifier, message)).to.equal(expectedHash); - }); - }); - - describe('toTypedDataHash', function () { - it('returns the digest correctly', async function () { - const domain = { - name: 'Test', - version: '1', - chainId: 1n, - verifyingContract: ethers.Wallet.createRandom().address, - }; - const structhash = ethers.randomBytes(32); - const expectedHash = hashTypedData(domain, structhash); - - expect(await this.mock.$toTypedDataHash(domainSeparator(domain), structhash)).to.equal(expectedHash); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/utils/cryptography/P256.t.sol b/lib/openzeppelin-contracts/test/utils/cryptography/P256.t.sol deleted file mode 100644 index 1391afd..0000000 --- a/lib/openzeppelin-contracts/test/utils/cryptography/P256.t.sol +++ /dev/null @@ -1,135 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {Test} from "forge-std/Test.sol"; - -import {P256} from "@openzeppelin/contracts/utils/cryptography/P256.sol"; -import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; - -contract P256Test is Test { - /// forge-config: default.fuzz.runs = 512 - function testVerify(uint256 seed, bytes32 digest) public { - uint256 privateKey = bound(uint256(keccak256(abi.encode(seed))), 1, P256.N - 1); - - (bytes32 x, bytes32 y) = P256PublicKey.getPublicKey(privateKey); - (bytes32 r, bytes32 s) = vm.signP256(privateKey, digest); - s = _ensureLowerS(s); - assertTrue(P256.verify(digest, r, s, x, y)); - assertTrue(P256.verifySolidity(digest, r, s, x, y)); - } - - /// forge-config: default.fuzz.runs = 512 - function testRecover(uint256 seed, bytes32 digest) public { - uint256 privateKey = bound(uint256(keccak256(abi.encode(seed))), 1, P256.N - 1); - - (bytes32 x, bytes32 y) = P256PublicKey.getPublicKey(privateKey); - (bytes32 r, bytes32 s) = vm.signP256(privateKey, digest); - s = _ensureLowerS(s); - (bytes32 qx0, bytes32 qy0) = P256.recovery(digest, 0, r, s); - (bytes32 qx1, bytes32 qy1) = P256.recovery(digest, 1, r, s); - assertTrue((qx0 == x && qy0 == y) || (qx1 == x && qy1 == y)); - } - - function _ensureLowerS(bytes32 s) private pure returns (bytes32) { - uint256 _s = uint256(s); - unchecked { - return _s > P256.N / 2 ? bytes32(P256.N - _s) : s; - } - } -} - -/** - * @dev Library to derive P256 public key from private key - * Should be removed if Foundry adds this functionality - * See https://github.com/foundry-rs/foundry/issues/7908 - */ -library P256PublicKey { - function getPublicKey(uint256 privateKey) internal view returns (bytes32, bytes32) { - (uint256 x, uint256 y, uint256 z) = _jMult(P256.GX, P256.GY, 1, privateKey); - return _affineFromJacobian(x, y, z); - } - - function _jMult( - uint256 x, - uint256 y, - uint256 z, - uint256 k - ) private pure returns (uint256 rx, uint256 ry, uint256 rz) { - unchecked { - for (uint256 i = 0; i < 256; ++i) { - if (rz > 0) { - (rx, ry, rz) = _jDouble(rx, ry, rz); - } - if (k >> 255 > 0) { - if (rz == 0) { - (rx, ry, rz) = (x, y, z); - } else { - (rx, ry, rz) = _jAdd(rx, ry, rz, x, y, z); - } - } - k <<= 1; - } - } - } - - /// From P256.sol - - function _affineFromJacobian(uint256 jx, uint256 jy, uint256 jz) private view returns (bytes32 ax, bytes32 ay) { - if (jz == 0) return (0, 0); - uint256 zinv = Math.invModPrime(jz, P256.P); - uint256 zzinv = mulmod(zinv, zinv, P256.P); - uint256 zzzinv = mulmod(zzinv, zinv, P256.P); - ax = bytes32(mulmod(jx, zzinv, P256.P)); - ay = bytes32(mulmod(jy, zzzinv, P256.P)); - } - - function _jDouble(uint256 x, uint256 y, uint256 z) private pure returns (uint256 rx, uint256 ry, uint256 rz) { - uint256 p = P256.P; - uint256 a = P256.A; - assembly ("memory-safe") { - let yy := mulmod(y, y, p) - let zz := mulmod(z, z, p) - let s := mulmod(4, mulmod(x, yy, p), p) // s = 4*x*y² - let m := addmod(mulmod(3, mulmod(x, x, p), p), mulmod(a, mulmod(zz, zz, p), p), p) // m = 3*x²+a*z⁴ - let t := addmod(mulmod(m, m, p), sub(p, mulmod(2, s, p)), p) // t = m²-2*s - - // x' = t - rx := t - // y' = m*(s-t)-8*y⁴ - ry := addmod(mulmod(m, addmod(s, sub(p, t), p), p), sub(p, mulmod(8, mulmod(yy, yy, p), p)), p) - // z' = 2*y*z - rz := mulmod(2, mulmod(y, z, p), p) - } - } - - function _jAdd( - uint256 x1, - uint256 y1, - uint256 z1, - uint256 x2, - uint256 y2, - uint256 z2 - ) private pure returns (uint256 rx, uint256 ry, uint256 rz) { - uint256 p = P256.P; - assembly ("memory-safe") { - let zz1 := mulmod(z1, z1, p) // zz1 = z1² - let zz2 := mulmod(z2, z2, p) // zz2 = z2² - let u1 := mulmod(x1, zz2, p) // u1 = x1*z2² - let u2 := mulmod(x2, zz1, p) // u2 = x2*z1² - let s1 := mulmod(y1, mulmod(zz2, z2, p), p) // s1 = y1*z2³ - let s2 := mulmod(y2, mulmod(zz1, z1, p), p) // s2 = y2*z1³ - let h := addmod(u2, sub(p, u1), p) // h = u2-u1 - let hh := mulmod(h, h, p) // h² - let hhh := mulmod(h, hh, p) // h³ - let r := addmod(s2, sub(p, s1), p) // r = s2-s1 - - // x' = r²-h³-2*u1*h² - rx := addmod(addmod(mulmod(r, r, p), sub(p, hhh), p), sub(p, mulmod(2, mulmod(u1, hh, p), p)), p) - // y' = r*(u1*h²-x')-s1*h³ - ry := addmod(mulmod(r, addmod(mulmod(u1, hh, p), sub(p, rx), p), p), sub(p, mulmod(s1, hhh, p)), p) - // z' = h*z1*z2 - rz := mulmod(h, mulmod(z1, z2, p), p) - } - } -} diff --git a/lib/openzeppelin-contracts/test/utils/cryptography/P256.test.js b/lib/openzeppelin-contracts/test/utils/cryptography/P256.test.js deleted file mode 100644 index b9655ca..0000000 --- a/lib/openzeppelin-contracts/test/utils/cryptography/P256.test.js +++ /dev/null @@ -1,156 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { secp256r1 } = require('@noble/curves/p256'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const N = 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551n; - -// As in ECDSA, signatures are malleable and the tooling produce both high and low S values. -// We need to ensure that the s value is in the lower half of the order of the curve. -const ensureLowerOrderS = ({ s, recovery, ...rest }) => { - if (s > N / 2n) { - s = N - s; - recovery = 1 - recovery; - } - return { s, recovery, ...rest }; -}; - -const prepareSignature = ( - privateKey = secp256r1.utils.randomPrivateKey(), - messageHash = ethers.hexlify(ethers.randomBytes(0x20)), -) => { - const publicKey = [ - secp256r1.getPublicKey(privateKey, false).slice(0x01, 0x21), - secp256r1.getPublicKey(privateKey, false).slice(0x21, 0x41), - ].map(ethers.hexlify); - const { r, s, recovery } = ensureLowerOrderS(secp256r1.sign(messageHash.replace(/0x/, ''), privateKey)); - const signature = [r, s].map(v => ethers.toBeHex(v, 0x20)); - - return { privateKey, publicKey, signature, recovery, messageHash }; -}; - -describe('P256', function () { - async function fixture() { - return { mock: await ethers.deployContract('$P256') }; - } - - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('with signature', function () { - beforeEach(async function () { - Object.assign(this, prepareSignature()); - }); - - it('verify valid signature', async function () { - expect(await this.mock.$verify(this.messageHash, ...this.signature, ...this.publicKey)).to.be.true; - expect(await this.mock.$verifySolidity(this.messageHash, ...this.signature, ...this.publicKey)).to.be.true; - await expect(this.mock.$verifyNative(this.messageHash, ...this.signature, ...this.publicKey)) - .to.be.revertedWithCustomError(this.mock, 'MissingPrecompile') - .withArgs('0x0000000000000000000000000000000000000100'); - }); - - it('recover public key', async function () { - expect(await this.mock.$recovery(this.messageHash, this.recovery, ...this.signature)).to.deep.equal( - this.publicKey, - ); - }); - - it('reject signature with flipped public key coordinates ([x,y] >> [y,x])', async function () { - // flip public key - this.publicKey.reverse(); - - expect(await this.mock.$verify(this.messageHash, ...this.signature, ...this.publicKey)).to.be.false; - expect(await this.mock.$verifySolidity(this.messageHash, ...this.signature, ...this.publicKey)).to.be.false; - expect(await this.mock.$verifyNative(this.messageHash, ...this.signature, ...this.publicKey)).to.be.false; // Flipped public key is not in the curve - }); - - it('reject signature with flipped signature values ([r,s] >> [s,r])', async function () { - // Preselected signature where `r < N/2` and `s < N/2` - this.signature = [ - '0x45350225bad31e89db662fcc4fb2f79f349adbb952b3f652eed1f2aa72fb0356', - '0x513eb68424c42630012309eee4a3b43e0bdc019d179ef0e0c461800845e237ee', - ]; - - // Corresponding hash and public key - this.messageHash = '0x2ad1f900fe63745deeaedfdf396cb6f0f991c4338a9edf114d52f7d1812040a0'; - this.publicKey = [ - '0x9e30de165e521257996425d9bf12a7d366925614bf204eabbb78172b48e52e59', - '0x94bf0fe72f99654d7beae4780a520848e306d46a1275b965c4f4c2b8e9a2c08d', - ]; - - // Make sure it works - expect(await this.mock.$verify(this.messageHash, ...this.signature, ...this.publicKey)).to.be.true; - - // Flip signature - this.signature.reverse(); - - expect(await this.mock.$verify(this.messageHash, ...this.signature, ...this.publicKey)).to.be.false; - expect(await this.mock.$verifySolidity(this.messageHash, ...this.signature, ...this.publicKey)).to.be.false; - await expect(this.mock.$verifyNative(this.messageHash, ...this.signature, ...this.publicKey)) - .to.be.revertedWithCustomError(this.mock, 'MissingPrecompile') - .withArgs('0x0000000000000000000000000000000000000100'); - expect(await this.mock.$recovery(this.messageHash, this.recovery, ...this.signature)).to.not.deep.equal( - this.publicKey, - ); - }); - - it('reject signature with invalid message hash', async function () { - // random message hash - this.messageHash = ethers.hexlify(ethers.randomBytes(32)); - - expect(await this.mock.$verify(this.messageHash, ...this.signature, ...this.publicKey)).to.be.false; - expect(await this.mock.$verifySolidity(this.messageHash, ...this.signature, ...this.publicKey)).to.be.false; - await expect(this.mock.$verifyNative(this.messageHash, ...this.signature, ...this.publicKey)) - .to.be.revertedWithCustomError(this.mock, 'MissingPrecompile') - .withArgs('0x0000000000000000000000000000000000000100'); - expect(await this.mock.$recovery(this.messageHash, this.recovery, ...this.signature)).to.not.deep.equal( - this.publicKey, - ); - }); - - it('fail to recover signature with invalid recovery bit', async function () { - // flip recovery bit - this.recovery = 1 - this.recovery; - - expect(await this.mock.$recovery(this.messageHash, this.recovery, ...this.signature)).to.not.deep.equal( - this.publicKey, - ); - }); - }); - - // test cases for https://github.com/C2SP/wycheproof/blob/4672ff74d68766e7785c2cac4c597effccef2c5c/testvectors/ecdsa_secp256r1_sha256_p1363_test.json - describe('wycheproof tests', function () { - for (const { key, tests } of require('./ecdsa_secp256r1_sha256_p1363_test.json').testGroups) { - // parse public key - let [x, y] = [key.wx, key.wy].map(v => ethers.stripZerosLeft('0x' + v, 32)); - if (x.length > 66 || y.length > 66) continue; - x = ethers.zeroPadValue(x, 32); - y = ethers.zeroPadValue(y, 32); - - // run all tests for this key - for (const { tcId, comment, msg, sig, result } of tests) { - // only keep properly formatted signatures - if (sig.length != 128) continue; - - it(`${tcId}: ${comment}`, async function () { - // split signature, and reduce modulo N - let [r, s] = Array(2) - .fill() - .map((_, i) => ethers.toBigInt('0x' + sig.substring(64 * i, 64 * (i + 1)))); - // move s to lower part of the curve if needed - if (s <= N && s > N / 2n) s = N - s; - // prepare signature - r = ethers.toBeHex(r, 32); - s = ethers.toBeHex(s, 32); - // hash - const messageHash = ethers.sha256('0x' + msg); - - // check verify - expect(await this.mock.$verify(messageHash, r, s, x, y)).to.equal(result == 'valid'); - }); - } - } - }); -}); diff --git a/lib/openzeppelin-contracts/test/utils/cryptography/RSA.helper.js b/lib/openzeppelin-contracts/test/utils/cryptography/RSA.helper.js deleted file mode 100644 index 48c8ee4..0000000 --- a/lib/openzeppelin-contracts/test/utils/cryptography/RSA.helper.js +++ /dev/null @@ -1,17 +0,0 @@ -const path = require('path'); -const fs = require('fs'); - -module.exports = function* parse(file) { - const cache = {}; - const data = fs.readFileSync(path.resolve(__dirname, file), 'utf8'); - for (const line of data.split('\r\n')) { - const groups = line.match(/^(?\w+) = (?\w+)(?.*)$/)?.groups; - if (groups) { - const { key, value, extra } = groups; - cache[key] = value; - if (groups.key === 'Result') { - yield Object.assign({ extra: extra.trim() }, cache); - } - } - } -}; diff --git a/lib/openzeppelin-contracts/test/utils/cryptography/RSA.test.js b/lib/openzeppelin-contracts/test/utils/cryptography/RSA.test.js deleted file mode 100644 index d717811..0000000 --- a/lib/openzeppelin-contracts/test/utils/cryptography/RSA.test.js +++ /dev/null @@ -1,97 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const parse = require('./RSA.helper'); - -async function fixture() { - return { mock: await ethers.deployContract('$RSA') }; -} - -describe('RSA', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - // Load test cases from file SigVer15_186-3.rsp from: - // https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/dss/186-2rsatestvectors.zip - describe('SigVer15_186-3.rsp tests', function () { - for (const test of parse('SigVer15_186-3.rsp')) { - const { length } = Buffer.from(test.S, 'hex'); - - /// For now, RSA only supports digest that are 32bytes long. If we ever extend that, we can use these hashing functions for @noble: - // const { sha1 } = require('@noble/hashes/sha1'); - // const { sha224, sha256 } = require('@noble/hashes/sha256'); - // const { sha384, sha512 } = require('@noble/hashes/sha512'); - - if (test.SHAAlg === 'SHA256') { - const result = test.Result === 'P'; - - it(`signature length ${length} ${test.extra} ${result ? 'works' : 'fails'}`, async function () { - const data = '0x' + test.Msg; - const sig = '0x' + test.S; - const exp = '0x' + test.e; - const mod = '0x' + test.n; - - expect(await this.mock.$pkcs1(ethers.sha256(data), sig, exp, mod)).to.equal(result); - expect(await this.mock.$pkcs1Sha256(data, sig, exp, mod)).to.equal(result); - }); - } - } - }); - - describe('others tests', function () { - it('openssl', async function () { - const data = ethers.toUtf8Bytes('hello world'); - const sig = - '0x079bed733b48d69bdb03076cb17d9809072a5a765460bc72072d687dba492afe951d75b814f561f253ee5cc0f3d703b6eab5b5df635b03a5437c0a5c179309812f5b5c97650361c645bc99f806054de21eb187bc0a704ed38d3d4c2871a117c19b6da7e9a3d808481c46b22652d15b899ad3792da5419e50ee38759560002388'; - const exp = - '0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001'; - const mod = - '0xdf3edde009b96bc5b03b48bd73fe70a3ad20eaf624d0dc1ba121a45cc739893741b7cf82acf1c91573ec8266538997c6699760148de57e54983191eca0176f518e547b85fe0bb7d9e150df19eee734cf5338219c7f8f7b13b39f5384179f62c135e544cb70be7505751f34568e06981095aeec4f3a887639718a3e11d48c240d'; - expect(await this.mock.$pkcs1Sha256(data, sig, exp, mod)).to.be.true; - }); - - // According to RFC4055, pg.5 and RFC8017, pg. 64, for SHA-1, and the SHA-2 family, - // the algorithm parameter has to be NULL and both explicit NULL parameter and implicit - // NULL parameter (ie, absent NULL parameter) are considered to be legal and equivalent. - it('rfc8017 implicit null parameter', async function () { - const data = ethers.toUtf8Bytes('hello world!'); - const sig = - '0xa0073057133ff3758e7e111b4d7441f1d8cbe4b2dd5ee4316a14264290dee5ed7f175716639bd9bb43a14e4f9fcb9e84dedd35e2205caac04828b2c053f68176d971ea88534dd2eeec903043c3469fc69c206b2a8694fd262488441ed8852280c3d4994e9d42bd1d575c7024095f1a20665925c2175e089c0d731471f6cc145404edf5559fd2276e45e448086f71c78d0cc6628fad394a34e51e8c10bc39bfe09ed2f5f742cc68bee899d0a41e4c75b7b80afd1c321d89ccd9fe8197c44624d91cc935dfa48de3c201099b5b417be748aef29248527e8bbb173cab76b48478d4177b338fe1f1244e64d7d23f07add560d5ad50b68d6649a49d7bc3db686daaa7'; - const exp = '0x03'; - const mod = - '0xe932ac92252f585b3a80a4dd76a897c8b7652952fe788f6ec8dd640587a1ee5647670a8ad4c2be0f9fa6e49c605adf77b5174230af7bd50e5d6d6d6d28ccf0a886a514cc72e51d209cc772a52ef419f6a953f3135929588ebe9b351fca61ced78f346fe00dbb6306e5c2a4c6dfc3779af85ab417371cf34d8387b9b30ae46d7a5ff5a655b8d8455f1b94ae736989d60a6f2fd5cadbffbd504c5a756a2e6bb5cecc13bca7503f6df8b52ace5c410997e98809db4dc30d943de4e812a47553dce54844a78e36401d13f77dc650619fed88d8b3926e3d8e319c80c744779ac5d6abe252896950917476ece5e8fc27d5f053d6018d91b502c4787558a002b9283da7'; - expect(await this.mock.$pkcs1Sha256(data, sig, exp, mod)).to.be.true; - }); - - it('returns false for a very short n', async function () { - const data = ethers.toUtf8Bytes('hello world!'); - const sig = '0x0102'; - const exp = '0x03'; - const mod = '0x0405'; - expect(await this.mock.$pkcs1Sha256(data, sig, exp, mod)).to.be.false; - }); - - it('returns false for a signature with different length to n', async function () { - const data = ethers.toUtf8Bytes('hello world!'); - const sig = '0x00112233'; - const exp = '0x03'; - const mod = - '0xe932ac92252f585b3a80a4dd76a897c8b7652952fe788f6ec8dd640587a1ee5647670a8ad4c2be0f9fa6e49c605adf77b5174230af7bd50e5d6d6d6d28ccf0a886a514cc72e51d209cc772a52ef419f6a953f3135929588ebe9b351fca61ced78f346fe00dbb6306e5c2a4c6dfc3779af85ab417371cf34d8387b9b30ae46d7a5ff5a655b8d8455f1b94ae736989d60a6f2fd5cadbffbd504c5a756a2e6bb5cecc13bca7503f6df8b52ace5c410997e98809db4dc30d943de4e812a47553dce54844a78e36401d13f77dc650619fed88d8b3926e3d8e319c80c744779ac5d6abe252896950917476ece5e8fc27d5f053d6018d91b502c4787558a002b9283da7'; - expect(await this.mock.$pkcs1Sha256(data, sig, exp, mod)).to.be.false; - }); - - it('returns false if s >= n', async function () { - // this is the openssl example where sig has been replaced by sig + mod - const data = ethers.toUtf8Bytes('hello world'); - const sig = - '0xe6dacb53450242618b3e502a257c08acb44b456c7931988da84f0cda8182b435d6d5453ac1e72b07c7dadf2747609b7d544d15f3f14081f9dbad9c48b7aa78d2bdafd81d630f19a0270d7911f4ec82b171e9a95889ffc9e740dc9fac89407a82d152ecb514967d4d9165e67ce0d7f39a3082657cdfca148a5fc2b3a7348c4795'; - const exp = - '0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001'; - const mod = - '0xdf3edde009b96bc5b03b48bd73fe70a3ad20eaf624d0dc1ba121a45cc739893741b7cf82acf1c91573ec8266538997c6699760148de57e54983191eca0176f518e547b85fe0bb7d9e150df19eee734cf5338219c7f8f7b13b39f5384179f62c135e544cb70be7505751f34568e06981095aeec4f3a887639718a3e11d48c240d'; - expect(await this.mock.$pkcs1Sha256(data, sig, exp, mod)).to.be.false; - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/utils/cryptography/SigVer15_186-3.rsp b/lib/openzeppelin-contracts/test/utils/cryptography/SigVer15_186-3.rsp deleted file mode 100644 index 275be61..0000000 --- a/lib/openzeppelin-contracts/test/utils/cryptography/SigVer15_186-3.rsp +++ /dev/null @@ -1,3850 +0,0 @@ -# CAVS 11.0 -# "SigVer PKCS#1 Ver 1.5" information -# Mod sizes selected: 1024 1536 2048 3072 4096 -# SHA Algorithm selected:SHA1 SHA224 SHA256 SHA384 SHA512 -# Generated on Wed Mar 02 00:13:02 2011 - -[mod = 1024] - -n = a8d68acd413c5e195d5ef04e1b4faaf242365cb450196755e92e1215ba59802aafbadbf2564dd550956abb54f8b1c917844e5f36195d1088c600e07cada5c080ede679f50b3de32cf4026e514542495c54b1903768791aae9e36f082cd38e941ada89baecada61ab0dd37ad536bcb0a0946271594836e92ab5517301d45176b5 - -p = c107a2fe924b76e206cb9bc4af2ab7008547c00846bf6d0680b3eac3ebcbd0c7fd7a54c2b9899b08f80cde1d3691eaaa2816b1eb11822d6be7beaf4e30977c49 -q = dfea984ce4307eafc0d140c2bb82861e5dbac4f8567cbc981d70440dd639492079031486315e305eb83e591c4a2e96064966f7c894c3ca351925b5ce82d8ef0d - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = ff23e00f819bae424e41d6b762ea6b88801e651c831c964af31de0c1d6dda4a7c8587d804ed12f526819da06650e7412fb627555979ed442f2663341e5fe57527e0ddaf453a124451674976a6a6e0a31f56a79f5b73dfac39af4f3ba4a5e8bb846cb5e333812756482d975ab1910162f96bfd7c58a02f113125189f5ac05291f -S = a3877b854832d6a6dec749a908e8bd3a73b24372e80321ed01c19ce066117d8efe78ef7168af8acd139e47dd262c0c92ed1701cf6c07e0c1140f82040167f55bb5180c18ad9e66a18dacf0742c1f05173129ed5ac523faeeb2119639cd30ae5a435884b55043d4fb7fa9af0dd92c365386044c2e8bcd196b3787bfede47fff37 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = a6ce108ff3100b953781496c3d081fe32b8cedaf6d14aab2ef2dc37d8f8d2613d2f599efd55c51498749c0961681ae4ea7e28bf14a8f044c2d4dd4f9102ddd25f86c7795289708eb4df2d526f91b176952eb52fd0c9de2989432d6e08e13022b82f95089d20a5704f0452f26cd1f83bc956ee7da99876c1f8da3723af388bead -S = a5aa479d792448cc3e2ddfbe444017eea54efca7101651f4616f0260c7a48a364fe459abf98352e86b0b3d1478208687dffde1380d4462fce68cd61895401c3791186f17f159b91c02b5c0a30e894e142657b7537e84d2574837256da6940aa14cded7fbcba24b9e12ed2bb7e3f6db69b5a02807b57c9aa10ad9c0e1bde9443a -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = 9edf5246ae1d8fe800bc2ed422e6441cedde94c85a870277972a4b4a5a74f4fd76be8057ac92e6c5c36a4242dabacb79fe31052ef83c38da68cd2095185ae6398a284fc5d3c934fface4325ec734a2265fd3cbd513b957bef47f04f4dd699c6903a42757cccc5fdfe5b264f18f5bb16b394c4f855404486c63cb5f2d51aafed5 -S = 9a2e5b3ce63cb8df79f3cb25cce6964527e38592c58ba8b7b9312da25c62940985e93e62689f34b60cd019d3d472c0b72fcf2666bfcf8c13407e2150a138caaabaa409e6fd1ea55faf9180f7b41ed53d47c4dcdc3c669928d8a1c161f91918593dc3be3892c8df763d1a5ee6bcd5801866683005d89a2fd6ed3bef581833d922 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = d73829497cddbe41b705faac50e7899fdb5a38bf3a459e536357029e64f8796ba47f4fe96ba5a8b9a4396746e2164f55a25368ddd0b9a5188c7ac3da2d1f742286c3bdee697f9d546a25efcfe53191d743fcc6b47833d993d08804daeca78fb9076c3c017f53e33a90305af06220974d46bf19ed3c9b84edbae98b45a8771258 -S = 175015bda50abe0fa7d39a8353885ca01be3a7e7fcc55045744111362ee1914473a48dc537d956294b9e20a1ef661d58537acdc8de908fa050630fcc272e6d001045e6fdeed2d10531c8603334c2e8db39e73e6d9665ee1343f9e4198302d2201b44e8e8d06b3ef49cee6197582163a8490089ca654c0012fce1ba6511089750 -SaltVal = 00 -Result = P - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = a4397d9ab677aaa13a68a09de9ae0ed4045d479aa0ff3a7242dca477ab7884faf55cd06ddf19667f668b4589955bfd299dc7642c28a68bb2eba6f08c7ad9f5e96170913270c6463256a0537a72b32a04e5662416ecda74696d275a8bcfe999820ffc2ab210833201332f323828be7dac04c1f01f93a3dde1efe7483a51b1560d -S = 417aa0531b1da975066a1311a9bf2fa73f5daf90f0473a8937a27a9c6378c53012e0b4db3dcb5309b85a3e7f9db161848465f2e8102f75d171b4dc5371c3dca0bd70626dff5fad68549477fea84db9ac1b405440e178f5d9f74f3935e78a6aaf774b86d509fb25bd1a93aac9a2cdbce6a897842ea3ae07d3c8b4c43f97e0bf75 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003021300906052b0e03021a05000414dd1e335f65b2f5e31562a2c74ea6eab09892febcefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = e4690fb08396a8bf07377778a447dbd14c771024bd2353cbbd8446eda42795971c9eda0f2575be655c68614a7cd2fd252569c664dc291410548ec3a5eb06da2078a66c59441cbc9356e5a452f4c0386d6662a663fd6b61f254997ee6d63b5e3080e98d37e873ea737f17083713f7d5ce98ca79ca27d18199470c3d596caf66ed -S = 56b25cc46a9ef9607f4f0f553265996e22a4552fc6cb2752d0595e887afad29f7f9a390c17dc427c7d9f83f19f6986c60ec6d8f8017c3419cc2a838fe2425c7c80ceebfa1a0a3de507b5601609fe54b871efde685d23e546d69fbd14a30ebc2e67ac99446ae4978f1b3c120103294318b253aa9fcee638907b84ac72b25e18fa -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443021300906052b0e03021a050004148031ffbcbd668626dcc49e40128d8abdab1e8172 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = ff23e00f819bae424e41d6b762ea6b88801e651c831c964af31de0c1d6dda4a7c8587d804ed12f526819da06650e7412fb627555979ed442f2663341e5fe57527e0ddaf453a124451674976a6a6e0a31f56a79f5b73dfac39af4f3ba4a5e8bb846cb5e333812756482d975ab1910162f96bfd7c58a02f113125189f5ac05291f -S = 30db68c610b9086e9c6273da708ff8a89d73dfba6e2564aec908292af3a52b84ddd28bbb7c4a39df02f6e992be0d9aa8edb320a6e5a0a001ad097e7b8d09a87f50d55e1d68f47d2215a892221e7e33ddfe181b58fb12c8703e60cf0248c62af8a99111befd96b45ed4cf441a0623b013b94d3dd0976f6b5db7ae595069f21ea5 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = a6ce108ff3100b953781496c3d081fe32b8cedaf6d14aab2ef2dc37d8f8d2613d2f599efd55c51498749c0961681ae4ea7e28bf14a8f044c2d4dd4f9102ddd25f86c7795289708eb4df2d526f91b176952eb52fd0c9de2989432d6e08e13022b82f95089d20a5704f0452f26cd1f83bc956ee7da99876c1f8da3723af388bead -S = 8ed880d91764fdadb04470e04509c6b800fe2bdb1cdb17071f855b8e38b3075c3b8a6991a34ab869127f47a753d7610c79e86a7a288b653326e31d90f4d043f52b7656b6831f6806119df6309a7846b05cb2630c28f7464a7b96e4e8ce76e9cd45502bd5e928f268763fea50271d29b7527097c51ebc2b2a3a83cf22e6b7e3fa -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = 9edf5246ae1d8fe800bc2ed422e6441cedde94c85a870277972a4b4a5a74f4fd76be8057ac92e6c5c36a4242dabacb79fe31052ef83c38da68cd2095185ae6398a284fc5d3c934fface4325ec734a2265fd3cbd513b957bef47f04f4dd699c6903a42757cccc5fdfe5b264f18f5bb16b394c4f855404486c63cb5f2d51aafed5 -S = 4a1716c989580f11bad633a8566b0f44ea689d8bc27c489bbf1a01d76bfa08ce87cace576ade53a5399addee803666fa1d99fa3739c556ae513baa10415e3db820e45f7518e15c7b1875f18f3835792e7ffaed1e7cf9c592afd660d2dda77e00f8f6cf298978929ca017cfce2675afaceca959810a4a33666be9a9a1b2f6523e -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = d73829497cddbe41b705faac50e7899fdb5a38bf3a459e536357029e64f8796ba47f4fe96ba5a8b9a4396746e2164f55a25368ddd0b9a5188c7ac3da2d1f742286c3bdee697f9d546a25efcfe53191d743fcc6b47833d993d08804daeca78fb9076c3c017f53e33a90305af06220974d46bf19ed3c9b84edbae98b45a8771258 -S = 57677b089e205486df4f56755972e3af88cabbc23efe29439b8d1e60ac226e990da487857392856d12cdcea387a269d1bbbc128549a1135ab062201cab8ac08886a313af8554506d7a93855b843086a1bf3dfbcb004ccde779c084ffa1724b41d17e10c8dd67dc0df26200376550eda14455d9b0b31f1d8c5e8bb1d3d963d0d5 -SaltVal = 00 -Result = P - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = a4397d9ab677aaa13a68a09de9ae0ed4045d479aa0ff3a7242dca477ab7884faf55cd06ddf19667f668b4589955bfd299dc7642c28a68bb2eba6f08c7ad9f5e96170913270c6463256a0537a72b32a04e5662416ecda74696d275a8bcfe999820ffc2ab210833201332f323828be7dac04c1f01f93a3dde1efe7483a51b1560d -S = 9b2222986b3f97dbdfd7aafd35fba51df5a7b76c88237e7454f2561b542289b424c76ba934e30b00e7726116ddadc359d6ad8b7ed7c16533c5661f2a61c45ec2e590e058663a740c0842e036d59f223d3c87a8127d40024ae205e46e3cd0fa323e01668da8bd723cc17e539a028a5ea69cb1fd9150db571a451ada2d81e05377 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffff00302d300d06096086480165030402040500041c472fcfddd47f6ba3bb9eb166c248320d9b39fb4b2f70b65a85615244efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = e4690fb08396a8bf07377778a447dbd14c771024bd2353cbbd8446eda42795971c9eda0f2575be655c68614a7cd2fd252569c664dc291410548ec3a5eb06da2078a66c59441cbc9356e5a452f4c0386d6662a663fd6b61f254997ee6d63b5e3080e98d37e873ea737f17083713f7d5ce98ca79ca27d18199470c3d596caf66ed -S = 7016e23d4fc070a479f4a9c173de8f1dc3a54183ab44af9e3cfda7a229bed269712f5697fdd485f03ea21183f563ee0b5a91d3478c5cc94cf6fb56c0102a7098cbe06a8a5ae6a0eef7722ef9514c80e5944c8b1412b1411d56c7b674650eafca7433ac8b9266363a049f3be30885e30fee049e50ddd76816db309ed59f9b469b -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff44302d300d06096086480165030402040500041ca73d80b7f5f188724498120a21df3683351f77de5eb916058f9769d8 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = ff23e00f819bae424e41d6b762ea6b88801e651c831c964af31de0c1d6dda4a7c8587d804ed12f526819da06650e7412fb627555979ed442f2663341e5fe57527e0ddaf453a124451674976a6a6e0a31f56a79f5b73dfac39af4f3ba4a5e8bb846cb5e333812756482d975ab1910162f96bfd7c58a02f113125189f5ac05291f -S = 10ecd0085694f8db6ea62dab2f239d8a93fcf449102f1368c67de329d79692b677500f55994c9722e2633063fc7d8c2c50ae8857d45c08bfaba9448dda0689c2a08605d47a7694beaacbdad1a954458a87fd78b6519393013b20996d636b755323b4b2b2b6d06a46c9221cd200462428ab5bef0f9743e144191f6928562627a7 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = a6ce108ff3100b953781496c3d081fe32b8cedaf6d14aab2ef2dc37d8f8d2613d2f599efd55c51498749c0961681ae4ea7e28bf14a8f044c2d4dd4f9102ddd25f86c7795289708eb4df2d526f91b176952eb52fd0c9de2989432d6e08e13022b82f95089d20a5704f0452f26cd1f83bc956ee7da99876c1f8da3723af388bead -S = 488d328861653ab0a769a11a158ec7b479b62db5b253eda899beae580afb9a7c762030262b8a066f085185475e17870700504d3f78fcc4bcb95a3c1648796a323613a7b706cb64b048c68c06b396aac20b52f22f3fdce40992fb9a5ef68b5725134d83035a6f091d01aa5947175885822b2d4618c3f3fdbfd8819847fe40112b -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = 9edf5246ae1d8fe800bc2ed422e6441cedde94c85a870277972a4b4a5a74f4fd76be8057ac92e6c5c36a4242dabacb79fe31052ef83c38da68cd2095185ae6398a284fc5d3c934fface4325ec734a2265fd3cbd513b957bef47f04f4dd699c6903a42757cccc5fdfe5b264f18f5bb16b394c4f855404486c63cb5f2d51aafed5 -S = 7c547b350710337c783e7406935fb8ac7bcd1cdd4a7bcaeb63422067d1239f9f59fc29b51993a29d6ac8dcc7980871bbba1be8f0b6ce951a9e0cad64b37d7d0c3734e038efcd4e3499c8855f7c52ea3323ba4876ba9d78a98e7e5cf72b4b7444228dd0d81283e59055873450b8bc411d1cb970efda5cf5947a1d1f17e92a4639 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = d73829497cddbe41b705faac50e7899fdb5a38bf3a459e536357029e64f8796ba47f4fe96ba5a8b9a4396746e2164f55a25368ddd0b9a5188c7ac3da2d1f742286c3bdee697f9d546a25efcfe53191d743fcc6b47833d993d08804daeca78fb9076c3c017f53e33a90305af06220974d46bf19ed3c9b84edbae98b45a8771258 -S = 0b20e5093c2a926233108afbdd851b88eeb554f4beaa7b18e51519f7d0ec53b181a3b03e8484ba8de2aa7864a402e2208e84ec9914af9d776ed13c48bdeb6484254de169318a87c40f2265ff16714eae8aee2bc9c3cb4dee045e4f5d9d625210121bfcf2bed8d3ffa602ce27fff4e61cf9bb650e71a6921ae6ffa296cb11bdbb -SaltVal = 00 -Result = P - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = a4397d9ab677aaa13a68a09de9ae0ed4045d479aa0ff3a7242dca477ab7884faf55cd06ddf19667f668b4589955bfd299dc7642c28a68bb2eba6f08c7ad9f5e96170913270c6463256a0537a72b32a04e5662416ecda74696d275a8bcfe999820ffc2ab210833201332f323828be7dac04c1f01f93a3dde1efe7483a51b1560d -S = 9313380722659eeccf8be943fbf514e90fb19657dfb410a50bdfc0cfb058a58e56bbae71ea1a30ecee08ca5d31a2d0bcd3f5a967a3794259c03635ee24cf2a15303ddb5962ae9747d72e83f630580600ba64d24bc4014c5d44640b2369b45fb09c2ba20721e0ae27d1a32546afa1bd023aa61079cea65389f55c31cfedb460b3 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003031300d060960864801650304020105000420fa98b3853b928263002bcb39b454ea21f3f62bcaf6bc2b616490b7a7160120d7efefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = e4690fb08396a8bf07377778a447dbd14c771024bd2353cbbd8446eda42795971c9eda0f2575be655c68614a7cd2fd252569c664dc291410548ec3a5eb06da2078a66c59441cbc9356e5a452f4c0386d6662a663fd6b61f254997ee6d63b5e3080e98d37e873ea737f17083713f7d5ce98ca79ca27d18199470c3d596caf66ed -S = 477a7d6ff281bee7d56ac9cdc7f041b7497483f07a3cea5667ff178233219f75da7b88d9fc854a22ef541af3a5be8fb30b4e50bcb6d130e11f6c18eadec5d10f9895d654c0947aad152ba395c1039d7a8ff41b829179984a513f1abeb5a748bf248af1ea0152093d9fafb5d18e4cf91bd3b57ddd18b6984d976e6bef58cb30ec -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443031300d06096086480165030402010500042034c9d0b0b487446c903244e640affe835096c7ada2e4295090bd9386884df006 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = ff23e00f819bae424e41d6b762ea6b88801e651c831c964af31de0c1d6dda4a7c8587d804ed12f526819da06650e7412fb627555979ed442f2663341e5fe57527e0ddaf453a124451674976a6a6e0a31f56a79f5b73dfac39af4f3ba4a5e8bb846cb5e333812756482d975ab1910162f96bfd7c58a02f113125189f5ac05291f -S = 5ad712eea6e12cf093b8aaa41bd972bd92ea43442dfae0671b27b80d821fdf8a83b032b870e2aa618430ab207ccb1c86bc5e74ea44a0f1ba2cfa2fca003e8547eedc4fd748e7718a9dc39c032b9bb997b4c01f49e441ddcb134d9b2c28a3dcbf126de439f07cb58aece617573797d939957083e51fe5eec00deaae17c41f59ed -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = a6ce108ff3100b953781496c3d081fe32b8cedaf6d14aab2ef2dc37d8f8d2613d2f599efd55c51498749c0961681ae4ea7e28bf14a8f044c2d4dd4f9102ddd25f86c7795289708eb4df2d526f91b176952eb52fd0c9de2989432d6e08e13022b82f95089d20a5704f0452f26cd1f83bc956ee7da99876c1f8da3723af388bead -S = 1f00ccb2e22d0355b20b79b3d3c2416c03d281673fa3314aeec0cb41373e9a8ad5441e93545b6ceb9d3b8d660709cc2b8cff61924768fcf5b0d0ac771a395c02797123f503866d2aee5bb03c651091388486f63793bd714485ead5e03b92c9d80668c2088866b14361d2eb5eb838f903994d84471d5a352366eff2c5cbdf1ab6 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = 9edf5246ae1d8fe800bc2ed422e6441cedde94c85a870277972a4b4a5a74f4fd76be8057ac92e6c5c36a4242dabacb79fe31052ef83c38da68cd2095185ae6398a284fc5d3c934fface4325ec734a2265fd3cbd513b957bef47f04f4dd699c6903a42757cccc5fdfe5b264f18f5bb16b394c4f855404486c63cb5f2d51aafed5 -S = 52edcc1c2bd6eecfda613f0ed8cc8ed5d0f0b881b5a05eca36d9fbb3d04a9f36f0fa916008d13ae8b17b8f6d97ac4450d892b2731f14a477032cd353b8c054d53a3b2932124fd8d1bac88b44e4fd6f37b8ec3575b290fad24a262011b45f7e9b96b09324901f1d153921e13f7246ffdce405018c20975dcd28a7fe55689bdd9f -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = d73829497cddbe41b705faac50e7899fdb5a38bf3a459e536357029e64f8796ba47f4fe96ba5a8b9a4396746e2164f55a25368ddd0b9a5188c7ac3da2d1f742286c3bdee697f9d546a25efcfe53191d743fcc6b47833d993d08804daeca78fb9076c3c017f53e33a90305af06220974d46bf19ed3c9b84edbae98b45a8771258 -S = 7e3ccb6ab03b419a3e54f81337a3c3f72e8c65bbd19ddd50246a36f51f58741ec245d2d0f07677a4f88aa3b1caeecdffe5fd6edcf8b8bcfb569637ad02eb154d17b87a8f00d0e618a7f4a70ce407f20359153e5f4a4d9744f3f3ff44120c08a460500f030fd3398e97fcaef9d0a7e2acef19a81f706805be5fc003d78e5b29c0 -SaltVal = 00 -Result = P - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = a4397d9ab677aaa13a68a09de9ae0ed4045d479aa0ff3a7242dca477ab7884faf55cd06ddf19667f668b4589955bfd299dc7642c28a68bb2eba6f08c7ad9f5e96170913270c6463256a0537a72b32a04e5662416ecda74696d275a8bcfe999820ffc2ab210833201332f323828be7dac04c1f01f93a3dde1efe7483a51b1560d -S = 1077cf5852f21c7986f30bc2bb382138e93c0670315a83799047e122b7804cb8cdc892f23c8297b8315c16c351f0c6138cecb630a51b8a0980eeb59d575b3d86c52ae9270c6f444143d22ad6a1eea05a886281c9d7c93f0d3ab2528bb72e99b2afbf74f04038c3e17743e286a409304e4c19d441a68142b0d7b3c0a6da5532bd -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003041300d0609608648016503040202050004301cdb4de69f4d84845bef51cd666020a895fbea98f2f61c9554ebdcffa525877093cbc9a4b1b8efeb77980d73ca54de17efef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = e4690fb08396a8bf07377778a447dbd14c771024bd2353cbbd8446eda42795971c9eda0f2575be655c68614a7cd2fd252569c664dc291410548ec3a5eb06da2078a66c59441cbc9356e5a452f4c0386d6662a663fd6b61f254997ee6d63b5e3080e98d37e873ea737f17083713f7d5ce98ca79ca27d18199470c3d596caf66ed -S = 63c488bdf2f7de4cd048c535b481a4cc2898e3810eda0038b2283bfe9b3f2beba2a74268639ecfc05170d1af534ced5d3b4941d1aad317875e05d6a19f734625721ed1f262faf995feb1acb44ba76beaec957aa8023429865717d0abfc553cb67474034344ceb8c5d4bddff7fa230ac620e5e665006dffb1c4cc7995c73841f9 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443041300d060960864801650304020205000430cf563bb8f42149df04c9bf20652986e8888907d2ff11f086bb1b6152abd4e945ad82dda241cfbf511a88b36a5a450dcc -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = ff23e00f819bae424e41d6b762ea6b88801e651c831c964af31de0c1d6dda4a7c8587d804ed12f526819da06650e7412fb627555979ed442f2663341e5fe57527e0ddaf453a124451674976a6a6e0a31f56a79f5b73dfac39af4f3ba4a5e8bb846cb5e333812756482d975ab1910162f96bfd7c58a02f113125189f5ac05291f -S = 48db9934d51e8c2e234d70ff665bf2de4fef620e23f27550254a0b4b18338e299c024c4ffc5a502945e9f2e091a86ff6e7f44059f1ca58b4a18bc15931ae1176a9775247039e57d4e322f3d77fed6c6e9bec26b066fe565384c42d2ac79dd8312c8e09d3a2bf85fba0648a02f0e958d4711396e42362c5558eb7227b12aa94d7 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = a6ce108ff3100b953781496c3d081fe32b8cedaf6d14aab2ef2dc37d8f8d2613d2f599efd55c51498749c0961681ae4ea7e28bf14a8f044c2d4dd4f9102ddd25f86c7795289708eb4df2d526f91b176952eb52fd0c9de2989432d6e08e13022b82f95089d20a5704f0452f26cd1f83bc956ee7da99876c1f8da3723af388bead -S = 125b4dddf5e18c8de2f7b72faa76f1d03dd88aac3c76ebc037b4b1aa1435eda6bef2c948e2ba51e763b8572f4ecef228ca38c10299add6f3f67c171a8fd56e33a1c287c49f844e4e98b20f0fe727b58515e5e7d3846c029afe08d25a9edf0dda6677b1cb2ca6be67763171f114932c43f53af126d0aab6dcb52d5b320b385c6d -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = 9edf5246ae1d8fe800bc2ed422e6441cedde94c85a870277972a4b4a5a74f4fd76be8057ac92e6c5c36a4242dabacb79fe31052ef83c38da68cd2095185ae6398a284fc5d3c934fface4325ec734a2265fd3cbd513b957bef47f04f4dd699c6903a42757cccc5fdfe5b264f18f5bb16b394c4f855404486c63cb5f2d51aafed5 -S = 70a4fc2afc2524ec159aaaac0cf5242e276057c3ebaee9c3c430aa862ac5758aa3a55f6f6ebbb25bc5229e51c976949314244efb35d89d4516845e41f9cb9c4db78d381eb35f257d3b9981eac9e27cd9d18a56a6dceceebb77523255684ad6ff58622889e08a616acafca687e2742074d0f7431ff5ca4324c4d25b44af9fd2aa -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = d73829497cddbe41b705faac50e7899fdb5a38bf3a459e536357029e64f8796ba47f4fe96ba5a8b9a4396746e2164f55a25368ddd0b9a5188c7ac3da2d1f742286c3bdee697f9d546a25efcfe53191d743fcc6b47833d993d08804daeca78fb9076c3c017f53e33a90305af06220974d46bf19ed3c9b84edbae98b45a8771258 -S = 8b57a6f91606ba4813b83536581eb15d72875dcbb0a514b4c03b6df8f202fa8556e4002122bedaf26eaa107ece4860752379ec8baa64f40098be92a4214b69e98b24ae1cc4d2f457cff4f405a82ef94c5f8dfaadd3078d7a9224887db86c3218bf53c9779ed09895b2cfb84f1fad2e5b1f8e4b209c5785b9ce332cd41356c171 -SaltVal = 00 -Result = P - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = a4397d9ab677aaa13a68a09de9ae0ed4045d479aa0ff3a7242dca477ab7884faf55cd06ddf19667f668b4589955bfd299dc7642c28a68bb2eba6f08c7ad9f5e96170913270c6463256a0537a72b32a04e5662416ecda74696d275a8bcfe999820ffc2ab210833201332f323828be7dac04c1f01f93a3dde1efe7483a51b1560d -S = 8e0fecaaf7911ccadb8ca5b6ae3bb89580cbda49d3181d5aab4f03431c62aedb4affc58b87c4b3c4ee09f7908f34f52e2901891382b57cd78d3a824fe446eef4ef46b2afb0d34e6cd9a263c21db8c9c2cdcd5e60eaac571d67410c7136180ddd6195ff2a0691746e457da69bd1667a56b1980a22d5f0b3595af0e8c3bf97c2d6 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003051300d0609608648016503040203050004406bb51b0f43cc58788c9d60f71e06fc473949ae313b3354033526cdfac71690c584f916b1a8eeb47f17f339b6cccc3fb3a53786d418295c1e454db8cb17cb7de6efefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1c23c1cce034ba598f8fd2b7af37f1d30b090f7362aee68e5187adae49b9955c729f24a863b7a38d6e3c748e2972f6d940b7ba89043a2d6c2100256a1cf0f56a8cd35fc6ee205244876642f6f9c3820a3d9d2c8921df7d82aaadcaf2d7334d398931ddbba553190b3a416099f3aa07fd5b26214645a828419e122cfb857ad73b -Msg = e4690fb08396a8bf07377778a447dbd14c771024bd2353cbbd8446eda42795971c9eda0f2575be655c68614a7cd2fd252569c664dc291410548ec3a5eb06da2078a66c59441cbc9356e5a452f4c0386d6662a663fd6b61f254997ee6d63b5e3080e98d37e873ea737f17083713f7d5ce98ca79ca27d18199470c3d596caf66ed -S = 9572ebe453e2f17dd72921b38a27c28c68f4605aedf6b4a7d54079e3ceb2811ccaa6dbc0d71d47d93cd1f18cfb028744fe3d8971b0e9712f29ccab4152e2635dff3b9a1e9cb8f462b138b00c4c0a1163739286b50ac232da5075a9ba3c02a3f604d4629a7df516b39c8d01cb5019f9630436c70415c6b16d79bb29f3a46b72d6 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443051300d060960864801650304020305000440605b7b97abce7dee5f9b9ebf2ebe35d7e474e62b3a6e86b108cbfe3c3a8300bd11deb0210048f502b7af1c9dcb1805f1d61e8df038359729a4bb33774b9d13aa -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -n = a8d68acd413c5e195d5ef04e1b4faaf242365cb450196755e92e1215ba59802aafbadbf2564dd550956abb54f8b1c917844e5f36195d1088c600e07cada5c080ede679f50b3de32cf4026e514542495c54b1903768791aae9e36f082cd38e941ada89baecada61ab0dd37ad536bcb0a0946271594836e92ab5517301d45176b5 - -p = c107a2fe924b76e206cb9bc4af2ab7008547c00846bf6d0680b3eac3ebcbd0c7fd7a54c2b9899b08f80cde1d3691eaaa2816b1eb11822d6be7beaf4e30977c49 - -q = dfea984ce4307eafc0d140c2bb82861e5dbac4f8567cbc981d70440dd639492079031486315e305eb83e591c4a2e96064966f7c894c3ca351925b5ce82d8ef0d - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = ff23e00f819bae424e41d6b762ea6b88801e651c831c964af31de0c1d6dda4a7c8587d804ed12f526819da06650e7412fb627555979ed442f2663341e5fe57527e0ddaf453a124451674976a6a6e0a31f56a79f5b73dfac39af4f3ba4a5e8bb846cb5e333812756482d975ab1910162f96bfd7c58a02f113125189f5ac05291f -S = 3c9db203bbb31c7a3498b3b35ec2ea818614f3a17cad8308f834c6945305e3b94f9886c00098640cb56cefbf06a9ebb7a8c28af610c49896dae53303fb716bc3d2ebf95205944f845658732e8a7ee032472942292f82ba24a66094c7c3b417f5e678a19c04e3b54ba5f0f03610c56d31b9726ee0e39cb1708d89fa61ba9a039b -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = a6ce108ff3100b953781496c3d081fe32b8cedaf6d14aab2ef2dc37d8f8d2613d2f599efd55c51498749c0961681ae4ea7e28bf14a8f044c2d4dd4f9102ddd25f86c7795289708eb4df2d526f91b176952eb52fd0c9de2989432d6e08e13022b82f95089d20a5704f0452f26cd1f83bc956ee7da99876c1f8da3723af388bead -S = 6592c64db5ce133e1c7d499bf7ea4d0203897186b4319fc5e29522d97b9af212fd5a10a8c15246a46d0382cc61c9bfe2b211871d7dfa4eff9a6fa15426309844fa72b1de7aba231c66076185014b9f9e9fadbc2a739ee95c48da75fbfc7d05c22e7896db47407e8d78f0d28519c7fcb6c868b05016bcf73075477a92e97625bc -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = 9edf5246ae1d8fe800bc2ed422e6441cedde94c85a870277972a4b4a5a74f4fd76be8057ac92e6c5c36a4242dabacb79fe31052ef83c38da68cd2095185ae6398a284fc5d3c934fface4325ec734a2265fd3cbd513b957bef47f04f4dd699c6903a42757cccc5fdfe5b264f18f5bb16b394c4f855404486c63cb5f2d51aafed5 -S = 6c80cc0f17783b39712a994f16a461830c26ba3f3afd1a277cda564c8a8b41c4ab444bb6f79df1d109f781de3e6e81d2a0aa2b6ff566e065b3125a6bebd36039aaab46e38a3fb36f66e665372f0cbe15a696d00cd79922bce7e6771ac59fa0c4576f28eeffca9177bdfb0804d2f883b929f58d4ea948df8bb3c283fa337d5665 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = 4ff6c9e7f9f03abd3e114a788fd51318feda52b6509c1b685483cb6574213f6a8ab4435cf5f34d2eeb076c0510d77b9a48889ae0ca44dfe8773b480169e8f423ce96938ef7221caeac02be42c38618bdf15eacecdf5d91da807d69f1a3229361c4a3a2c628060d05290b2776ce6d52499e647022b66e9b071a4f167c495683ec -S = 6466b9759635fbb2a3e8cb7d2a6192ea7da6033b76dd578b76ca468fcb9215f8138966f9aaa3e82246d15bb271a269eda087e63812406407ca12cb085ae82ceebcf28eb44f6608549fbf6383882c864688665a1b5a2d748496b36f8b935f676339fc61e9bc0c3a5a58141226f300cf29c4371047d530a4776809f572b88ecdfe -SaltVal = 00 -Result = P - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = 85624c37ee13b3d8cb80a5961a39c5953caf10f1b4e9c00a2c78701fb8ac821f5f08bebbd8f43bc091b283a4f693f25eef6b5f7baa42ff6f9c4c8529c21c8eea2d143d56bd2022cc2da461f34fb210959981e0b1e11a00cb65553e870e047076f66e123027ff30a3a63d87aab0fee7e243d8dbb9e0da8cc79079e36225cdee6c -S = 705a07d366f2326ced17374d5f599d483ccf184d5fbbc288face464b64c058e6583b8ba664f979f3a6c1b0755b1e2cfe8154c39176d432f59af5714bcf9b0af8da122af77f0393385613393d43db7902eb1b81fc9dc6604692e0f85d30ec59fdc521cd35e5aeef006a6b919bdf47bc9a468daf3e86b3e4956ff736bbc25c9ed1 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003021300906052b0e03021a050004143dee53379c3e2d8c26a41c9f63be60b1993097d7efefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = 263da806fe0a7a242843f295893fd891cd13c0ecc1648c90fc79322bc594bf2531839cd58c7210f4fa0307525ea112c77b11ae6d5a49c90ceb8682d6ee9931551481a7a1623fb7d6d7e6f5c54ef2bdeaa6da779f1fe91a8e0749ef6c976198e5186150d2491a74b20514435821dae2e19499a2e9dae986ff9aeb00558694fcbc -S = 727d32d7faa37ab2dac96e9f822be4dfe60459ab7aa18a26cecf6c84bfa7fac7261c86f89ca84356ee20fa9e8a8a9a2b5f5e624cc4269aa8583fb148777091ecab8929e3f8a628c8f6e1b3a48ff1f60ce1b40f279439bf8eadc6c1b977b51e8ec3c65cb8db9fdb956b514d28381260b9f6b02b2d065ef57770952d968bed65b8 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443021300906052b0e03021a05000414eaf16b6fc483cd5d255ffe76f761420c4df301e6 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = ff23e00f819bae424e41d6b762ea6b88801e651c831c964af31de0c1d6dda4a7c8587d804ed12f526819da06650e7412fb627555979ed442f2663341e5fe57527e0ddaf453a124451674976a6a6e0a31f56a79f5b73dfac39af4f3ba4a5e8bb846cb5e333812756482d975ab1910162f96bfd7c58a02f113125189f5ac05291f -S = 64c3e9ef2af3501ed929ec204d43848d42f3393e437b4267c70d87fc5296ebd752739088529c16e2f6f0aa87e1bc6843779dac3af54f90d3334d4b65b6b0adaf91b6fa8a75826a30f50177f887e705fb64a9258f131dc958bff8134bd68206b9d3a6fa70b2c7de5308269a6c33716916c37810aa69ce3e81db88674a07fe55e1 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = a6ce108ff3100b953781496c3d081fe32b8cedaf6d14aab2ef2dc37d8f8d2613d2f599efd55c51498749c0961681ae4ea7e28bf14a8f044c2d4dd4f9102ddd25f86c7795289708eb4df2d526f91b176952eb52fd0c9de2989432d6e08e13022b82f95089d20a5704f0452f26cd1f83bc956ee7da99876c1f8da3723af388bead -S = 6c9e4455899b0ede371ddb6fe074217d330fe0e27537b0f06ea2e24c75ed6017594ead552296da15f11e6e6923639d95fb73e98d5160e80754ec12f4a06660c6e27eb4de4fbcfbeb37176ef5281a190249e34276a2d736e622c8151f3d5b838e450383edc986cee6b00a1d4cd5a7de8fc8629b6557a3becad84cff5c6c51f2a8 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = 9edf5246ae1d8fe800bc2ed422e6441cedde94c85a870277972a4b4a5a74f4fd76be8057ac92e6c5c36a4242dabacb79fe31052ef83c38da68cd2095185ae6398a284fc5d3c934fface4325ec734a2265fd3cbd513b957bef47f04f4dd699c6903a42757cccc5fdfe5b264f18f5bb16b394c4f855404486c63cb5f2d51aafed5 -S = 9b689f488edb16d4aa3192af3760977401dd066d319d4c5dacff4dbe8aab9aa5790f39bc2378d0c8f52f286fc1cabb743bf6aabffacf5ffe4186054d0b121a2e6559806886759398e7d30781380aead8af992485e2bd582208dcf69ae8e7124b1571cdfb7db87cd565f293cb8d26a8d005508a3332d4ec27d44a1423402e6d8c -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = 4ff6c9e7f9f03abd3e114a788fd51318feda52b6509c1b685483cb6574213f6a8ab4435cf5f34d2eeb076c0510d77b9a48889ae0ca44dfe8773b480169e8f423ce96938ef7221caeac02be42c38618bdf15eacecdf5d91da807d69f1a3229361c4a3a2c628060d05290b2776ce6d52499e647022b66e9b071a4f167c495683ec -S = 86ff99daaee2a3c866a71f7f6fb391b9b31a3cbcf525321087a6b253e42a7b5fa386ba3907751933cd153431507b78486d5d43dd35779962fbc9babc487afc696b0140ade1456fc5b23ce5c7c97019247e827cc7032c7e101b68eb4bfb003ba107f042b92ff697789fe43018d28794c7aa8a70a5386e891e3456a5e52990853b -SaltVal = 00 -Result = P - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = 85624c37ee13b3d8cb80a5961a39c5953caf10f1b4e9c00a2c78701fb8ac821f5f08bebbd8f43bc091b283a4f693f25eef6b5f7baa42ff6f9c4c8529c21c8eea2d143d56bd2022cc2da461f34fb210959981e0b1e11a00cb65553e870e047076f66e123027ff30a3a63d87aab0fee7e243d8dbb9e0da8cc79079e36225cdee6c -S = 1f4e56f13d4167951a716dc8340c006715a4b9340a1bbcfcbb7befd70e15723d81ee5152c42967ac479b3a4ceaf1527b9379daeb245c423a21bf35826dc0f6b90a4caa579d962023e12e2eda516484ddc9483b91c7853d03a1854536d1e6fdfb9217223d2d9132a56d411183fc30de2463c4d5bea4429e7599dc9c4dd2b96b89 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00302d300d06096086480165030402040500041cc53cbccde35eed66e504f5ae6ecf78ba8f83abd4b67822b40e121f99efefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = 263da806fe0a7a242843f295893fd891cd13c0ecc1648c90fc79322bc594bf2531839cd58c7210f4fa0307525ea112c77b11ae6d5a49c90ceb8682d6ee9931551481a7a1623fb7d6d7e6f5c54ef2bdeaa6da779f1fe91a8e0749ef6c976198e5186150d2491a74b20514435821dae2e19499a2e9dae986ff9aeb00558694fcbc -S = 002e26f1d72dcaaf2935f4177601e7b55da3ba0769372a2326d4e621449deecf84c2b3b2998da662907d167a6e7dd0b63116acd7c98d3e086da986ce126568aa31ffa136efaab815ccb9e8059a1e2bf1393dfe8567b73c8191d5acb8560a69514495a33362e05b94c3e260e181603a5d5d9a589c21c5b18effbbf016cd493276 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff44302d300d06096086480165030402040500041cd8eee327931d42ecd0654f1da8d551ebc5ca117b9a9bee9d28049ac5 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = ff23e00f819bae424e41d6b762ea6b88801e651c831c964af31de0c1d6dda4a7c8587d804ed12f526819da06650e7412fb627555979ed442f2663341e5fe57527e0ddaf453a124451674976a6a6e0a31f56a79f5b73dfac39af4f3ba4a5e8bb846cb5e333812756482d975ab1910162f96bfd7c58a02f113125189f5ac05291f -S = 8b5a3675f397841c53a9021dad71a1efab91451c71ad7060ce85d75b306d6403ba23d3370b0695be87485cf6680204c68424bc7e442ef90ac01c4df420ef574294823250a000d56a5d00947800dcb2f4947f5b4eb18fa1dbdc6ab16be4b7131102d4dff98ddeac38554473964d29cdc521ee690cde5a8cd16889aa090c32c53e -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = a6ce108ff3100b953781496c3d081fe32b8cedaf6d14aab2ef2dc37d8f8d2613d2f599efd55c51498749c0961681ae4ea7e28bf14a8f044c2d4dd4f9102ddd25f86c7795289708eb4df2d526f91b176952eb52fd0c9de2989432d6e08e13022b82f95089d20a5704f0452f26cd1f83bc956ee7da99876c1f8da3723af388bead -S = 750e59f29d2dfeedab2a3a09034904715957149126c63e6a2dc7a633a32c4c0561d54eeb1479cb65274bac37cac4751f4dffdfb7530171599b61d94862845f6cd12a5e0bd6adabc36f06d216a00b1942349710540555106aeb87f5cf3f78df918f36cf63291ef2a7064e31b84075d1c8b551225a25f59c721a3d77046078557f -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = 9be28a4763c6665880c1c2a8a74494622be46de3c20e5b118cf70fee51d33b6d0b473e84a4200382004526a33eea59e13b07070e580937207ec7b2cc5fb76856fe6210a771150fa0e5da9baee4a6209ed3d4e2b3bfd2e5f6591b0ace3e657ad07c1b47d8520d5159386767f11fdfaf41fa3348fb7dd32d3c25da5d1d78433985 -S = 0ac6e41252383ee5d07f4fb08a22204f56440a8f3c8568d6e6bae46cfc9d39b65b2eae827164d716e9e465301d08fca7356ef447e0699feabbfac16ed19dc9233b457fe64d6fab38aca4464e5cd3eae3f43bab17856cdcc942e2cc848b7bf390fc53b3ed2e6f63c5d961bc83475ac200708f6e1d5be30cbe24fe4d3dad754269 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = f56379c42e3ba856585ca28f7fb768f65d273a5fc546156142857b0afb7c72d2d97ecfceec71b4260bdc58c9bb42065f53af69805d9006233ec70a591aff463bf23d78200fb8cc14a4eba286afe8924120efad9e3d3f06f7452c725e53728b8f86c9fb245fbaf7086ab0092e215213830d1091212efc1ec59ddc3a83707d4ab8 -S = 5f49d8dc4519d9520d6542eca08cafb2d99cdb97c5a8685df2476b40505a2f9e8d63d76516b83481e2d961a7e8dc5f9f46887e394776711b0f85e4303065c06d362456bc219fc6eb343ede6733f779f75853533bc9ab876188da8ad98f9ea2f335d2ceec34ef9cb2782bb0f79cad309608ddc222e00ebcff9d14f6e6ed39638b -SaltVal = 00 -Result = P - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = 399b54f756514628f32ce8f1cf391d77047af55f3d43804923e5e09a188aa27f28604f2f3cfa3d7091f3ab5c69d40d650137a597c22d531dbbdeae074f6f534a2b297e087cd7d7125e6f8eac97f5a990859d9d3555301c5076b02f9c4d3f84d62b3d090c7cb1ba1841eab668c066990079f206c15d1383eb3ba58ae17bc2dc2c -S = a62e4b688bb3c4c2e11a3a0b1ef81ff4bbaa110c9b830d02bda2d364dadb2345a8c5dca58c611515f0c09732ee6a6642d5c5c339460a9d15022f48c36e9bc2fb8b2b0ff99005273287b8c3bed87993baf52f0e9d079281bc25a8694ed9692446127c26c34f21e610a84f3617247ecfb3b5337fe59d1239dfb7fdac8694dbef0b -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003031300d060960864801650304020105000420be1f73a059cec568dcdfddf1daff4201e79273653f88ef8f16be7e9ee660335aefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = b8518b80a55b365eb1850e18f88da2941c99543c2f865df3d37d114d9fc764ffc5e2ae94f2d4ab6276bfc6bda5b6976a7dcfaa56897982880410dd5542af3ad34c469990cbec828327764842ef488f767c6b0c8cd1e08caec63438f2665517d195a4d4daf64bc2a70bd11d119eec93a060960245d162844c5f11a98cd26003e1 -S = 06317d3df0fa7ae350729ae2096b050dcec8909d36681ccca09a7a527b90767f8c2318c49e09483b48df77ddb632d6ca721155165389f7795d3ede70465678649399242aed6d984ca74fc6c2eb4dd4bb2cd7bf2125ec853f2bf757d665b29487bc5b63df0d0b03b18608d3d9a7576ea0954aef3d3303f7d8fd7e7f9725c114e2 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443031300d060960864801650304020105000420a51c139e5ff91509eb0bd542bebfb9a4baa9399a5535d9168942298ce69c4f5b -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = d3787e2cd5eddc154a3b29c8a5161cb0ef6fa97d6b90c9d579677d46ba22108075fd9dc13958d290c40df3ae2400224a1cf8dd74c9adc8d48522ad9c0c34c1bbde732954e432bc6e55da0beddb849ec1f2c6815d91cc006a0dabaebd3af3ac87d38327cc1ca22317c54b776b12c7197c39829c1f0c17f700d7ad88938c86594d -S = 678507d9ebb2c5254ff371d3e41b435deb1118bf0b0121c1bb8a46575df101d12d771471b956f8c229b8021a9f08faa61e0577c6a715108874bf655576954a85fb63817b58298fe3d3643a748dcc635210d2b202e3b2e663c4a212ecbc7fdf5e34e8d499a20034d98732c09be015ea728d1cc831c61965f3e32a8aae958d43d7 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = 31f8dd3024b0487ae1e3a7af9032ef7c76d5420d617771814747c09b2a4ce9ba3ef8630b4e01e3fd5c6c24f588ebe44433682f5663e2df2b6978640bc2c3c1763c69d75b59efe68af8cf516a32cba1ef8380cdc72a3eb9d4d217fcdf7136e68b7173c2870e245808ff35b677587b3066af45a6c97d340563c84d107eff4d61df -S = 8d26faa1cc87606514e47b7ab3d82768868a61d237cf18e75f935e20fc5925e2c667b05cbd09da878fd623430f71ecd1f632fff4d1d049ae704004c89012008e8856f61a03001b423f4f06eadb4a72eb946a7a4dc4469e995609801498bb7471a533ee0f422adc5d41b744301efd836e5cfcc496cfc6ee646ae2218e924f76f9 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = be9b41883cfadec3960d866fe8514f9821c6c7e65af6e5c167343fb8ac227e2432760f08fbfd1c3c92e0bbcbe5266599577aa949122e215d9a81a69fa81dc0c035e46040d5ecd28d46c8ed6f490a8da3b00543c7b9d84a769aa8bdb35d2c088bee6f9df673d1e8ffdb4f8424ba05af0054f1fb27f7fa47528f31eebc74563ecb -S = 735c47985ee75db358eb0d05624be43778a37d40ad1df88cfc5b4669906e290704265fb3a133df781dfdfaa082d21d0c431b54c0c6c239fb0c0b47e675c0def6d94a726ff8267c449f1300b21a7c7f171c76e869851f9be39546e274f60924ddeedd4f69b70d97293a10ebbb3df8f9c1fec31f7d3562150a357150fbc8ae5237 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = f8a2f38109c9b6d868c5b3481cd3478c8e0845fc3e36479cb50f4158bb8d5c8ec99101cdc1ca33ddddd823ffe5b1fe75a6440a459f5df13bfdc95d2dcabac482616d86f52509359772cb3313d46083367792d9afdf27f313d9062c24b29c4f52a67ea9829b50620f10e50d0e50a77dd7eb3adac1665cf52c3210d9c5dbfba305 -S = 9ebce94bb79d82fcd236874df4c2c3d1b56481ba15fc17a345f6d45297b6adb9e07c1b582e22ce0b1830763758827a77ca675c708163cbe7a5db72d2a95939b3cef60c632a19849e6d95bf6a867604eea7f69b506bcee7d04678d4252c715edf0a928ef4c1181177bff20c3a95215782cd6b70564cf1ec2ea25e6318ef1f96b5 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443041300d060960864801650304020205000430940085d291d91da907231dd6d6e10d71011dc3e0944671e632bb0d87c0b8fa1bc2f1019caa64a8f6844a8db073b0743b -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = 7e3c652fb2786a379614fc8f9f01555cf029cf61cf0af6c455a4e2156996c48cef84be923cbbf883cd18f0b3392611af658688c5f79453c60d479a0a2e5943b581a8c1393cdd2c1c604b97fca41a9ed0aea43e70891fea58547ddaa83790a7709c72152b9b242f89b5759a72c6252347354b9a6b6ef4e302920d4af86c831745 -S = 995e2522f280d28f9719663178429d6ffb26cfcfbcc15812e83821db1a5e2a31a8160574e4fe4f1f09ce67690c67fe89c11015ffbf5dd5ec669561f0a2b13c416992de570a532b805b00b8003f6c70d56925ff2bb5555daf3edef1da6bcb1c94d29bbb243119da64ef352d36ddd6ac472a99a1a22da809aa235b51afc8379619 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003041300d060960864801650304020205000430cfd23d0f765da0ba39f284a77f62552300460944a69e6fddf7aaa731f62c6d822f5eb581075a23fd540aa7a920f7c3bbefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = 2bd0f6349c6f8198a10ce8e761feb6d4d72bc71addcefc628a773367be537758fbad737e77b52d1e6f80f1a1bd518af2ad17b9280d36df65838afdfd24a9dedb4169932184a3200f3c367526f64ea08d4de640b3038b3d365063b604796f3bc0a50d3d67edc1c233b2345dbf337d5e6d5ea04605e7547e9e980a48c2e82af5cd -S = 38103ad73f8bb3a9c3e01e95b8cc45e982a64f17a318026e185d523dec851ef9fbd1b9c2694a4688925580bb50709ea624417a685b39b36e988d9b7b41282cb969379c3e739c0a98151db9181dfa58c5e6ffbaaa6971dd5171d9ebcf18ce346364f7601856aa68584ee3303e8a69d0dad778e4a4ba3ed4f8a009d561652d134e -SaltVal = 00 -Result = P - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = d3787e2cd5eddc154a3b29c8a5161cb0ef6fa97d6b90c9d579677d46ba22108075fd9dc13958d290c40df3ae2400224a1cf8dd74c9adc8d48522ad9c0c34c1bbde732954e432bc6e55da0beddb849ec1f2c6815d91cc006a0dabaebd3af3ac87d38327cc1ca22317c54b776b12c7197c39829c1f0c17f700d7ad88938c86594d -S = 22754363656ce107c1beea8999cb4a95d267d6c6d3a06b42c939f51254f822cf49bd6d51e27af51afa0d260fb4bf6fcb8b4926270851d64f2fae6f4c6562c532e3fd72db5188c51eb57b01a871004b38d6a1bb4856fdd93573735a480b4c3e444262d198d54de6db409db7432dd45beabc34991cb6868e1e1dc62f8ef509f36e -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = 31f8dd3024b0487ae1e3a7af9032ef7c76d5420d617771814747c09b2a4ce9ba3ef8630b4e01e3fd5c6c24f588ebe44433682f5663e2df2b6978640bc2c3c1763c69d75b59efe68af8cf516a32cba1ef8380cdc72a3eb9d4d217fcdf7136e68b7173c2870e245808ff35b677587b3066af45a6c97d340563c84d107eff4d61df -S = 92cd8a854b4b9842c12c7f9ec2dcfad57d1f403ce8276d355f436c1d9aaa720867dc5a96b91debceedf55eea2a33d99e586a0a59d68e9289ce6f001be3d9ae9887d9f169ecd77600ef60b97851bc8ad6c5566c830a25690a13a92bd082fdc0b356a6443fcae3d29c5e9818b06c69748149a3f34793a6c7b04da345caa01d6f20 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = be9b41883cfadec3960d866fe8514f9821c6c7e65af6e5c167343fb8ac227e2432760f08fbfd1c3c92e0bbcbe5266599577aa949122e215d9a81a69fa81dc0c035e46040d5ecd28d46c8ed6f490a8da3b00543c7b9d84a769aa8bdb35d2c088bee6f9df673d1e8ffdb4f8424ba05af0054f1fb27f7fa47528f31eebc74563ecb -S = 5d8ce84e9473178a2ab5373d3154e7d649b40a144040d4a612e9ae43666d681458b5d985f5bb1bd5709455f5421dcff12307e074714b6592f0095c0a67f66f950ac8e2cc7b8ffa5d8f89d407292ac659a4e479ee2cba19d6f31673edbecb3535b85b11edfcea4df17799418fdfda145711f5f9c0540f811ac92e05bea4460c87 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = f8a2f38109c9b6d868c5b3481cd3478c8e0845fc3e36479cb50f4158bb8d5c8ec99101cdc1ca33ddddd823ffe5b1fe75a6440a459f5df13bfdc95d2dcabac482616d86f52509359772cb3313d46083367792d9afdf27f313d9062c24b29c4f52a67ea9829b50620f10e50d0e50a77dd7eb3adac1665cf52c3210d9c5dbfba305 -S = 3c42cf56c04c1ddd18a5ec523df036428d09bb44a7b12be5bf6fdb3866a122a5cd0edb2cc81930c126a9244afcf6a27c8820369f474a06f8b7022ac8b95e35791a49d71a40ecd145e8d2e334b15f6ed698b7a646248ee73f567739469960c0da5112916a12f212d198a6f6c518b4745a578d265ab1c04438d7a38263a5a8c254 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443051300d060960864801650304020305000440174762fdf1f011f716417beb00598a33aae32c141c664908178740f19833d9109154e89f80a1ff369930cb2dbeeba511433122236e0cf6df2d7b7202de550c6a -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = 7e3c652fb2786a379614fc8f9f01555cf029cf61cf0af6c455a4e2156996c48cef84be923cbbf883cd18f0b3392611af658688c5f79453c60d479a0a2e5943b581a8c1393cdd2c1c604b97fca41a9ed0aea43e70891fea58547ddaa83790a7709c72152b9b242f89b5759a72c6252347354b9a6b6ef4e302920d4af86c831745 -S = a6825908039d9165b1f1d7e85de390819b3e13fb914521bde6370db313e0c37444bc1bca1d798a73e9602b3c61a67b6c3531c25a0528f4945ac7f27ed5848b782668cad8533000a42a0435de4436e4ee7fe0f9a347750543d921a313c6872cbcf5466ae41a69f32d03acff357cf3e4f1a3e7ed4575dc61bf4fb77a04b9d3cb32 -SaltVal = 00 -EM with hash moved = 0001ffffffffffff003051300d06096086480165030402030500044062eeafda47b660f230159a79e8b20ffc84752ef5ddc420ac6478511cc199f983ea3cb8cbeb9955c175ba5afce719ae601c6303a1f6cd5e0c241b5cfb8577deb6efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 252c4956ac328ba04789bfdc5e90819981a100f3b540069ba8719b8b3ba27980cc7c96710a75ec0da83c1ddf353b45845f3db7224cdecbe5653cebb01fb66305d42e617e8a51514c6d2fb6b3cbe3ad9478ab7acb575f854ec9c9576a70c63934921c39662b32b8c93fb660f64f50e5481892a8ef4b92a64774995f2a0fbd64b9 -Msg = 2bd0f6349c6f8198a10ce8e761feb6d4d72bc71addcefc628a773367be537758fbad737e77b52d1e6f80f1a1bd518af2ad17b9280d36df65838afdfd24a9dedb4169932184a3200f3c367526f64ea08d4de640b3038b3d365063b604796f3bc0a50d3d67edc1c233b2345dbf337d5e6d5ea04605e7547e9e980a48c2e82af5cd -S = a5c713d065e204f5a3d87e4752b235fa79a703931065aaf7ae4a29d641763d7ea4350d8d9a29b29b4fc770169ba7adf1cf7ba872769265cab2d41ee7e227e7682c749fbc5836debc02485eaca9637391c3793b3f05701f80a90cfcc04c091fa37628e4eebbefe5ceec0b4dee1b41241fb883252fe18ca65ab01e4a4e3f31ba36 -SaltVal = 00 -Result = P - -n = a8d68acd413c5e195d5ef04e1b4faaf242365cb450196755e92e1215ba59802aafbadbf2564dd550956abb54f8b1c917844e5f36195d1088c600e07cada5c080ede679f50b3de32cf4026e514542495c54b1903768791aae9e36f082cd38e941ada89baecada61ab0dd37ad536bcb0a0946271594836e92ab5517301d45176b5 - -p = c107a2fe924b76e206cb9bc4af2ab7008547c00846bf6d0680b3eac3ebcbd0c7fd7a54c2b9899b08f80cde1d3691eaaa2816b1eb11822d6be7beaf4e30977c49 - -q = dfea984ce4307eafc0d140c2bb82861e5dbac4f8567cbc981d70440dd639492079031486315e305eb83e591c4a2e96064966f7c894c3ca351925b5ce82d8ef0d - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = d3787e2cd5eddc154a3b29c8a5161cb0ef6fa97d6b90c9d579677d46ba22108075fd9dc13958d290c40df3ae2400224a1cf8dd74c9adc8d48522ad9c0c34c1bbde732954e432bc6e55da0beddb849ec1f2c6815d91cc006a0dabaebd3af3ac87d38327cc1ca22317c54b776b12c7197c39829c1f0c17f700d7ad88938c86594d -S = 4bae63c2b4ed42b92d95293ba755c0f3dbae5a13369b298147e3d7d9cf8629b7df9df22f13370239ef86c91a6b15efc5611057b375e948d554a95a7119f5663b0ba6c373121f2d4f6f9a8703a78153be3472f296254db218a22925546340dd0495ec68f354ed17ed4f9d85d4b9eb1b9d1816cc1422c852410841f166e69cc212 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = 31f8dd3024b0487ae1e3a7af9032ef7c76d5420d617771814747c09b2a4ce9ba3ef8630b4e01e3fd5c6c24f588ebe44433682f5663e2df2b6978640bc2c3c1763c69d75b59efe68af8cf516a32cba1ef8380cdc72a3eb9d4d217fcdf7136e68b7173c2870e245808ff35b677587b3066af45a6c97d340563c84d107eff4d61df -S = 8a8b25a74adf17dbc6ee3dba1982f94c17ecae57a75835cc4cd476a1afb23d01c964e8532a6d0afe71ebd8d26a2e5514906caae8b18ddd860ae16303723cbd0a155cca1a4a7be32c2396b1d09544057e7f7fdf6bf1bb2861ecc0f90223269add410dd66ea54a507a31b75528bb277ee9d3d3096d2e2f0f33b0509f27bd990b9c -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = eb2a75ef219b2bec0987c2623a76a8d3c292754519c47f8d541aa8cd9b6c7b3cdd3f7825c2e9ab33e2f684eb34cbe27ac98971b1ba34364e5f15687dc15c829e520a9649dc0ee48fb8aeab8340293ffa869b5c8e4720bae91a3ce140ed7b3f1db25478625653fd8bf378e03346dae7d9638fdfe5a7d032e6ef59bc1e070fdb40 -S = 0fd7069ca1e24f81f3c67b0bcba5fa72764655739d549a59288e6eaebf4d2f52c52eaa17e495ec2b2fcb52a4673aac2e48e2078688b8e5d8a91d7c8c4bae725070425a183e95b352999ab2b49adce63b6c9d48dc29e0649d91b73fb04c45786239b0022231e5e173e2f0d94fee7905706f39ec88fce30d107e4151d010be719b -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = f1cf2ba2463023a1d329957cf3fdc044ffecf8ce0a11f9b6ce8b7ba5e5db07d03d8d08c1c61b255a6d0ece174e661593253cc04e06a69cad4fdb1442da97014e77c1c484994c93104f5b10d876a820022e26fab68ae57e258c36c9ca501106ef87b38674278b14cc61578248d48b889800f2cf8ffd9748266ce6c2c4af0fbcbc -S = 2e305057388fc454647e2c20b71c3cc3383af683126b1b802b6e74096b46655df2715e18bbd1f9f7f4484dc63ea58bd7461c58d6e7ed63e885a2524b01eeea2b9d0cbe25e6f0f780fed9fc9610ea5b7de468b0cc409da4607a367b2815d346facdb6375a7723d013f2d8726e7b40a680b82c112324ab161aab860a943d4fc84d -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443021300906052b0e03021a050004141bd3d18838d09a61c2b0ba9865a146b958c0ec0b -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = 8b61c39efa507e17cf4d575bd600286d56a40e84f35d6c06d3cc33b400e161220df1c86bfd0911226081008cbfd4fa0c3aafc4de70478d089ff02f8e0cecb2e6a68011abe64d4196f9de70a9217e8bad594c02df3891cfe71750b509761fc59f9c3627c77ec61759e28c2e1cc4a5e339f9a451ef12e23b8983154d8d0524a437 -S = 72c3377e5a389a176383ffb832de6eaf3b7ee9dfb38f504031af6f3d059cd9c1027e22233d1ed0908bc08ae5edb9aa491aa189610b353b31ec92eb8186c0d2bbe8fb1364c3df8393b5917f69243ccc7cf95edd413cc175793c964efc3eed10b6c2c4de4d7b75f419a68e6cf8eb1a09b0ff29c40b713ed63c4fcc08fb59ddfcf4 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003021300906052b0e03021a050004141c6c02fb4af79739cab2f59451c9ec6ff577051befefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = a6cc1c55dd9b8da73acc6716344503690a9db27bb439518719b41da28284c9894fdbce9de9cc032cf7af6df2d5c658e04121a61c58be6848c2f5ab07291394bdef46b09720b985cca5ff6d22bbb5a4b3a4639ff19ca49fe80f8787c30934ea92eed3694a6ba93c0dac840eacd05a0e6b9a2d430469311fee6a3158de0c2ff38f -S = 7fc3737dfc4bf283bb8f8aa2918af4fb7156703b4870f679bb76e079e561d0adb7a21bfae94e21b83edf20bd28d6c06505109bcdd000c7533a8ff9118be14cd8beeda9cdae6f0735d75fb80953bf28587fae51e024d5b415664b3ab9c26abbbb7f2461d9bf7f2520ba08a09421939fd661d5e3dd83f3e4c41f760291e1c081e8 -SaltVal = 00 -Result = P - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = d3787e2cd5eddc154a3b29c8a5161cb0ef6fa97d6b90c9d579677d46ba22108075fd9dc13958d290c40df3ae2400224a1cf8dd74c9adc8d48522ad9c0c34c1bbde732954e432bc6e55da0beddb849ec1f2c6815d91cc006a0dabaebd3af3ac87d38327cc1ca22317c54b776b12c7197c39829c1f0c17f700d7ad88938c86594d -S = 7948b018e9d0772d84bdda094957387e91179fd7ed4483091f764a2077d37b87a54f4d10069584e50314e1d866c01f1c22de215c0cd1ffff3e23b321378c1b53d0d517aa29ac262ce86dee0ba752958fab5ab69a3a0fb6824ffa8554d4b212f532611b10a28faca706391ac2bbe04a9603e4f15021ddbb1d47505bee6ba83c28 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = 31f8dd3024b0487ae1e3a7af9032ef7c76d5420d617771814747c09b2a4ce9ba3ef8630b4e01e3fd5c6c24f588ebe44433682f5663e2df2b6978640bc2c3c1763c69d75b59efe68af8cf516a32cba1ef8380cdc72a3eb9d4d217fcdf7136e68b7173c2870e245808ff35b677587b3066af45a6c97d340563c84d107eff4d61df -S = 2146e1bf9d75336d7bd76091527567c9326df14a810cf39d22eb91589584caaecd89ddc1b3ef0782e79e535b0bdce8eba2d7f40aa05720278e6c3ed8fe58974fc1ba6cde3fdb79284b64eeb5d08fb312eab503fbdcd85c240414b8a9fb726f38e2780d2506381d90eccbad3c075c7fee67e8a1da037f14fc4a6d8f06c301742b -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = eb2a75ef219b2bec0987c2623a76a8d3c292754519c47f8d541aa8cd9b6c7b3cdd3f7825c2e9ab33e2f684eb34cbe27ac98971b1ba34364e5f15687dc15c829e520a9649dc0ee48fb8aeab8340293ffa869b5c8e4720bae91a3ce140ed7b3f1db25478625653fd8bf378e03346dae7d9638fdfe5a7d032e6ef59bc1e070fdb40 -S = 885c184cf7e40453f8dcd49e1336c91adfc070ae886b23b561cf444092017a86594dbc09c484d6307201633b4476c480994c4bf0a38195d9e9065dee62f5510cb0d9b16a5a9e0ad86eee516a090809e599b4b7022333bdc1c2f9b0cd181a897108c8db6e2abec0c9c6acc426e55ceb9cb4dd565af9d0eadc24ad33bc6a0f2f9d -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = f1cf2ba2463023a1d329957cf3fdc044ffecf8ce0a11f9b6ce8b7ba5e5db07d03d8d08c1c61b255a6d0ece174e661593253cc04e06a69cad4fdb1442da97014e77c1c484994c93104f5b10d876a820022e26fab68ae57e258c36c9ca501106ef87b38674278b14cc61578248d48b889800f2cf8ffd9748266ce6c2c4af0fbcbc -S = 56c800772a63baea87e02adecbe6e7a1cbf352ec6c40d68d02035a8ef54e3c5d4e4c8d23a686d186ab783dc0115ff56138f05cd0a88a28df8304a7fe8c1f944acff2c51ba447d333e97a053aaf222bb6371c35d37a3c7345f7ba81ce99baaf2f165c3a5f0d9a1200da7017de8ab65c35cd7d082800fd13fb87c37ceff83e3dd0 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff44302d300d06096086480165030402040500041c084f86c411436b0111c733c5642186a98d5a8dd8cceb2746ccb8342c -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = 8b61c39efa507e17cf4d575bd600286d56a40e84f35d6c06d3cc33b400e161220df1c86bfd0911226081008cbfd4fa0c3aafc4de70478d089ff02f8e0cecb2e6a68011abe64d4196f9de70a9217e8bad594c02df3891cfe71750b509761fc59f9c3627c77ec61759e28c2e1cc4a5e339f9a451ef12e23b8983154d8d0524a437 -S = 1daeb428f8dcb93c16b0b96a23708a4a0b2e70ab7fcc2fb16075f901f94fc9bde149b26c83738e58dc598bf4e1c53b34adb69d93f30726a174ac87c1a1b67bf70fd83fb9b89f476fcb13cfed84c2f6d6a92294e0eae0bfdf91119cb692b096c9bc3d242a31f8a979f965fb983031b8f33f18b1713cab83c1391005a94b79ab31 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00302d300d06096086480165030402040500041c6c72c171d3d71a0bc8488c39813a0b20e2e937a13d9484f6c5de23d1efefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = a6cc1c55dd9b8da73acc6716344503690a9db27bb439518719b41da28284c9894fdbce9de9cc032cf7af6df2d5c658e04121a61c58be6848c2f5ab07291394bdef46b09720b985cca5ff6d22bbb5a4b3a4639ff19ca49fe80f8787c30934ea92eed3694a6ba93c0dac840eacd05a0e6b9a2d430469311fee6a3158de0c2ff38f -S = 7d914ae58407a2b981e58ca575a81796a5d3d7073f6cc3b2641338fff4b963c35125e99360b8bebbd12add1919ae46f84c67b642b43d48360785d7d990bd6b23a24feb54925575a46c2e49d5ce16204ef0c921a25c31fe0b5ed623b2a35be5069b7a7fa57322a9fdcee5b391451d49e624fad211494ac3230efbad44cc5f739a -SaltVal = 00 -Result = P - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = d3787e2cd5eddc154a3b29c8a5161cb0ef6fa97d6b90c9d579677d46ba22108075fd9dc13958d290c40df3ae2400224a1cf8dd74c9adc8d48522ad9c0c34c1bbde732954e432bc6e55da0beddb849ec1f2c6815d91cc006a0dabaebd3af3ac87d38327cc1ca22317c54b776b12c7197c39829c1f0c17f700d7ad88938c86594d -S = 73b08114f6256d434c5cdc278a9ca697ea2447895884ce05170dd41d5073ae0b6e346ae64fe886287151e0c6aab0aca3638e5b82d63aaaafc50f8070b592cd052ce7bec9306ddc4760a6f6f2166e40800715103f938698a68a10c73ddf524c6c6e55f76f7a0ab7058cace263af7061fe70fd93ca62884d232195a91acc38af2e -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = 31f8dd3024b0487ae1e3a7af9032ef7c76d5420d617771814747c09b2a4ce9ba3ef8630b4e01e3fd5c6c24f588ebe44433682f5663e2df2b6978640bc2c3c1763c69d75b59efe68af8cf516a32cba1ef8380cdc72a3eb9d4d217fcdf7136e68b7173c2870e245808ff35b677587b3066af45a6c97d340563c84d107eff4d61df -S = 6707ff06f4e6fe6cab612b8deb099ac9995511ff0f43fd42f9f1822105e6c78cf6e7bdb117f5a8d554000aeb22c69cd0beb7cf1eddaff92161117f08befcb01605e3300826c87f2fb10f6e34bde865db2c5b7124d3273a997b115f3d0022d0cded54daed0b4ddabfb9b39abec2f9b1e052a89c4d64f38a7649729ccb14f72650 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = eb2a75ef219b2bec0987c2623a76a8d3c292754519c47f8d541aa8cd9b6c7b3cdd3f7825c2e9ab33e2f684eb34cbe27ac98971b1ba34364e5f15687dc15c829e520a9649dc0ee48fb8aeab8340293ffa869b5c8e4720bae91a3ce140ed7b3f1db25478625653fd8bf378e03346dae7d9638fdfe5a7d032e6ef59bc1e070fdb40 -S = 43a9b4ac08716a3fa5e6ea8fc5957492d093b3a4293df69efae3501e938dc25f551bffc491abbc1059543280c8f48e5c97ae0fe602c911eb894804ee585f2d3b9de882856ba2bb4c86c6a14b8126cb02be2ec6303c228dfb892d3786ebd2a9eb3247581ff7f01a2d0f6d4c75a96dcb4e98fddd204eb8d191f0896506fb72d2ea -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = f1cf2ba2463023a1d329957cf3fdc044ffecf8ce0a11f9b6ce8b7ba5e5db07d03d8d08c1c61b255a6d0ece174e661593253cc04e06a69cad4fdb1442da97014e77c1c484994c93104f5b10d876a820022e26fab68ae57e258c36c9ca501106ef87b38674278b14cc61578248d48b889800f2cf8ffd9748266ce6c2c4af0fbcbc -S = 6db3e5bbdfe86efac37bc19abbd07d9209f67876d0ed8f8859b1826d98eb22fa093e161274e4a38675cb76224a70346730314f08475db6ce6fd77d840b9de3063c88e987fb244ac823e962b31ec648ca8942e378a2f7ccf7400b036aea7c5a11e694d85c3c929e43613178eaade378d3c2f6805a14d94029f4a5ce89a87651d7 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443031300d060960864801650304020105000420659241b16b3fb30e5012378eac6d83b927e7fc9d0eb5a5ea9d1b75d48441a6a9 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = 8b61c39efa507e17cf4d575bd600286d56a40e84f35d6c06d3cc33b400e161220df1c86bfd0911226081008cbfd4fa0c3aafc4de70478d089ff02f8e0cecb2e6a68011abe64d4196f9de70a9217e8bad594c02df3891cfe71750b509761fc59f9c3627c77ec61759e28c2e1cc4a5e339f9a451ef12e23b8983154d8d0524a437 -S = 87ee0da9c96d9a17f63d3e9e142181c0979c381ceb769a370545b535abc6eb8981d3fd4029f529909f620d2a00f209b6ad7c8f709fca13118e00a2f21086fb3a4eb4e416a0b2a121e4f7be5b172a8ed12185948cdb75575fe53d883a354f17baae73fe464d85ca0519b980a4b6f565bc0e76060f86b4cb3e90b6c4b9902f5bc0 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffff003031300d0609608648016503040201050004200d04ea209c27fd97098f416a6410afea38ead35d43b7a1f93d7ae04f7d62d502efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = a6cc1c55dd9b8da73acc6716344503690a9db27bb439518719b41da28284c9894fdbce9de9cc032cf7af6df2d5c658e04121a61c58be6848c2f5ab07291394bdef46b09720b985cca5ff6d22bbb5a4b3a4639ff19ca49fe80f8787c30934ea92eed3694a6ba93c0dac840eacd05a0e6b9a2d430469311fee6a3158de0c2ff38f -S = 8be4adcf1f21261f16ed5b4ce29284399e2a6b7f6339ebb94fcd8c412827911eb5e626d6c83315a59db85bea8010ccded74991f98488fc48989b1854619acccb63fff3d1e4e9a350440744e8bd16631f39ef2a1426b8ffc33418dc7a2a0bdd3330b0bbebba1f0b9fcad2347a875dd89feb43506c0d8e1476e36c9fc6a2798ec9 -SaltVal = 00 -Result = P - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = d3787e2cd5eddc154a3b29c8a5161cb0ef6fa97d6b90c9d579677d46ba22108075fd9dc13958d290c40df3ae2400224a1cf8dd74c9adc8d48522ad9c0c34c1bbde732954e432bc6e55da0beddb849ec1f2c6815d91cc006a0dabaebd3af3ac87d38327cc1ca22317c54b776b12c7197c39829c1f0c17f700d7ad88938c86594d -S = 70fa48adbbe7f5cfcc61dd844ec0948d8c20ca5bca62cafb0d7014413350c5fbbbaeff1d445a7367420b1237dd316db6c8298d5ba13a3b26cbc48a84081bb12848cd8acbd198a7250d0411ed8d0e56d0163c39853b3893655037f6b4774be21d62c604522904202d6aa0f11aa1f7f56612e85139ac0d577593586d6229422289 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = 31f8dd3024b0487ae1e3a7af9032ef7c76d5420d617771814747c09b2a4ce9ba3ef8630b4e01e3fd5c6c24f588ebe44433682f5663e2df2b6978640bc2c3c1763c69d75b59efe68af8cf516a32cba1ef8380cdc72a3eb9d4d217fcdf7136e68b7173c2870e245808ff35b677587b3066af45a6c97d340563c84d107eff4d61df -S = 1a7aa3bb07684cb72a23a570dd06eec11f1ac1e5cc02108b6bcd7145c413c743da8706a44db575b7053573e975ea2bc111821612f14aa001dea6551863e34af0e68d6f9281cccf590d1b2528085cb8e878a427d320c73806a3af8b498b7d3789b66dda4ba9d6c26d15500c71a6b663d9612076792513776921503435d6578b6b -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = eb2a75ef219b2bec0987c2623a76a8d3c292754519c47f8d541aa8cd9b6c7b3cdd3f7825c2e9ab33e2f684eb34cbe27ac98971b1ba34364e5f15687dc15c829e520a9649dc0ee48fb8aeab8340293ffa869b5c8e4720bae91a3ce140ed7b3f1db25478625653fd8bf378e03346dae7d9638fdfe5a7d032e6ef59bc1e070fdb40 -S = 706c8a70281ab07dca9ce73757279e70621358f1a5bad91bb8d0f34a4519c625ad000df75709b7fc805ee64e1a0e8b2f5c637a833b682c707eb21ad79f99d9f82aa91ca1f3ceb6da9c117c96391f547297cc8f507cc4363f9f2ff84fd9c8f430e84740f3d3d9f385e73d90c8769da2615e46552566f456f6a675d613b8a97678 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = f1cf2ba2463023a1d329957cf3fdc044ffecf8ce0a11f9b6ce8b7ba5e5db07d03d8d08c1c61b255a6d0ece174e661593253cc04e06a69cad4fdb1442da97014e77c1c484994c93104f5b10d876a820022e26fab68ae57e258c36c9ca501106ef87b38674278b14cc61578248d48b889800f2cf8ffd9748266ce6c2c4af0fbcbc -S = 5b3567d2742f596b42cd2e3951f75b8058a98d822961f5deed17ce86355fef06ce8f1b1e83da9f27ac4203d2b6a406ae2657993624344fc760a0ade6106028e2dd68646f1c6a735547aa7e4d4e6ae1d3f14610d5eebc88dfeeccf979d93f1721554c67bdbae99dcc2efcf3a98eeb6bf713dd3c5fbfa44e3b9467838744d226bd -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443041300d060960864801650304020205000430582a092df1f38834b32c013209c529a91289d7e595d648c1a633680988e5c8f8153c37c9caf89c37578d4a5cccedf712 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = 8b61c39efa507e17cf4d575bd600286d56a40e84f35d6c06d3cc33b400e161220df1c86bfd0911226081008cbfd4fa0c3aafc4de70478d089ff02f8e0cecb2e6a68011abe64d4196f9de70a9217e8bad594c02df3891cfe71750b509761fc59f9c3627c77ec61759e28c2e1cc4a5e339f9a451ef12e23b8983154d8d0524a437 -S = 0a23fdb9060b70ffeb690d0e4be5201499f3623663c4a3c5b8ccd937c20523fcdf526db4279d7d7f1067e241b0d7f00de2841934691747976f3c63e68048702b69db8981d8efba63f0fabab14abf2f517b0d5caab537f187af9f46414f070fa5c1fb9d2eb6858476a5af8bc82b7c38aed298f169f1b962aa452e5f6cfbfe766d -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffff003041300d06096086480165030402020500043061ec010a79fc79f61a9051dae86a56fd57b311f7d5043f4519aae525d02bbe46a433dcc6aad89016c6298dd09ea7ffecefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = a6cc1c55dd9b8da73acc6716344503690a9db27bb439518719b41da28284c9894fdbce9de9cc032cf7af6df2d5c658e04121a61c58be6848c2f5ab07291394bdef46b09720b985cca5ff6d22bbb5a4b3a4639ff19ca49fe80f8787c30934ea92eed3694a6ba93c0dac840eacd05a0e6b9a2d430469311fee6a3158de0c2ff38f -S = 9bda2d9a6a3570737eef2c75f5fd4891d9e8acc102654decc8321b2e114ae8c2f615a1173d855e5d4261a99dc7f825fccef11199e57ba30d98502c237761217261dc31cd14de68201278ccfb46459323d192fdce1577a1a9098e5c7117bc0e52ece3403e0b35fc64969342a72ad74e0330a10a50b67536b088372514a8436de3 -SaltVal = 00 -Result = P - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = d3787e2cd5eddc154a3b29c8a5161cb0ef6fa97d6b90c9d579677d46ba22108075fd9dc13958d290c40df3ae2400224a1cf8dd74c9adc8d48522ad9c0c34c1bbde732954e432bc6e55da0beddb849ec1f2c6815d91cc006a0dabaebd3af3ac87d38327cc1ca22317c54b776b12c7197c39829c1f0c17f700d7ad88938c86594d -S = 3892627dc93f65857a6e773202ee6d8bfed806ec2580f1f63fc7bb547d6ca2d2459efa5aa6cdc9513153ef2dc2f9acc0a3f878c4b3a149b674f246842610ec9d4f8d2038bf1126632b588b7c8376066d1b18d85e51ec221efcb5f58e6f3f4fab1fb6b232d443cb16484670b1adec3a450f9f926ceee02c6ffedebc4664a9c5bf -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = 31f8dd3024b0487ae1e3a7af9032ef7c76d5420d617771814747c09b2a4ce9ba3ef8630b4e01e3fd5c6c24f588ebe44433682f5663e2df2b6978640bc2c3c1763c69d75b59efe68af8cf516a32cba1ef8380cdc72a3eb9d4d217fcdf7136e68b7173c2870e245808ff35b677587b3066af45a6c97d340563c84d107eff4d61df -S = 6015144a01c388c92bd4913907fe075a42afea023989156b840a493f074d55164405e50a4105d5ba9810a9c761f4626e6e05bf7ec4b47b07ad459ff404db6931f4a994a1911fc65448163d369eaa61674ce2112f79a7a9f541f26a111a605b9a3aeda1db6627c59bf723d34153769d18d9ca724570484583b37ffbb11bf7d4be -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = eb2a75ef219b2bec0987c2623a76a8d3c292754519c47f8d541aa8cd9b6c7b3cdd3f7825c2e9ab33e2f684eb34cbe27ac98971b1ba34364e5f15687dc15c829e520a9649dc0ee48fb8aeab8340293ffa869b5c8e4720bae91a3ce140ed7b3f1db25478625653fd8bf378e03346dae7d9638fdfe5a7d032e6ef59bc1e070fdb40 -S = 45d7f419feda3099092973f1d61994225fec873a0467b1348776a3a6578a10b24be941000311519cf426aa8bdf45a300d7eb31766e0516988cefb14f076c0502a9f7421ff4965875bae992930322d34555cd32ec47d8e6b1ddf95cf1eb193ef3accea5db5343a80d0d36d4325361c7180de57dcd80929bcb9fa166ecf930113c -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = f1cf2ba2463023a1d329957cf3fdc044ffecf8ce0a11f9b6ce8b7ba5e5db07d03d8d08c1c61b255a6d0ece174e661593253cc04e06a69cad4fdb1442da97014e77c1c484994c93104f5b10d876a820022e26fab68ae57e258c36c9ca501106ef87b38674278b14cc61578248d48b889800f2cf8ffd9748266ce6c2c4af0fbcbc -S = 22a5c4a08adf1a8d1dc26d0a3f02af5f12062b82e10743fbc2ae74b0bb533de279bb57bb6f0a44f9b79c2621c426e9e6b5f50a5a8a2df9d46ce9fdbdd0bf6e74cbe2e55682046145a7e40622bc81ec945e8b87a8a9b9ad711e7626109772b64be7a7ad7d5f3b3aad20c03eb164716b62e0851f1041930d4e5ef4b50bff82f425 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443051300d0609608648016503040203050004406aa75a3539ad3822952b91897813389ae2946b072578bea95a64f583bb5eb9a27a8e44c2405a9681d9a290e2cd55fbd59c381039de0e21ff120d2a3ed8889277 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = 8b61c39efa507e17cf4d575bd600286d56a40e84f35d6c06d3cc33b400e161220df1c86bfd0911226081008cbfd4fa0c3aafc4de70478d089ff02f8e0cecb2e6a68011abe64d4196f9de70a9217e8bad594c02df3891cfe71750b509761fc59f9c3627c77ec61759e28c2e1cc4a5e339f9a451ef12e23b8983154d8d0524a437 -S = 088942923512cc272b5cd0b40d4aac42ea3165c74c90970ebdc46b5fa8c0b0e153f85c446b0a2d3886c7fd468a47efeba91550c7f01167ce009a4d6a3069bb280b6755eb9716c03f64cd2788555b9f8a0e85d74879dfa9c48ba3ff2002a8b0de02cc8479ca2a59966994d36c6622f4297e2a26cfaa824e447a6badb92331829c -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffff003051300d0609608648016503040203050004409bf5087cc76d346579861f84faef10011e190ef00bfd9b708719d5b672952c0a5f5a8fea8c12b2d738e0b420d785e6a02d7352b6a0e3d20ea2c2140094278b52efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04f7405154be02c482bf07115b27fd7f988920d8207937bec317f1791c11b0f2325851c35ce42bebc828c946438cc22656b702cce2a0dad6d8a5ac3fe6fd587c36f81ff5edc977edf9c6c085efd73510ddb2532742367f8f878814c1714549dcfa17dbd5d1e17ce3dd1a9893a3785bc34c5205df3978071aa36c9e86bd33cba1 -Msg = a6cc1c55dd9b8da73acc6716344503690a9db27bb439518719b41da28284c9894fdbce9de9cc032cf7af6df2d5c658e04121a61c58be6848c2f5ab07291394bdef46b09720b985cca5ff6d22bbb5a4b3a4639ff19ca49fe80f8787c30934ea92eed3694a6ba93c0dac840eacd05a0e6b9a2d430469311fee6a3158de0c2ff38f -S = 82f547779204eefa0d857ae077b2e02e61dc76ee75e709388ce33b3f227dc96c5a98148a816a4c954516a7e44b00b080cd8b05cfa4ae9ff82d64b811f62e6752904b88c2e4a9d54088a49d2d480c267b96974c46f75a4fd9cf09acca14290d6515defc75e0807334cba3f492d42a17dec01396e39d7d8335bb4d11a1c19db3d2 -SaltVal = 00 -Result = P - -[mod = 1536] - -n = d2b6c8fd44e7eb621fa6685fb62371872b5e8408af51bd1b44c6473823402418a26963b98e6fb191cf74175e64132ae6cd101133fc002a89c10bf7739eb930b9c067b52570842395657f927434aa3acbf3369dcdc3990f77cbf22939ddd5877f09c8aab818b80aa20544b6928fe62c78795a4160aecde6ab454db0dcdf1d6c13522526c5ccf82d429791059306f02cdc18c4e580ec6c2da19b3c6de63933ebeac79010c73df95748d987e96a0f8ad523b5014b33423f55922aec2ec23b9aa22f - -p = f260d143cff1e8e0931765da8cb335c0206bf7fd19aaf8ff41e762992f2bb0a660cd65f08a80fe502c9125166a6927aa1859a874159796fada835b48522f5795ed1f8d23f05016358ff908b0dd638bb7ed12c8b80b46aa858d52c77bb7fc0ed1 -q = de8e674fac0b7ea32d518a22030fd10d4298a77974db8febe195a4240dc5373e8161baf8ce47dc4fd076f64e307ea6262c35b9819bac4f142b613973eeb6a62a15a2ff09fba9ce4db7186969af925ee3acb7d3be7a1f9c85358216640fc1e0ff - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = 95e319c0df793cf1c1b424a8949b9529d6c1a0cece5f6db573a538b68b529a9810830a84d7c8a3b9747d2882585845653c3e179ec35befcc5a7153e96370467f9448ca1999fba2f801f65c0857a18f138f356233a5ce4d8d80c1243c1c2f518ce8da60696d38c21731c6ca23db9ffc99974d8777bcdf1062ad3bb198fdb64226 -S = 1b5d13124f4a0ba3b4e8f102a7044d8a633ea025729f55ac75e4a8544612f229d4f43c45574983b51efc83ab611a60b009949dd032c97358bb7ae5d3b2ce417fe11a9f6435b84bf7113b23403b010fd749838823450ec954f6e3f54c13db12606ead2eadbf209d5d31efaaa0924f256d3f64692db8a2b7fd8197df13c33b160b2f8fef0d4f2ccdd1e1a5b269b25e4efb462c000573b8584d45c2cafd248348f19cf1f7422abaa402ba54274b7611c4c9db3a7dac61ce51c396cc3c59ecbe5594 -SaltVal = 00 -Result = P - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = 7271bcb91b18288e874f4c04c10a21bd35150b1813ef61a7f4dc29e4c036231fcf040abb4ece169ae5afc5d696abdbb2e943a7d0464789a4a2ecb1285e1e29d16b1716c2b3313b41b4f8be676e842f1b8006c6418ea0ec2ee57afd5f62124d6b90d3693710ea9f693e55c01f113c24e04385efd3b2a3932e07ae96f295b996d6 -S = 6b9212d017ad9f4bb7ebfa3975b514bdd22240d753fef5631e1c216bc750336349255d53b857bc944d3eee3bc82805620d770e41dcba45869f47d36343ef067cae99a941ab94948bf0c02d2a3ee403c7eab0f9d6f9423c166e62c2dd61198046944b5082db4a17843229489c46baab712416e3d0a685d2353abe010c94ddf7b47f5edf1fdfc9a5e0de27d65ab5dfc9f2e660d20d169cde3e2642393edd79fe7316ec4ebe61fb88223f6711e138d09ec3d76781e73d93e7dba9830c53cdb5b0fb -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443021300906052b0e03021a050004147c3d3d4d94e5e297419551f26b517d0046a98d9c -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = 1484f58f6b8cff56ab4b81d17967dee7ef1eabeae57c11706fd2735ea6655145ac636df2ea1b2c409c6c3e31907e813d2ab123eaacd3089db4966bb00741c7c48ca5f8599c539d9c790cc27f1b79bc0f331c53036a872790e9cc4c851f343893be34dfec079c1c11481253e4a3bf55051048835ba50037f1165c5f0478a76b5a -S = 57b3646aae17304bcfab8b6477bbcf791ccfb4b20001b2c3cd4e6dafe129934f2c401b07eada6a4b2db9393ffed36a8ae8af85b1d433a398399fc0c2956959e99c12053ac3346710ea5d9119fa4757032fd1739b426e879214afe364a9d274d383e4d1fa64b0b07c6f6014dcbeed59ee0dbcbec90cb5f3133daeb829855d61b88777d806b5717227a8016a965f1bd2080b44ef80bdbd0bf0c494ea7baf09295aacf161c433320fa81cfca5ba44a71264a1d1db1d2f5baeb58eb9d623710ed1ba -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = 957018ebbf4bc279aff3a28f87510c01666122399490a4c300680910ed6ece73e84b0e70fd2b53362a63ac6a1456ff26f999a142e65524d22aed70ef0ae115bbb6f3e09f7c88add73c507b311c29c6117c4111b92d7bc2c7dd1532ffd687054be9aeb700a4297863cc043a6c079308cad8a19926d0cb25ac032677c8ba28442d -S = 7d9edeb96e2eb21b32fc3707c42fc26cc2ddaf5283ed2853206e51594027fddbc82260dfb3e2da03dbec1069f0bdc63a7583f0ffc194ba158860fb0bd13dbe22ed34f7f77821b58ff1b6d9a6721f91914d3529d5e605b813f7de832afbc57d7ba570a4af8f9ad2b7ea8d2c1656c669e1df7d3c112bdbe212d37d61ff62d03d8b19426437a48977ea5aaf5eccdb7d90d1e8a1c652cb2333984cfac0c1432e42fb16168a3760328039d1a836a52baa9be92050e96dc86d37c8e0b0684d445be018 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = af0272c90402a9c27f9cf6c9de652cb7a3a402b4695a0c58777fea11958fc0c51f45e6b857a6e0afff42905628b7aadf457669ec83ca80af5d16544f6a5e688e7a0818aae2e48b80146be3f77344b69c650dc28aa957dc8debf22a87956c9212e9d472664dc3927ee59e5776671539382bef7657820a083b499dd57fbec12797 -S = 3cb0d524151a8e3210123ac13086c6299074f5b5a4276059cc2e741944eda31a80aada9427d0a7e49823632075093e4f779f9b84ec4f159227e650c267cf7126047f7d257dc6e41ec6113570bc231681667735d41085ea92a2b9197fac8e4ec9bfff1d2b16f65ceeed22741a872a05afd641b1444a928a948d15248b119f28b3d35e28a337096cb7bb97e7e3d73bf1cf8abdad9cbfb84481a3e124b8c345a2d1065b1713de71e0ef6b8beddb6d88e82379960bdc1cda7ebc4c4c4ea9bd1d81dd -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = 3797ad7bd2b5c611a7b1a15b8337058a1e2c15cc42418d7b2fc949943fc8076cc64c6d9e3c004e489efe297711e5f2dfc92b15d029b5b9652ba541ff037419f1ff40af7db267bf005154d4695d990cef823e1b04c0599284c8df6233a9ba9b66ab1c7a007b12a3a0895cab19af7cd923130d2e504e56a241ce1fb11978c31632 -S = 0a34ff5dd8d7ef76bfd56bd4218ad50c22cee0af0532674427c7e13f8b99b86e7128316bf2084c6477180283a7b3f4f4aefe5e0dd4aa136a2920ea70eb23b0e8b8b2c2a2c530f4efa1b6bc59d2a83547cd5c4043ce497639f609f05f3d4d2099b07d9bdc0a15690b7bf2da73def963eeebe118e59ead6dd89f0fa271645fca4d9bf220080a850649f48709bcbcc1cea3fce9618bf167e2fdb13a1ed50eea093d1070c5bfb162b054317f2e41bb3099c39d8e2c7b0b771da05cb7b7bd1abfbfa8 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffff003021300906052b0e03021a0500041486d9512b229032778b2d54e07bd553ebe7f36713efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = 95e319c0df793cf1c1b424a8949b9529d6c1a0cece5f6db573a538b68b529a9810830a84d7c8a3b9747d2882585845653c3e179ec35befcc5a7153e96370467f9448ca1999fba2f801f65c0857a18f138f356233a5ce4d8d80c1243c1c2f518ce8da60696d38c21731c6ca23db9ffc99974d8777bcdf1062ad3bb198fdb64226 -S = 19ca086cb98c4770fbd6b70206c3896f966c968c1e5600a2348f3457fa823f053b45b75f0da759994d5d047922efa5184fd0499f57be607a9ac63a1926f8317e6845934a37cd58c07831a970d9599dcc15fb50c629caff451c96e2e2d7f9e3842e8dcdb8011adc8f5cb1c01392218d62285442d9b651b2a0369af3f99343dc8e24fe4f93fdd490636e78ca1b7ae73af5ee2bc0ab6a0fb42ef612c3260f62a1577c3b41bcc25e8feaed1f53e0d85c8155c9c38cf72385ae28e96831f891e03ad3 -SaltVal = 00 -Result = P - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = 7271bcb91b18288e874f4c04c10a21bd35150b1813ef61a7f4dc29e4c036231fcf040abb4ece169ae5afc5d696abdbb2e943a7d0464789a4a2ecb1285e1e29d16b1716c2b3313b41b4f8be676e842f1b8006c6418ea0ec2ee57afd5f62124d6b90d3693710ea9f693e55c01f113c24e04385efd3b2a3932e07ae96f295b996d6 -S = 843e9f1f0a472be4a3bdf456281eda82aaaa08a0fab173f2086bc03f8b88c0517f457bc276ad144c1b53084d736f2077b0c05f451ed6544a36bd26e902592b384c6d33587a79f2023226fc7c52b1384bc6dc83360769014fb5110245b2395baeec2b3087f6b6eb5de706d08fa7eb069c749a56b91d43d1ccc8f1631a597beaa6486a618b85a2982eb32fb5039584c65f7f07e7c31663a06f48941878f1ef4cbb657f18cc85db6e9d1c87ff81fa7b1e63c74abda333de6242a21a43789749bdbc -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff44302d300d06096086480165030402040500041cd6266f6d4d47969031bf6bd3800efb1332f5c75ba7d91394de470bb6 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = 1484f58f6b8cff56ab4b81d17967dee7ef1eabeae57c11706fd2735ea6655145ac636df2ea1b2c409c6c3e31907e813d2ab123eaacd3089db4966bb00741c7c48ca5f8599c539d9c790cc27f1b79bc0f331c53036a872790e9cc4c851f343893be34dfec079c1c11481253e4a3bf55051048835ba50037f1165c5f0478a76b5a -S = d140b01f9d0d67a4b869fa67c115919268657f97d846886f07174fe6a30be909a74f1dfc4590ea356e349bce40547539e76bc9011ea133356c6f01b7739126c8af29e307966bfe39999625ef989faf817d0ad6378fe5dfcd5974089349d977c7fec62289b760b4c7679d41e463be7e3f996cf1f66e48cc004f5823b1f7a94524abd06ff35fc4f51fe6bd16dc4b43eb360ca18b4c4e5a33440d748dc7fb1ec3a8344f4e175f52479f4d93275e03890664fb3a2941187bd023a3a277fa840986c3 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = 957018ebbf4bc279aff3a28f87510c01666122399490a4c300680910ed6ece73e84b0e70fd2b53362a63ac6a1456ff26f999a142e65524d22aed70ef0ae115bbb6f3e09f7c88add73c507b311c29c6117c4111b92d7bc2c7dd1532ffd687054be9aeb700a4297863cc043a6c079308cad8a19926d0cb25ac032677c8ba28442d -S = 10699cef91c348ab96ec062c0a98bacec04aed2bc2a806d8553258ebdc999abd59651e8aa7236e50eaf0a183e278a956de7ad6c3eacf7e5a2dc1e46a5fc1ff58d09db56580d924de5c3ea9863c006cd9f1556555b024a670c316d2de697976a3ce5d3994a758220cc83cffce43f7ce42942c3caad5a477c494d9581185c4e5a69f056778c77784a7fcb246f3edb1cf93bd416057d0c2ebeb36647ba8796b50ea569930132d189cb43be8405ea210b8e2266807620487791839d0e6ee4dcf9d63 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = af0272c90402a9c27f9cf6c9de652cb7a3a402b4695a0c58777fea11958fc0c51f45e6b857a6e0afff42905628b7aadf457669ec83ca80af5d16544f6a5e688e7a0818aae2e48b80146be3f77344b69c650dc28aa957dc8debf22a87956c9212e9d472664dc3927ee59e5776671539382bef7657820a083b499dd57fbec12797 -S = 90277451b160d24cd2df6e5e84e2f90a8fb6208f3395a305e299d5005656a153d27801084f7cb76fd0e4b8d118f84214416bc65446cf41fdbb6532c07b718ed82e34a8b5b52575e39de48e65eddeced22e5556d89103960a228df0efb047ae0e1569e579b477b38198045bc3f4cfe021dc9bccc33f10d3ea30a01c7c567ab22bd2d0bbec9c57dc990bf0ef19fb5942f116ed33510ff76405ea1cd99c0b47ac687d8c66f9540685d831302c272de04b4459951ff480f99dccbe3b0c01f3330560 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = 2da2547df2b14d5f28bd5cd71250f55cd840a11e7bd799470e30938124e4dcb985e7a72325aca57f5690d59a3c759e1781ad1b6f4b1bb6376b94f8a2d88b9f465beef1238b4b51e1fc371059b4f08557de41609ec3a63b2df5b172c1cdac359b1880db830ed6790d847bb41b6209d3a356c419b3cac251b2144faae8ed8fc541 -S = 8866a8d6767eb3a88cbbf6075ce1ff085e541e3dd305915cfa2ebc94ce8d6ae9b7a76d5770bd4e96b913fc41824b59f3066471b054f744efe0fda0f12fd1413b755f0c1d93fa3bfd00dbac16cd6c83a947d71645aa3828b7452aef6b68a92f83dbb48a041ccf1905e10665e186d5aa85e502b36dacfec5b1d17ce9500caef5e8eb8b51cff080368b75baaee54886e602e722d2b9d04dbf05026624ec6fa772830090c570c5b8ac7594abe3ab312d46fa3294dd96ed9c2642672154240e66b197 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00302d300d06096086480165030402040500041c9d529ed5fc99f3b9f2d3c3abce14aa723e6ee9397db13c35a355fb87efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = df8494995c51a92e651ecc6229ec4c5ffc54b2975876ea582233a3a02f9cf73207a94fe9e92f814d0f0c3c6432a4a6cb51924304af9719121bd612437344a14e6b5aa89d8b0d9aec77ffdd1373f77220268fd7a99e2c2c61953396e8f37ae1e894fd695d4ad33a3426607618f3cbf78904b2362e301d6b6c1ab1f637b627fe28 -S = 8474bb2649667bea417d1a51fcf6cf891c29d838c7002d7189b945b53436cc0b67175e910e2cdbd3e1855326f7c0c823a8b76d06b2ae1e0bc6a835a524401b5a280d07f09acd94ee745e1a789919128c617a683d1b145b3adcc494aa701c2fc5895d14ba6a7798c3fa51a04497e78413200b284a4b50bd82f0b7a1a4b3b5b3cae15e345844b0b7f155e48bc52fddc2a83648b2714daeafbd0c8c36de1165cdaa75bc8442b681b9ecc1cae114e629b13956734aef0ad11c421ebcc27202df5899 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443031300d060960864801650304020105000420351b72799b9cfe54802309d2be3fd5ffc3377302cb171d35af0d486d4e664516 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = 73a012bce858e0ae42fa2893a0fb1439a73a9c101841b28ca8c8bdcb0c7b497853fefdef782dcda238a871bb218f1503ec8a52020c0d5d6887da7eab05c7c4f226c1f8321911cf966bde63251cf3e49ff8c38ba724aad027f876ddf10c2642a296f2eaccf38b4e5483a3e818bab0ebd574ed314989a27594a2a6c2e44b222b51 -S = bd0512605f506b906f012de9f50ca56881c61edc331d8b36996b4eefe75b4751b6ff980194b52e19b82dc85fb3428c86905aea1e59e9db90018ad5471e29ec170f18b9668725a562caf850ef41c7ab871448a6f428db6b2ddf85fddf029dfbbff5677bd92aceaa9372f9a579a2f7fbfa8872f8de3f7b15c5095598d39b3808f99cc672d89171302a7e7c3430a1ae675cf3d1b3341f432b4c57a372f9be3a06970f2c4ee3f557b98a8e767db450ff29a491163330bb3438432c5dad3dd8dffbd1 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = af51ab7e521b64502702bd561e40dbb41e2f80afa95bd562bcdc67b3f6e36f86fd9256311e11782f33de2918ca64f5d083d02cffba209fc2667ca4a141ca60c02a7d4559c7add9696e6db9aa4659dec2a96e20bacd1ff8b1a4a48ad20096e383fbb97fdf96190e67a05877f4da461ef158b263c62a806b973cfc222f7b6e8037 -S = 6ed6b46b522f09d6c1007dc32e593a2dec403c5f318e9ce0edbbb2ca6b9b05803ba43c1828ce2fc0e2fe8feb4f80db80e1673e111f204a6a009c115f0a797006bdfc5b5258404e259aa0f9d72957d01f92b756daa9981952dddb0bd1b1aff6caf46ccaaab62a15f52c79fd663ff64b94ab8428c04780efe11ce1a210acd89e63a26f4a48b9e4acf7c327521a9654ffcdfe03c6baec5cc8bc32731d6a9254302a69f56bf43ae8b82738e8073f073dfc8c386d9adb0f1acf16e59710e4e519cb42 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = ae4dbe3079ef09f963a3da04099f596a6eed3c979d798eff8f69af0d4eac9d5c5bd6712a4d2b2d0abcf9b4d85d2c1af26e1c1ea555a9f5e6848a4a439fe28219e1144406bcd939a1bf901069bdd5c6fc2c54248acbdf898888bfe9a9a048160a08b13eac0c22b528360df59e71c2e4ef6e3e552c4744d04e62b096279907e098 -S = c7ad03de788a43496f2ebed7df3179788360095e880785bc5f9135be256cbd7693ff1c47d7dc74e1e3f318a533ad50850336d64cecaf1b6b6a317332810d433362eff2b03b6730df4a04ac3c69e18e752577cf8ba9bb0981a2c6cfc2178fcaa3bee1957cf10a74e87541a3311e40206457a11efcf76893f59dc78cde650b0571072a9af5500dc76cfad2bce35057768b97046adb84a67efce9d9f569839e3f36541cf0b24862f8311796edb735476eed85d8290619b56237a89028c92b3eab48 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003031300d0609608648016503040201050004208aeae1f557c4b574127603b7da392e75ad6df1b94d840cff18ca38033d5cd0f4efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = 9245f9e8a7b4e2c8744d5bd42ebe68ca32426a5cf7c5ab78414938cc9888ef8af9dad868cb5ab9ec1444e4e6eda2543e3428f8ef805c4f545afa35a3aa96fdb76f83bf12b3f4f322bf613fc38b2c8e0678856230418b6b062fb358488d6eed7c5c0656ec48c9bbf2da6a1473eea43faa68204f27239928172a3e49c52b58e861 -S = c9e9152887b5111f721aced7cdb0e7368b0eecafaa1506ccdf35c378b633937d08544493a1e8aa84b5b7f892d89976f2ebfd55ae85189f61fb280ebfff5a01fc2c90fa4896ebdc3725ec472631e69d35fc9d5a03447941e7befe21a36ce5cad72088177d7e54cffb60dadfaf3800ca38e9751df2d4fab7738f31d82a944e0f3bf652197121c4e74ce5f170fed950f7a03906e75b7fe12469fa4d44fe8348d5459bc5f5f13aa694c12ac64912a20d694230ed95b75f3de4eb0c3c60169695e94c -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = bf15e4f37e28f61a35be4539f17d70c75d3591c19368b84c320a999cb1858114f3008faf1be1209ea1908b33a67e0ffd84670935aad46a58a7e36916844a756b579a6e0c15c11404a8d3c09f410a5287f00b6a2d726adb6a4a715c67131d81ba146aead115d0bb94710e4b466d2621acc8a91c729334f1ca433bdb5605058d48 -S = 897dd26e35a3833b069c14e173d8f90443d51f3c8867457980f0c20420568290a2e239642fd21e93778dfea2bdf3ccf72c3ee8f4334394238d52fe577d1d050dd69838626922ed9af276f888356349fd1ca8e9c17d615b9d3cdf86e86d01eebbe52dbd26c034e8a93fffe7cbca27edb1d03b13643ed4ad122400d4f980ff7b8a9864d39e9fbd5781ea4d21a06136b70a90fe2bea2ce142334403bb078095f1257df2162e9998a7268d1f05f4c483f726b9b0cfc132023c643b1b0b04b6d88745 -SaltVal = 00 -Result = P - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = df8494995c51a92e651ecc6229ec4c5ffc54b2975876ea582233a3a02f9cf73207a94fe9e92f814d0f0c3c6432a4a6cb51924304af9719121bd612437344a14e6b5aa89d8b0d9aec77ffdd1373f77220268fd7a99e2c2c61953396e8f37ae1e894fd695d4ad33a3426607618f3cbf78904b2362e301d6b6c1ab1f637b627fe28 -S = c7fab5c4083fd43b67dcc56c10b5f9a4793ae49411b828512e4930765f496e313995b506e6b2ed4ceb29eb2b9a649e18a1c9f22fa5c89f7349bd7d8e967c3169fdd120517834c0aa355b5bb85b13b0c1fbc2e915c9ac8d7801c37cfdcc45376d8915ab57a67cb39fbe3c976e49e3a47e2312dce0b27ebb2baab9214a7af25482ca1f7d9baaca22ab73deca082b271044048505257c968b131f5dea33c1d02bd4ced74b6c0cf71cba31d989c685e9291789d2a5e906c52268a270ec8206e3bddb -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443041300d060960864801650304020205000430ee9e3e985b715474d343f9823ce7f3fd430e13cd9dc4d9117c1a7f1c87f40e16a1012f103c90db1b979cc17934b20756 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = 73a012bce858e0ae42fa2893a0fb1439a73a9c101841b28ca8c8bdcb0c7b497853fefdef782dcda238a871bb218f1503ec8a52020c0d5d6887da7eab05c7c4f226c1f8321911cf966bde63251cf3e49ff8c38ba724aad027f876ddf10c2642a296f2eaccf38b4e5483a3e818bab0ebd574ed314989a27594a2a6c2e44b222b51 -S = 28e465b1d7e5e227ca3af797f7f4606a4d78fa8037190e52819b184bb42237b64854c317e08bf3e6ac2e544eb58e0e318682224623f8912682c9afe0e81e7d9f027105c0da1c2b5f27fb24089af422f559ba97839749bcf9e968dca0e58213a0ba53547934804a1e10db9da4464ce7800e5613c89586277beaf69edc62a3e8ca2a8935ac4d0b4d65e7ebff4358be37102a70f327245475bd6673c7d092505f321cb600f6df917c6873625e5d3539d95b94be06d39f90eccb424a9e5acb27f0d3 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = af51ab7e521b64502702bd561e40dbb41e2f80afa95bd562bcdc67b3f6e36f86fd9256311e11782f33de2918ca64f5d083d02cffba209fc2667ca4a141ca60c02a7d4559c7add9696e6db9aa4659dec2a96e20bacd1ff8b1a4a48ad20096e383fbb97fdf96190e67a05877f4da461ef158b263c62a806b973cfc222f7b6e8037 -S = 198f72795be3be9f70828fcfa6fd2eb286f4d996153953730f8195669840b685b1854ebd54f8d1ae8db487802f8c6978197822157eb45c8085ae91f11390e0d8910f2bb51d1efbd743e2e7d7e16c4757a67a666c1e6bbb90fae924550847b68e41bb9d8b58b376c70c075cbedb2875bd7789971d2281ac3a591c7361030dd46afa79ef20a32f68764d40f4f5d689f3686967e57f1b718522a61ebf35e194219f9b044aadccdf0fab455be9f86a651bd9eebab4e8c798c9156880b06f12ca6b7f -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = ae4dbe3079ef09f963a3da04099f596a6eed3c979d798eff8f69af0d4eac9d5c5bd6712a4d2b2d0abcf9b4d85d2c1af26e1c1ea555a9f5e6848a4a439fe28219e1144406bcd939a1bf901069bdd5c6fc2c54248acbdf898888bfe9a9a048160a08b13eac0c22b528360df59e71c2e4ef6e3e552c4744d04e62b096279907e098 -S = 14f03b08b6e55a8aac770701ae964a627e2c35a6e5b0a086cad74eb7cfd5f30c2b481b9a23a03e61f9a73ea131ee9e0d44ae896fd815595adc40a7f719e37d453c6c2ac99f5e76665894fbba102102e31a4fbcc172d523a0feddf5f0098949041cf5c6dd729882db4a3104062f37fd0b51f990d180fd58c2894d9c306e001878aceab5ff4376b98c65864e2216702b6afe97686498732b6259a85e60e56e184515d8326d7ea98508566fb6ff79e771a08904918f19562d28d6ae334b9f15104a -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003041300d060960864801650304020205000430d641c0a68fa8724ce04f866e4c8d232b9643ff63669e3ba6b030d0ab734710b9d6ae8c7703bf964d4b827d2098fcb79cefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = 9245f9e8a7b4e2c8744d5bd42ebe68ca32426a5cf7c5ab78414938cc9888ef8af9dad868cb5ab9ec1444e4e6eda2543e3428f8ef805c4f545afa35a3aa96fdb76f83bf12b3f4f322bf613fc38b2c8e0678856230418b6b062fb358488d6eed7c5c0656ec48c9bbf2da6a1473eea43faa68204f27239928172a3e49c52b58e861 -S = 7ea67611c9dec51c441cd3b5980e566f13e1191ab9acc5885d12e04c231b8ab7ab1bd388cdfbcbcd6a8c175d50296483edd4415ff4220b6af620e3ab5d2561c0db009e2ed7b094c8ead105d9067ce25c555cd306f52f183efe0bf3a618c5d52b9517ea948cc1a3dc43cbab21dfa74a44db4a34f8ef6aeb9e7fade424122a96f587a5ea94dc9b7399485d2bcf255826389209a89d5695891bae7bcfb22e430a3f5324fbfe79adc7f7fc5b143b86518022a96902fbba5a39275650d8028d3bf144 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = bf15e4f37e28f61a35be4539f17d70c75d3591c19368b84c320a999cb1858114f3008faf1be1209ea1908b33a67e0ffd84670935aad46a58a7e36916844a756b579a6e0c15c11404a8d3c09f410a5287f00b6a2d726adb6a4a715c67131d81ba146aead115d0bb94710e4b466d2621acc8a91c729334f1ca433bdb5605058d48 -S = a7395ce62131a5eac115ea950fe60953fc334cc244b13b159720a502b7194c9e65eb665e6475e1e19e462b735496d65fa8a5c16162d97b11656a85b43fdd4a819ae918d79e50e51ea1e9f5fa92f467410c61d50ce2e3b61f59be2c88cfadea890b71edb70fa87e38df81c38d315b33fe4ca4fdbd5779052c16eed21468a03b15fa7a235e8f6831ff55fe2eaf79eaf466a2280eccb8139dc16c8f296f0e79a1bc4784f37e6550264d7e26a8507b97b1e279f644a29c166be2c761e1ddd7cb6611 -SaltVal = 00 -Result = P - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = df8494995c51a92e651ecc6229ec4c5ffc54b2975876ea582233a3a02f9cf73207a94fe9e92f814d0f0c3c6432a4a6cb51924304af9719121bd612437344a14e6b5aa89d8b0d9aec77ffdd1373f77220268fd7a99e2c2c61953396e8f37ae1e894fd695d4ad33a3426607618f3cbf78904b2362e301d6b6c1ab1f637b627fe28 -S = d1d6a615340ccb1504625ab056d09a95f42836bbee98bbc1ebeeef5296adc55eb8159a5dccf5fbd9bab8854bdae4f9c73379881adfaeab1bed26a544f4b56067d1c29f473ad84486a4e48c51354e4b1a9c9ba1aa019d1c75c277a2dc5df6ec4e112312c93e5652dbe107270f02805250dc77e833637c65f2248e2834b7cb62135b43730a54e0782822fbceb33073912728dbe0da834342ff7d519404c1171b347b96a4df6bf794634247e4b15b93d7929a0e1852dd20b6c88b4f30e0a18be8da -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443051300d06096086480165030402030500044027c454d298019b1b6718f4ebbb3e2d115f3ea8a214cc95367bbe80783dbc781438847c4b1508b6010de44f47ab6e213f32e7348b8e6d6b4f85fbfbd3b4c6e05f -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = 73a012bce858e0ae42fa2893a0fb1439a73a9c101841b28ca8c8bdcb0c7b497853fefdef782dcda238a871bb218f1503ec8a52020c0d5d6887da7eab05c7c4f226c1f8321911cf966bde63251cf3e49ff8c38ba724aad027f876ddf10c2642a296f2eaccf38b4e5483a3e818bab0ebd574ed314989a27594a2a6c2e44b222b51 -S = 3a24d99406cb5a02ba7a403dc0b5b2bb87984a3feec115dfd4e5531993c391294aa226761a02affab891886acc356160bc9543f2b722412392dd5dfef65688d8084268278eb04482eee60f72a34b30376a8395f5f3fd27dd56e7a8431f2093a8ae93c02674409c492b52a1b0c53923672db546c85ce5e2e160c94e78a5d66dba5c398b97585a20f3b32ac35a4216e4b93fd85c3fc5693fff06eab4b9e0495c5ab0d93bbce6b3e16bcd9bb458b2d7b4e30f9f4a52f48311a26e3c0e9ae30e4872 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = af51ab7e521b64502702bd561e40dbb41e2f80afa95bd562bcdc67b3f6e36f86fd9256311e11782f33de2918ca64f5d083d02cffba209fc2667ca4a141ca60c02a7d4559c7add9696e6db9aa4659dec2a96e20bacd1ff8b1a4a48ad20096e383fbb97fdf96190e67a05877f4da461ef158b263c62a806b973cfc222f7b6e8037 -S = ac7598c1f1f9245d59b443cf44e1eaa00f9a213ba24fffe3b6051dd0d9f430669edeab9157371eeda529bace4e66f31f272b210b5b9308d0dda403385238d758de9d2099c516e39cba18a1552059d9eba6deca27db71e766ad67b9db321011b727619bb303df82bdbf029649300b03e0ebc3208b2ea8e290b670b2796b4ea12de9f07e6185fe508548d2516ee1f8997394079cabdb6bbda455983169fee7cca71eb4c5841c27c37762b985824134fea46bd2c95d7d82abb66894c6671ddc45d4 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = ab50f6312f99e068e4a76ed88efda9b0acf416b30500e798843673b1450be4ccf05f2f5746ba4ac7f9d5993ac15ca95aacf22085b676f42c9984dc79e63f0435554e05e859251442f88679b9da474474a0553b6877f916c1ec5aef830244f47181275f2e9263a8a289c2f89f0246e2c42f264ea27013b51e24bf9416c0a01a48 -S = 6c0b09fd6b371212279378f8e3d91a4861c63c7353e5480643774821ac72cb3519cfd77e46c6edcce92b796fdd5a511199e9b870087fd9d815e7d8c8deccfc7c229b93a038e202e60df022d0a966e6616c67a447cee59b0b3ca206e9e503e928dcb33160b9b21897e24d860c7327e83f15ca41449f7aea16a3e7d83faa458dd0f27117e68bc279367925a42ec8cef69cc1bae1df16408ca60b8f1b9fe9f837a1227153b59ab2b3707c1e5cffd79d7c11a31a81f41317f012b497e34d4b3bb962 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003051300d060960864801650304020305000440c4765be0d27a4bdb86ec440bb5259aff46c9bd89a6870bf5b87c3755ce45d780c63282898f959c929d9f144143a038c36d4d0448ef8c4663cedf5cab3d59bf0aefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = d3d03ff14b9e72bef1c6e7d29a5bb8f0ce554cf3cc867a63cdd0f1468d94d738086db0be811f82d8c9ca36d5be64426b126585074ec4726216237155ae4782eebdca24c35114758624879ada1efa61651a692527edeaf30aa4e3eaba0e7be8b67b4e63a8c26594f28965db89c0065f066fc7f5fab2e143820179251cb5194fb9 -S = 81664625093bdfe332db62e3c1f5ba000062576d95f1a82dbc5043eaa267d7602c25cb45759ae8ceb360c017f9a0c4847763e25206699792af187294514bb214a453730350673bbf2feb73033a567d4d11a6a4a13d2d1d79850bd71e4ee9b8b404d2114f505ca695a760be6b1a784be63a208edeadbd1a22c86d8ba614210d9b01b89f70243749f5be9b43385ba94ba0797219323bb1817e5e3bfbae02e2e360383e333b27c32b6685e6b9545a3a6c7742a7e0612f20bfff18907c58f3fe671e -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 076fdcedd54168af223f18c42188c7c5860c5f03517b5b00f66159dad4115297752adf60e6e8d614347f9466b83ce96b88be4ee9bd999b19f1bb26d9ea7f01b84003a907584cf232730480a6bc9692a3cf5c47d40ff051dd133ec2353e0a8c4fb6b65b5ea82aba7686f2aca7edef2b7e824b4dff3a5cdf2aec1c726d8a3dce741605abe0a0b66047ff6e3e7a1be8338af56b4cecd1e650d4fc3c52f56f29e746c7b2ec95f9dbd6dfd1f822541fb6f331faefdc00a346e86b2dd6a88076894b91 -Msg = 4ff4d6aee37bbccf415b68228612f69eddea178398c0c13d7f0a258b6719e2e0079b780a0863ff115b6d1962cf1c252ce3c7b50bd87442e40be31f1082cfacbcc570cc8fef44998e040f563d8521a40742d7f9e070644f29fbd119d41e437bc8307dba87c1a5f20ee54b07fdd0a7ddf7a322cc4c86194ed5f7ddfb2061feb8cd -S = 303e5f73eb2125488fed92692fe597994b86e4189ef71152bbe277501866f64df9de78f3d11d74c6aa48a916ce2759012ea86a862966a3cb78d8ac12d0d99d059e8cd56e83c0f5198ef7248059510687e3943fd41defcd58ad501976ec17fd1c252c13a177cb99d2ed831279d6cba8ca63ad0929eef4fcc85c985bc449030a76aff7a2b389d23b89471e21907043eb6c973ed375d85871bcc9203d6c615fa78a066e7fc5ac9f8f7099ac22d5a8b26d0608df22ae0cdbabeb81bc6f750a61f5ee -SaltVal = 00 -Result = P - -n = d2b6c8fd44e7eb621fa6685fb62371872b5e8408af51bd1b44c6473823402418a26963b98e6fb191cf74175e64132ae6cd101133fc002a89c10bf7739eb930b9c067b52570842395657f927434aa3acbf3369dcdc3990f77cbf22939ddd5877f09c8aab818b80aa20544b6928fe62c78795a4160aecde6ab454db0dcdf1d6c13522526c5ccf82d429791059306f02cdc18c4e580ec6c2da19b3c6de63933ebeac79010c73df95748d987e96a0f8ad523b5014b33423f55922aec2ec23b9aa22f - -p = f260d143cff1e8e0931765da8cb335c0206bf7fd19aaf8ff41e762992f2bb0a660cd65f08a80fe502c9125166a6927aa1859a874159796fada835b48522f5795ed1f8d23f05016358ff908b0dd638bb7ed12c8b80b46aa858d52c77bb7fc0ed1 - -q = de8e674fac0b7ea32d518a22030fd10d4298a77974db8febe195a4240dc5373e8161baf8ce47dc4fd076f64e307ea6262c35b9819bac4f142b613973eeb6a62a15a2ff09fba9ce4db7186969af925ee3acb7d3be7a1f9c85358216640fc1e0ff - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = 5d7f76ed239a1a5d00c3a4f4da964ae0bc409c43ce9b147b859aeea617e8396532cc2fe1ed50c20cffa2772a2eba778f0b3de4aadda26942db9315009e96692ed5ecafbe3bb98e8ec666dcea2144b3535d72c77ee400f6a0ae5421e9b7cd3b4eb0a79f8cf41fa76abfd77a3e9a7b25b21aa5eec8cafee41c66a7bb6a4ad7d74f -S = 810510f7e41b63d4d1db17ccd919547d021c0148047ae92fa3278a1fc7d2bcea796f6ad6b927df033302d5df46b3d33af70560c01bceb46502552a8b6b67e0c754ab1bf58f5ca9f96397aebd5d852c66865c399032bac358e7a990ed6dab9aec27e664a08c505fce3dca4bae2cefd8e1b35f6d4b4216cd6572f139e4b520188e8199c9e3809938ad642123c466e0d59b172217ad290dbf74e2ada78c0b7dfe639ee88caf44535a734794406fe909922442b1bcee8fa3a8e31bfd665dd219c46d -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443021300906052b0e03021a05000414fe4eed9d60746feb5599bdcf486716a6a04a0e69 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = 044138280eb07cf03ec9747c7e9b89e0a37850b2fc40ba6b2ae38b1132210d13d194057510f1e62c178b45cc46188d6082b8f499cd33ad2c1a825f755f92d760eb44fa89fab8fda287cbd81661def7eb81da33ed9b700209f3a6eaf7728f3c1cf959feaef58e2919349315a1f775314948e4f7f48d801fcb5e5413de94a0a40e -S = 6af0c3b45ee0b0f5182b692d5703921e779bcc5ec5e5f71fef5c480a491acd10e61166ac2b40e4246fcb28aeb5b8feb870be4a4efa13695ec211e5f603d86d33b228a41069003d18841f48aee2f4802f1dfe95caa9a3d89e5425ce06fa4d17ac2e5fe4af0e5a2f86e5ccfa21c5d1520290b2d4d4ca5096486b6012e302b2eb3cd9f906d36719f3a19e3c124969eaad2a43c2e30bea835dcad93ed550dc3137e59fd891694274cfd6a2522600c661dc496f4e4de5a58aa51afc15834de5c97e96 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = 8f662067a26e81165e23ed70b145725faf2c591491ba4d9ffe8fbfbc8a7b88f07d39d0d5d55a2fb28e7f134f20cb62084a98601f0e69d257fd2064beb47248caa79720a71d461ed07ce069ddc7ecc39b65c36a62248c3ba37d6b1dc11af69d2295e9d685831a9496b1afb9bfad8edf4288153e85db0cd0ac08d7b46dc2f0d120 -S = af16b7a53f57ef673aeaf9a17727836d00e883352e7e2109911dd839ab23d46400f140af84d4cb4a5864165c682aa85eeaf4300e74b94b4f8fdbadbec540e07056b55fffc96a627939928ce5fb61e119c94f14719a93fd5f3a3dd4a8754a8bcaba64afd5e63bea1a793d420a2b6975603f2d4597b26799da0240fdb7d8b0e6e2896f63bbb46526a2f651ed17deda3ab3b43622e749bb608c6d30d41d7346f9338bbd768209e531a17e2a92b815efd222049451785565117f39812de4c6ecc65e -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = f93d6cdebcf190ea6ab2358636af5cfe4b3a9bdc1bce160bf350aa3cd3956b897e255158cd3e2e83481ce3b6f778d418764f992d48e4f7fb6d080e6b3799d3f35949c17241a0cc5ba84597166779e6a38ce45681ad944cce7c432baf9cd8caf2b33125f2c12052bbb0b3b76f2cb97be9b4813a9ff1e5fdcd478769d0ab5b36cf -S = 1e076b3feeb281e5ded58a886f653c59a31789050df263bf06401eabf4eb79b4b516350fa63b06c4ea8339190ee9ec30c3972f0009a892bc5938e17c0ad3502f5b6ebfc6e90281cdd94ee5758a2747e05d2523ba337301d392bfc6fe57890234bb1e485ecb0c2eff55c6861100b2911fe594e6db29ed773da026bea1875f334a2de2214e656f6bb25b6f84ef5cfd4158d27642f84579c1f5e185bfbe2948c2ef26e6610355e190b4c06143f487a68ff15da2f7acc9e28bbae89e9ef0c362d63a -SaltVal = 00 -Result = P - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = 6f856225ba8dd27718b7c684764f2a18c19df4dc4bb9accd71a12bec7b89a337c372dfd91afecc9e678339a9915edb699f8a94c91e71f4a7c30101885203338abea8c39a926526e68f01d49597ed4db6cad35e77ee71a09814a8431f78d0094caa4f95cfeb6ae639da5b1fb150a389e888a1da4f8364b887aabe7918b6992d67 -S = 2491418adaa343b655e7a3e762737b02ee904d6d79fb6ddb9cf2043b671de59e5165f2898bace269f0e65f3e754aee71a5fa596a5a89574afa49818c7a962c38e1577f2302b75ddf53fff93ef035be0dfe14a086a27ab5a2e64808c9abc9007cfc748fac383c9c89fad72d89044c49cca11cf761d7d8e506920aeba7e7e8f187aa287c6c8878a90fbded8489789e2742a8386d8cb21f9d0b51123a5f78de74656107e562ebf50ace92da2437ed325629e66e14b573668ed6462a8ea21e54a543 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003021300906052b0e03021a05000414753938c49eb8f7bc120354dd8ff2177dbe9bb916efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = 9fc80458af5f2489a910779f7b9d078b249a68a276219af01ac830d0d4d0b2ba089f415b7e7079eb624a9cbb8f2eec0d0d955829d71a5bade27322255ca5eddb3178b7f1d42919ac3c606c132d612eb9b886a6d705edcb9d506e63ca32d0687b223caf403bf1cc75403a30d0dd9d94362f569bd38704b2696ba13be8deb7ec40 -S = b23c38a05b861aabb41227c23af9d3b6e1767605cdcaf1627875a7ce09f99cc4b7397a4f010a3bb2d8a9c9765b9877f936369d761a13dc3c22c0db84a3364661b5c7fd39e6965e43a728069daf89612dd8dec3dc9142d6987b8345579d9be7891d315247955f70ba789d3650947de9e92948e049696a00d0e0f6d256cfa24128be180ead9af648436c1cd21d0b396d70c27c94ad8c8625b6b3dffbb3ff78c475732203c8d08a3f99e7dcc86f1c233131571210e8135a29565761dc94e77bf484 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = 5d7f76ed239a1a5d00c3a4f4da964ae0bc409c43ce9b147b859aeea617e8396532cc2fe1ed50c20cffa2772a2eba778f0b3de4aadda26942db9315009e96692ed5ecafbe3bb98e8ec666dcea2144b3535d72c77ee400f6a0ae5421e9b7cd3b4eb0a79f8cf41fa76abfd77a3e9a7b25b21aa5eec8cafee41c66a7bb6a4ad7d74f -S = d1b5a7c9880f3b076d635ce4f881de6c715d0e2ac85fd08ad5d4ca93f2b04870f7264bad5c7dc9f38046b7ce0bbb4fb4e6279571533f61cde6d540c6e6bf69e4869ab76a563f30cc6718cdef849f76c75aea4c9a3068bc579b1104474d9a4849d9c3db49fee17afa5281fa7ffb848e9b33835e942e89c04e291d123f5d2bc5869f076b550dd8c04d2c2f29ad290ae294ab3d34ef54f5148b256f50c54f14dbe4f02e2aef97e39a90431b774142b3dbaae385615323badf58f309e70a1084ee59 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff44302d300d06096086480165030402040500041c7c8aa165fbd14e4361a3bdf3f9b6bbfcbc8e14153c901f8e2104975b -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = 044138280eb07cf03ec9747c7e9b89e0a37850b2fc40ba6b2ae38b1132210d13d194057510f1e62c178b45cc46188d6082b8f499cd33ad2c1a825f755f92d760eb44fa89fab8fda287cbd81661def7eb81da33ed9b700209f3a6eaf7728f3c1cf959feaef58e2919349315a1f775314948e4f7f48d801fcb5e5413de94a0a40e -S = 6883e11e659c46bbbe5a9b3470adfcfeb546bf008d1f2f272e2b3b957ffb52f6d25e0a1aa4facdde72c103566cb6b898a9f059f17b895ccca14aff8a658591998e8f106dc8624a48158e932034f9f3fd4f2692e37ab8a31d02831641d0518d4557f2588f394eac4a54510b4d4397cca2f55e7b8e08f7fbcee8a9f1c60e4f6a8fbe30b3b29bd7492aea116701187d6bcc9c91979de68b52e7c6d57e4fb9d5fd6526497be575ee861bb83e05f5b51b9cd60276d93e6fe987f4240c610d94aedb49 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = 8f662067a26e81165e23ed70b145725faf2c591491ba4d9ffe8fbfbc8a7b88f07d39d0d5d55a2fb28e7f134f20cb62084a98601f0e69d257fd2064beb47248caa79720a71d461ed07ce069ddc7ecc39b65c36a62248c3ba37d6b1dc11af69d2295e9d685831a9496b1afb9bfad8edf4288153e85db0cd0ac08d7b46dc2f0d120 -S = 0e53008d7626ce138c6aff6c40eb86dece247e192bd5013880e759f96142d22d18abb6f1701b88aa28d53b0c5c13b91a316e79373a37ecfcd61df7d3c34b59ea36eebe0c6864ef63514e504a8c796780be8c2586f1a2eca3a45d45b15c4c38f94420ef563efd9fe2d8c194d01c7c34cdbd7f89923bb39bec9e8ddbb1a282e1ee18bc9cc93ab42c2dbe58ff0927036d2a66e364d88354571b75fd11f131076d6fc9c75b810b522d2c18faa4a6332cf82122dfdd17f5efa030fbb50177f97c9bf9 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = f93d6cdebcf190ea6ab2358636af5cfe4b3a9bdc1bce160bf350aa3cd3956b897e255158cd3e2e83481ce3b6f778d418764f992d48e4f7fb6d080e6b3799d3f35949c17241a0cc5ba84597166779e6a38ce45681ad944cce7c432baf9cd8caf2b33125f2c12052bbb0b3b76f2cb97be9b4813a9ff1e5fdcd478769d0ab5b36cf -S = ca58ea0da7afc7dd4a1d32ff168a03b478f296dc0f6edb2a0e859d85476f1af70d21b42f0af6fed26cf82604f8a2c5d87b50e5a5babed6d585a6a84861ae56dd2654c4884af6672ef57c63d8b03e5d7cb8ea49e6e8b53051cc64b366dab0b93fe29dfbcd7b9a0b8885711bd103844532f08ddc2edea7076e36e7ee25eb592bda6a4f862af008344117f5c51073407a8d230f2ab5aad9c981ad10842706b502f4c984f2f969dfb5090678b602b4748004984fec3a39779c2f5ee1b02c6eb77dcc -SaltVal = 00 -Result = P - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = 6f856225ba8dd27718b7c684764f2a18c19df4dc4bb9accd71a12bec7b89a337c372dfd91afecc9e678339a9915edb699f8a94c91e71f4a7c30101885203338abea8c39a926526e68f01d49597ed4db6cad35e77ee71a09814a8431f78d0094caa4f95cfeb6ae639da5b1fb150a389e888a1da4f8364b887aabe7918b6992d67 -S = 1a524bd769380e63ba31ebc0adf908a5c2b657b03a534da42eae48f044ecd2bb643f2ab320b34df4ad0938e17044d9e8a40c0b50d696024e0f717f19102f82854c626642da58c430ac865d3a25299f5d8864b418a172b331734db2efec8e44d082556d7d37731e4d4a317a22a076caf9f9e9854c1eafbdd57fae1822ab268076126f55c3ca52873885f9be15c0308210465b78e34335d6fcc569c8e4ae0f65034c0d8ffc1f078983e15e4b2bd7f46a0bf41c8ad7fbae341037c2bc87c2248060 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00302d300d06096086480165030402040500041c3634827aefd0d0bef3df495c39e6d596907496b91679e2bd96be6542efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = 95d3ac5ad05aabd72a1c331b0bb6f75ddeaef4f4b0b6a6bdf92f7bbdb9ed8807c73a7ae0661dd0221adc48debabf9745c5175dc9f97f587f2262d8c831bd73308d26f996ae0eab8ee743a70383b8a7211489eb71083a74467d40735957c201b08fa010c4cdb5a2e23a5939d28f2a8eb7730d8536036f61dab2d134b753839a4e -S = 15893719e5cd0ceaac13914028cbc46bcfa00171d18041371ee945c546f10a0f212231090f4ab7f490ac852bec6ba820997d71467b797ff9a09af565794a85c15e3c10aac19b91f6a540afcfeca49f1660a788c2ae040a907146b4f6179d808f96da06f15daa18cb3be6b2ca0913fa91e966652a29360dc41e50c6c43ea5d633532d264b0ca09987ff3b0cd1542b4a6a48332d434ee3f02f9e0ee353d2acf260a3ac278de0ba65677b44911ec76071f74a5ebfeb33107a01fdfecbbc4645baf6 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = 0b9c18c93a8b1b8fbbd036c2d5a6869c2c326e80e613df300d3ad74034fc28cb5e657b641bd0944ff4b4d8f209c10c86f92c5f120247ab9a6a54f8931d9b429b97ba7c67043dd4fda66e3923786e1a1711857180cab701a52398dbdd636127467f4221ba3dfa62ff99a6613e68d639b73be6adb2868c69b902ad8a044f756135 -S = 29dff9f009373438341a72589399904fab9b900a2bc65c371c989dd60e9c825dc222d982d773cea97be3a3c378956a91240b23eb59a4cd5b78d44fb948bc402db68a8efc3d9d7c48b55a826bab47ef4b605c0ff33a7019d8f1e71a17b43a6a72a57889157c15d10d65152a7581b8ccc0c09b1dd284d9da78786853bb8b88f4458bf178e05247713ed13a6bb7080827a1f4cc85de9a8b094f9c6edb71e8e3166d4907b786fc64d97359907661b6e63e6c1e415e9d31aff0e43a47e5830fcbd26e -SaltVal = 00 -Result = P - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = 5c27ae4e00a9253b8e43c744e235654a6ff72a1cd37acfe0aeb10fb5b5505b9602d4ce81aec363d9a235660aaa93286bcc9ff768d7b44de03e4f48cc27cf5a22c07942f9d2bf3bed98c273c5d115be5314c48c9c64951939048de3fd8cb661d83d20f2fb9226143d17f2d6be7e4490caf06ed100a1a499b3a772c8900c8ed781 -S = 36b438a2420cd0683b040001f926e499992d21be6d6315302123efc80d63d9182f014fc8e8cbbaa70c5875f2e7e7127e5925eb267948101ecca130bf0846f2c4aec394faedba13ec6cc19e476cb31c2cb025bb188127fe70d240fed47d674f2d5b2c3b4660b08242ebb5c005bd1e836c908121f0e73dd80a18668b79d05783c521d9913768296b057cdad7f408394d080e46b74e72c6d337b54c6ff976af2eacd7ce51f3d2432f3ccf7b55b074cc2817272816525b91264c96325f3145324cea -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003031300d060960864801650304020105000420cb6adea7aa43ed6220f5f0c4dce57facddc4f77cd4e9072b0468da9bf104c1bbefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = 8bbcc23dd3ea4ba9c1d1c8e052be5d49e1f358c657050a3b9e83d64a59d88761d273e6f733258d12facaf60da72bd798b723b200d601a7b1512e8ef9ca10420e2f2d3f53ed9470d76079421e8e1ffd2516fb54a063163b8625b3f8cf02327d7d8834f5d967009dffdd25d59c716177f7e4c2672e650b6bc204593d566906dfb4 -S = 3e116c20ca4dba97fd0804d5ac89cf75bf53a71c77af12c2301a1c093aa269a9074f467c57727a5c0b17f18968842f98bb11d8b4afa9a9ba193c0e8f2d2853a19293c310ad2a5e792ceafdf307959a50fc48aba8dd911b367614b26b1a19ef13e37a4e3eedd4229174d7e6184f6bdc4c5d24397545709170a72fe202bfac3695373da28abf90aa1dec9ce1ecf4afa22016c2b6b65e65a5ffe38925ebebe49e4def0133916b4c22d2225122e1d77703a716da7cacdb85d9863d53c039da1a1c44 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = 676a410de221dc39a833bd94dffc5b06dc4ae2613b1ce1452ea9434115a4813a4fbf1611506e3280f4edb24513845083560a176549a81b04b1df668b1fcc3599c5ab65e6899b282a58a0fc3abdeede74b265ba5eb658278a1f9251bdb29b364f713716d5b43024fe7b5582bb03c36ca39763b495a9b46e9f21cbec1ef598ed27 -S = 34f5337351298d299f64828163e2c8edca0bbb1e80d8da4141c3aadd5827d815f32ec5ec6696679580f92d1e97ea7cb85485566f061a4eca830c22f01f9d952d33c2aea8cf7d1b49d426cfe029f2c52a2789e9031e015ad74c7105d43b9fa603869e850c6be898830ce1a921430cede5f1312de7bdd4edcde835f32102ec28628ca49b5009fdb5ac03c6ad077c77f66fae2779eace6908c4fb5051d82255e7e50920afd1692f1c08d61d233f47e8a7a1e342d39fbc8ac527d96a622a2812f177 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = ad82f5bc35d0995edf617b3b05f4ebabb0444cdb678980734541a1754f30f26804a615b735007e54167127a09603858fecd8bc0772b60f8ab7c39a15cf8c4348ee4ceec6366cf0dfcc46c66d312e08fbd0b3982dd3221f5c3b4cba803089f05395fde8b3e01ad8482966c168807f5a37845c491332d5992ffa66697d1830e1d2 -S = 8dfd4ce88f22ca5c7faee59e9c0c319ce22581108d1f333a4f53c239a840db6cbd9a18d1be3d211bb2a7dc69d1750aed173a50cce78d4b8ae804525f5e3dee05c98d9e1debef27ac43dbd8faf87607affdd97589995cf062c7f3b5c1ce7dad7c200c3124fdfce5f05e0044ea952e54ab642c47e0bff3f80cf96f0dcd08baabd11152b8741d8e700c27d805ee6edff11f95b441a24d65bccdc6949b91baebfaf249762f61593974813bec018929b51cdaa89df092b38422e2a82aa7cc8a22f971 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = 75025b7ff7978e537b49fdbc59a54ce3e8313c96885ecce3e6b8a5e67b60b4df56bc19871c6d40a54d814ddcc8eabec7922f4b48d362111c2152f0b30101323fab596d0c0e1aaa0f1417c6c127a2192ef44556486fb3b28217fd499a7b09bdb6fd4120b3d68814ba5a7230147db4a63f97d923416437f73c4f227643f05f9e6c -S = 1f435cd0b2835f4a895c2a53c4a9cf8561197c90548881f3150b7f2247ce7c1f0fba20dc1b3a265566b2cacd6ac66f087ccbe11776168f382ca2cf79cf97420ea665c5cc547e250a3582febaebf9b4ec97a1cf7c8f1f75e75e67454bb2179d6fe1a66a1ca01091134871f8886eda7e72536eb05b3ab352f8e775f94a0c1c3060d3932200cc10aa07a282a2c540ead4be9c3b664da3adbc4a513e5363b41e8e867d2c348eaf50c37cab0a1ad9f7e32dc48f1ed90d2c4fd88c7588f3250e9b582a -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443031300d0609608648016503040201050004201652a7df9a92d3bca639e5b379b1bad5728d06fe2ef755fa734a1f09be6e782c -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = 0b9c18c93a8b1b8fbbd036c2d5a6869c2c326e80e613df300d3ad74034fc28cb5e657b641bd0944ff4b4d8f209c10c86f92c5f120247ab9a6a54f8931d9b429b97ba7c67043dd4fda66e3923786e1a1711857180cab701a52398dbdd636127467f4221ba3dfa62ff99a6613e68d639b73be6adb2868c69b902ad8a044f756135 -S = 49eac9a68c0786ced77b437b01a3a562a5d6e6fbc9728dd513814cbe611f3d1d4aeb4540a61853595964d370406f3a18fc6973387c99821c8e966c47bb6e636543ba7940b1c0f23a8fcf46ee4e3173dd39980088b0fb2479ee4a08b41b2dff7b3ec1d2989bae39f7abd1bffc8d33155518ea6968b6b471c90e6773c76c6fe8cbb1fcc138dbd48e9eda1090ab245dc2b98fd7c553a7bf11321ef7c77fb14f36e5b7c969abd5e8c049d2ee4fc3f08caa6d996ee0580af6cbe27c2fb1e0bf3d79fd -SaltVal = 00 -Result = P - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = 5c27ae4e00a9253b8e43c744e235654a6ff72a1cd37acfe0aeb10fb5b5505b9602d4ce81aec363d9a235660aaa93286bcc9ff768d7b44de03e4f48cc27cf5a22c07942f9d2bf3bed98c273c5d115be5314c48c9c64951939048de3fd8cb661d83d20f2fb9226143d17f2d6be7e4490caf06ed100a1a499b3a772c8900c8ed781 -S = 2a7d47940bef4582f4edaaaab4b0181c76c091179465ec3c007edef88775986ac07f85b4fbbd68450ba9dc346f590cee4ec1e828978d82c5e0bbb87df6f8c548ebbe64fb4f101bb8cce618d88dfb96f3d8d5efb0d6f7dd67c8f75eb068005f47db66d87c33b833dabf7dbd02b3b327988164f436a0e313efa3cd124f87730b463962b21b5a4e3a9530db7ea0ad8d3ebaa23414aecd343ceb58e324a1deb1653e792ec5a9eae709d77b2e55b6e8b5f653a8044882d020f5fa8520afa588416d67 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003041300d060960864801650304020205000430e1d3f55e005049c7d99593b81a02de751db47deb6bbd6cebef963164123fce991214c8be6828cd6caa14964f293e1245efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = 8bbcc23dd3ea4ba9c1d1c8e052be5d49e1f358c657050a3b9e83d64a59d88761d273e6f733258d12facaf60da72bd798b723b200d601a7b1512e8ef9ca10420e2f2d3f53ed9470d76079421e8e1ffd2516fb54a063163b8625b3f8cf02327d7d8834f5d967009dffdd25d59c716177f7e4c2672e650b6bc204593d566906dfb4 -S = cc5bb97aff280fed4499d2fb96d5acdee24406fd1d80217a0b6a27f7324f4728db0a4a6f996addb55ee8fd2fff1aa109d7293f5a7954a08857e53941d1ba0a86e1c38ec61cf9d54c2ed40c281475fd68dfa1aaf0c246a05959465c89bef974df66fb1f3228e07fe03eb7b9546c6f09dabecc6f2b8f2f6be058186578d87a097aa6a0a15f98061d4d1a1ccb67a9a6ae6b35e264e591a8115b459dd392d3c1f6a6785ed3c97d319d19b562da148e7361ee261c2991ca09ea924d69d5dc59f7beae -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = 676a410de221dc39a833bd94dffc5b06dc4ae2613b1ce1452ea9434115a4813a4fbf1611506e3280f4edb24513845083560a176549a81b04b1df668b1fcc3599c5ab65e6899b282a58a0fc3abdeede74b265ba5eb658278a1f9251bdb29b364f713716d5b43024fe7b5582bb03c36ca39763b495a9b46e9f21cbec1ef598ed27 -S = 4f43d98e1a988f7b64d37fb9db79b1759e1b971f90fccd542d636f04c4f8e35c3f07d941c906f8fb788cfdef25b4438a5c9322ca2230e62b17e618dcd7a4669a187506dbd2087cd25da81f351cb87430163208dd06bc3e5b7a36559969ebbde2200f8933c45cb327f5e56e1c36bd15d11ebc7bd0034cc2fec3a9382dacd61a715c1f2f5babbd549faf752d4515e4375df0aae487327b765b45e82a868dc7985e03bbf1e6c80d022562c7e4455db4463f42fca3f2bfbe9f6cabeb3bb61fe0c073 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = ad82f5bc35d0995edf617b3b05f4ebabb0444cdb678980734541a1754f30f26804a615b735007e54167127a09603858fecd8bc0772b60f8ab7c39a15cf8c4348ee4ceec6366cf0dfcc46c66d312e08fbd0b3982dd3221f5c3b4cba803089f05395fde8b3e01ad8482966c168807f5a37845c491332d5992ffa66697d1830e1d2 -S = 5028c5c1d6558214048ab00458a5b0308053d91b312c671a15a47ebc32dc85b9760202b7f1d81549fe4c76d48318655b376e7d2398be7693f530bc28611cd48a7825759641c24fef6af1376d0d7bbbf23b9753dccb810a95e4d988be0c3c694f445f47e46e2aed98223c0583fac02cd9330e5652a697b07338193efe9afe1a514786c31edea49654d90d87d7caf26978accd08aa2272e12dcb058296c032fae8c63c736bcf4837c1d0bd2deb0a9539eea5f376aa5d1593afd8a0bb48d44bd5a3 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = 75025b7ff7978e537b49fdbc59a54ce3e8313c96885ecce3e6b8a5e67b60b4df56bc19871c6d40a54d814ddcc8eabec7922f4b48d362111c2152f0b30101323fab596d0c0e1aaa0f1417c6c127a2192ef44556486fb3b28217fd499a7b09bdb6fd4120b3d68814ba5a7230147db4a63f97d923416437f73c4f227643f05f9e6c -S = 068559fc0164a646aa07337ac8d98cba1da106d4fa951f408315284f4b2138037687b87c33b38d0e180ccd62bfe1baf2c42f72b9750d133502092c42a3faec6e42f3059ccb5cf1b3db1ec2c714e12aa0c5ab612a4d0c913ada82c98015ec761e7237087e2da676cc92e3340b2f31b13b157bb128b2a6afbd183dd67d5e1bf8bd041e580ac6a3fb8b4ab280d182ef906fb247c0d174076da4770eb10b13163c2e53f0a5b8a0b2352de761677a424fd5d71a4efb54b49ba6e2a96b9aa740453157 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443041300d060960864801650304020205000430d7d7bfdf4dd5cfd15b04f924d4be54564e72e6a2ec5cd83b24866b42a01970acc7686ba35e3f9fc29f0fd53fc5254104 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = 0b9c18c93a8b1b8fbbd036c2d5a6869c2c326e80e613df300d3ad74034fc28cb5e657b641bd0944ff4b4d8f209c10c86f92c5f120247ab9a6a54f8931d9b429b97ba7c67043dd4fda66e3923786e1a1711857180cab701a52398dbdd636127467f4221ba3dfa62ff99a6613e68d639b73be6adb2868c69b902ad8a044f756135 -S = 3583422f69bf11bb8c8c9e18c40cf2fe3d6930b174a4d8efcca214550b525f7d460077d280e714b8297378a9d228226c719f790961999f0532d7068ac8d51dacfae64819e8b7eaf618ddbc33557cd8f9a3a1e65efe8a4d02654bc725b1aa779ba54b1b9445488a084b9614d8e2c9a0d559a217c6427cb62a6cd8a255512bbdb006427db49b1a3698b643a21d65cfea8e624aefd38f0a3700687bd035028bc161f5eb005cb66aed2fe59110108140b15d6b97567b72b1c712d6fd030872d50ae4 -SaltVal = 00 -Result = P - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = 5c27ae4e00a9253b8e43c744e235654a6ff72a1cd37acfe0aeb10fb5b5505b9602d4ce81aec363d9a235660aaa93286bcc9ff768d7b44de03e4f48cc27cf5a22c07942f9d2bf3bed98c273c5d115be5314c48c9c64951939048de3fd8cb661d83d20f2fb9226143d17f2d6be7e4490caf06ed100a1a499b3a772c8900c8ed781 -S = ac97f3f6ebcaeb77a23ca3b9226f7167c7315e5687391b700f21e45a00b23d7ad5834ef313eb3163b2390ccc63f9d76274120c1f0380747b33c1c77edb3e06923482e39b5c964f8499c20e28ed3fb064990190cffd033ce3ae384c275298367baafafc5e66bb0cdbad6e2cf9b16a393610f0088c129b75b88da6207bfb8570425e38b9f2a30d24f4753184e36ce0dde7e9026fcee5cb88f70c1bfd3b9a3f0a0c6bb80a04266c2edb3ca9c06a37cbbf77c1b50c01443c9282d023309a1668fccc -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003051300d06096086480165030402030500044068ac2dc5d380018cb50e8316dea0bd72d31a9c354b9185b1d227c6540be123d48d79581880a02e2cbb7166289ab6798fd3215b272fd171bf16f74af65de4a360efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = 8bbcc23dd3ea4ba9c1d1c8e052be5d49e1f358c657050a3b9e83d64a59d88761d273e6f733258d12facaf60da72bd798b723b200d601a7b1512e8ef9ca10420e2f2d3f53ed9470d76079421e8e1ffd2516fb54a063163b8625b3f8cf02327d7d8834f5d967009dffdd25d59c716177f7e4c2672e650b6bc204593d566906dfb4 -S = 5b591910bacd2f0bb6b2052f81445397d2056d114924a306a2b24c4fac2b7698d9ad725cec3010d57b11795f7654969a86f528709655d07a336a68fd4cbbe6ffc95fbf1a6e6c17c2d627c6011e4209f406ae7f2c670ecf4081053c2283845e2c855938da5530a146a1ce4bc203d0179a19398177534c7bb37cd9837911e8b1e7988b800e8046864fbf95e8c584a3c4209f3ea5fd535ba58859ff128fed9d0fc5be8e8c2890a71e38f3acf2a1fb537cdc87f53e3376276c8cd501d21069e453c6 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = 676a410de221dc39a833bd94dffc5b06dc4ae2613b1ce1452ea9434115a4813a4fbf1611506e3280f4edb24513845083560a176549a81b04b1df668b1fcc3599c5ab65e6899b282a58a0fc3abdeede74b265ba5eb658278a1f9251bdb29b364f713716d5b43024fe7b5582bb03c36ca39763b495a9b46e9f21cbec1ef598ed27 -S = 5f6b11ef4b5b0a1bcd9cdb2086c60db19544dd33aac813ff6ec628d9de0ab882bab6496b79477cd445f71686f666b9e041e2ac40959ad94d3df00b1ef8c7ac3ab68b1d2e07294b3aa54bbcc1039b90dda11bce3aaf66646d19a7224028dbe7b48dbb67dece2812a5bf82e89db0908cb26043b78ca5ba455ab680d3d6aa4bd1682b39b5ff744a65dd5cfa909d1b71218a48d88e4e112a8b959b1886d956610d915ef41b30031eb3f2acf7d42387db245d84ada17b5995711ab2e12b8ffca81905 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = b17ebdbb8027c2ef5e5de76780979c65723d73c0ff0227d95074ded158d1abf96f1d578a3c716197d996433f32d3f727ae02ba2812e91044a2c808df892fc12b7a122de5981f153f934f5d1d14bc8a835cb2814e28089123d7b1b4a6ce8e12ec1c86c7325ad9e6cfd5b1be67f0fb5c62c374519c0807b55e38566b8ef197a722 -S = 1e80b47f34629c79b612fa8d25483056d1475f5f51c50ac60e8f5eade21469dce676d13b32140760d828dece21cd9aa2381b40f42e8e20a77392713f5372d1e87fc131eb7367b98d92a76e5276bfd073d6e44f8e9cf81e175d531e6ad50dbf84bcbb636b378c3342ddf6b2d85c3d27b2afe449c40f2915515c4c417a633b4de6c30e86f49f8f5dc44427642aa0c98e499e321aebda279a7321836a3cb24ee90c08c9e88f7745c19deb0e1de72b4da5734bb137414f1d4b1c78a9c2e58f148105 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0e0c2f8859ed53f57993a08eea025ce6e0c208cd61057301d1628d4802599c01a46d6d0c5ed43f09b87f34c206abf1cb1ebccdf2662224f81defbb29d761adea4006e9f16de6ad09f5b32be59d1c6a51dd03a41ec8c5eff6eb768b481fdb0908591f902492fb603537ca6292888ae060bd38e8a9355a175113522d7993584d142998ef52f6add24f1b5e76031844d322ec03914d8c7a26e7a38e63cf99164313eafca2709f1107a6c57f5d49913d20b3bd8c2dc850db453c3a23b00f18ca724b -Msg = 212bd005a8e8e13b0bf4620ce2d3d6bbf18b3d195b05e90412b78d2e92809720cfd3bf7e6b18e08c2d4f07f1aff7cabb562edca48719de931886776605d0a6ef6503573c9c41351cd165c0dea3e59f5c17fd3739d50a7c66953407ebd44f6ae4cb03c0c9a12b88f3e07cb35c2667fba71d407760ac9f6c846f07674465c58806 -S = 6db765c50f9ac9da75eafad6652ddb99e62234397fb2c96769af84da59cd408c12b7562104d9ce9e7455e06abd53af83da43406c64bf15d37ead519d6b3a12cd5e02803c92eeeff2312cc681d53b22caafe9ed5541db754772fcfff3ae53cf67d07b8eda85202a36db8cc01fad12dc3b455bbe123f9ed7c3873c0ebf25bcd55dac7002c7ad1d00eee91c58c357276cce875ba1719b2356ad821d278e9a62ae1a6e22b145ce2c072a1faaaaa8ad2ca4ca807eba3d420af2f3d915993d1327c940 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443051300d0609608648016503040203050004404be226f7beb9c592f2429b00af0b7dd3de42b17313c58ab7ff24fb441e6e47280fa6f5ebf3bc14dc60f8754db42c984e4bc5077fa7b559d727938c3043453166 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -n = d2b6c8fd44e7eb621fa6685fb62371872b5e8408af51bd1b44c6473823402418a26963b98e6fb191cf74175e64132ae6cd101133fc002a89c10bf7739eb930b9c067b52570842395657f927434aa3acbf3369dcdc3990f77cbf22939ddd5877f09c8aab818b80aa20544b6928fe62c78795a4160aecde6ab454db0dcdf1d6c13522526c5ccf82d429791059306f02cdc18c4e580ec6c2da19b3c6de63933ebeac79010c73df95748d987e96a0f8ad523b5014b33423f55922aec2ec23b9aa22f - -p = f260d143cff1e8e0931765da8cb335c0206bf7fd19aaf8ff41e762992f2bb0a660cd65f08a80fe502c9125166a6927aa1859a874159796fada835b48522f5795ed1f8d23f05016358ff908b0dd638bb7ed12c8b80b46aa858d52c77bb7fc0ed1 - -q = de8e674fac0b7ea32d518a22030fd10d4298a77974db8febe195a4240dc5373e8161baf8ce47dc4fd076f64e307ea6262c35b9819bac4f142b613973eeb6a62a15a2ff09fba9ce4db7186969af925ee3acb7d3be7a1f9c85358216640fc1e0ff - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = 34d9afccc659c8f438830b2fbe8b6600dfabc007cb22e826ee7dcbe2c515eb0cf1d90ca08a4d30edb5d3c6f6792a1f19ce3421eef7fc3f7212f7a965ee8abff01ccdcc8b498ff11ecb9a5f667937c99bc0f51a50f3a7639ae3ac1774b0737a62de3d5755ab25f1cfa05e3d4767bd4ecfdc7711f4662b3ae688237ed9b3d703aa -S = 38fae4b9233682065387c11829b0a9747217bd7d49acbb5957b8e7d231235f4f7ec316b5a3e5f4f8f45c8b9a161f9b8d3bed9aec0a7b0d4484474150c8bdf392172592c1d0b8ee2724d08aa73a32afad3dad1a0cac3a9f21811f53c69809239c26e36c7b6f4b3a90dceab045413dc3e89fa1927cc7a622e55044a3417b44ff93b2faa3c864c6fe519fa1a8189121a4881e178979096f17519203f0d2c9313a70b2a5b670b675319ad0971a0728f0db729fb5d50280a33fa201271715b256515f -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = 95e2657996a4fa69f824ca49ab5a7e6ebaf498a0dc9eaa7f4981c51fcc0935f619ec6bf862683b0025cc48724839bc1e67aa3c686d321ba66185cdca83ba9f41984fa61b826ef56b136e13f1239dadf6e03d877866ccb887908917ef0d33f117b614fd291e3e91736b15150e650db9bdcdb56317f0f5ebe97c938bd691fc9140 -S = 3ae81b95c93a702dada5637e1c4113e5c37a8a24021bb2371c788a90ce8fab1c063c7e17f7f570a25baa9adfc78035d8ecc87219df1bd30c6b8b593682f354db71902ce23faa18f4af6fb9cf925ef7916c168f7298d56c49b6c68da954b56e2164ca37bb7c06498d6ee96aa502011356fc48733b937f299616ecba6699fb8d3d64e332c0fe3f9c58c18f033f92f237940afe9101702af51d3cc220547028eeca8e2d4f46ccb400f0620339b4da7d415ea288bbd7552eef2e68e4ca7c4ea6d011 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = 24b78a630dd8cde2fa183956b3edff7e0ea5bdcdc0f1f51172a3bf5218b7bafd7e9048422385fbba4b9c4a4d50958953392b18f98d96dae66a54e81fd12987284465586d9365cfe0f35ce6e250541367e46f77550973582e4b85d1efc235c8389fbb21ac0480319b19e176df5c2f850338fa43abda8f582f40bfe18a92e26573 -S = af9d6db0d610643147996ceb4e3cd539603b068b02eb31a70dd83d40d45f88ba25edda65873271099965fe67758104c2e40b93a8aa3eaf1277fe0d0db1c08de0b96b82c9b48f9a2cac852124de8ff81a7d9742365c8e7f68e94b5d3fbd3aca0e42528b0693f4c61aad95cd912a53545a785e08464b2f675a4b1a5a3c53a8acfebcb25875f7afd802f6f5d6342b1bef4c848504b40a475e56ce9b967175dd9288761599946838617dcc57ee43e1b99eb47be11773cd326029cebed368f821fd4d -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443021300906052b0e03021a05000414a651b5b5a63ddcb4142c5f673fff0619b853c194 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = 165c3a41385c453b38d0ce2eef3a1fd2863535b993080c84847b1d5641ea24890d9726a0ad44b37dcd0269d59f44b9e0c537ee5571566a95cb39332693adaf64070aac7307c1a37877353e09e5cc17e26b45c3d9d74c0f140a4b89799e844366cc5dd3a28cfa9e94fd1157b308fac23e4006be2d0d1282670a5c2735ab9567f7 -S = 56965ebb90a59710f86a5868573132bc39e3be28d7b5c1e588bc2c80799a0c89c17dff65d281b7aad6c0c4dedc4c134d022512b3821e057f51e27105858b2ae063f3cd0b4204b326ef8ba52310a3187a2effb3295a848de5d06d73504f71c6a91c2edfa5b6bffc5b140b031957b7bb26055f1cb2a79b89df8b1c31d9a54d96d546fa1f77e3678efcd9aa875627419d1dd38c1fe743785739c8bd0655b996f5bba23604983385ccb75640fb0c6b128c2e117e9a5fbb7b25ab1d9e7a2db644113b -SaltVal = 00 -Result = P - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = e2c50870d442d577b5fcd43778e9ac0e13f62ae7d506325ffa38fc267d697da72dfb22eb03d4c4bab3a9d904817ce78056633f93138ce773257ed88c5aa16923f2010c39fa4f38b2d529a6b61c9ac058a8e55775ec7e94df885a31bb1c68e8285a602c2260bb18a54402a515f04c1fdd3003da5709e621ec4d546f7c6cc7e2ff -S = 11875488140cf57011ffff2c42926d00a8f2cae3367360ab338c96aebdcf9cd95c091840c416039f58c8a5fc0cee32432a673714f67baa42d4ba6150054dc88644d5c133903fcf02ed83e196078041bc96f2ce785e0759f0a7ca80f41c2c2a97196d0e4763330b74355d8de3a102538e1b4174de2ae8ac71ac14f8e0a9d9d9a71a34b953c0977758c43fe96a3cbd9ba00b52a72fe464b485d306979685db3bfcdfbec66425dbd20fd59e0985458dd4afbed8dc4a0756f38c54624d86ea71e9b1 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003021300906052b0e03021a05000414cb9ea455374c24f698ff1b23b65a9a0e1980c32fefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = 2a5853c37f9428e1879034feb2d07a5c454e9970f4c1ff43b21f5918c8614d4f24866c89f4da620d7478706b040e1d5f7ee028f7c610c0f8a31cf77fcda875e4477e69e3eed3c6fe53ccab1dc6402278b3c00eb632d45f56d988884fd42733f3384733199505ba7bcb92cc5d1eeff3708cf435f55d974325fd6bf3d10767f046 -S = 616e467f569c1af563d7775df9c11116856febba4a4b7f801945b702621bad8cd599fe43ba381e02a67714244c0961c9cc65b6f842c2391a439ffab1d262ab0896e200493526f9047e3bd77e1b88ec854f8075bb54d7ebaa1143b4adf05fcd1f7873e036f464e73b4761505f7e96d6e80553260a95449dabc1e45f6e5079ea6fbfb8281c693005d3214e175ed18a9f5e70d7a59e87381611aff9cc82964bc6e68735bc11277f5c2e00be2d089511b12a32bebcb96ed91f4e158989b3869eab4c -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = 34d9afccc659c8f438830b2fbe8b6600dfabc007cb22e826ee7dcbe2c515eb0cf1d90ca08a4d30edb5d3c6f6792a1f19ce3421eef7fc3f7212f7a965ee8abff01ccdcc8b498ff11ecb9a5f667937c99bc0f51a50f3a7639ae3ac1774b0737a62de3d5755ab25f1cfa05e3d4767bd4ecfdc7711f4662b3ae688237ed9b3d703aa -S = 238a420dff7b0b18fcb6684933c38a9401fb2a6f8fdbb42b786cf5acb08948a46e42197fa690a613c8c0ba530d57d4f3fcdb410edaadcf995377a4512d09e5dea6de8e8f553d7694705929b012e7de002c95cd670f47890fb2077ee5a4c819ba2438d0757d8dfd1d0a83e4203672c269ac7a0c1e9769cb86eb3c9f5d7cd81058bcce66f1e3e7f47e1e15f000a02a7c98794f383c9b8650cf512b3040d1b6ccd638f5c8aa891228ea870177add8a9e754fe1a5c97f01f945dacf851eb6eaa0219 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = 95e2657996a4fa69f824ca49ab5a7e6ebaf498a0dc9eaa7f4981c51fcc0935f619ec6bf862683b0025cc48724839bc1e67aa3c686d321ba66185cdca83ba9f41984fa61b826ef56b136e13f1239dadf6e03d877866ccb887908917ef0d33f117b614fd291e3e91736b15150e650db9bdcdb56317f0f5ebe97c938bd691fc9140 -S = 5ae8f7c7b9f7002e048f47d7471f83265860a70e7da64a9ec5053f07e9d92f2af5d738c79bbc9924eae62eb723edca05a965f48946573323132b482c04810d521277676145e505b515cb4fbf2f783e3f71124300bcc96963536ce8ca83086a004e4963b8fa52c4101073d252bbc242fd6e0648b61edb394d84b01f1d7bb28f24b65e89f5acc881b6d30612105f143c0bb871193f70d4217a1e283285518cba57ee85a3bc77fc9f481ddcbd5a78144685de81a6828b0a253f17929ce14c4cdf12 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = 24b78a630dd8cde2fa183956b3edff7e0ea5bdcdc0f1f51172a3bf5218b7bafd7e9048422385fbba4b9c4a4d50958953392b18f98d96dae66a54e81fd12987284465586d9365cfe0f35ce6e250541367e46f77550973582e4b85d1efc235c8389fbb21ac0480319b19e176df5c2f850338fa43abda8f582f40bfe18a92e26573 -S = 6fafddafe9df19c45011ae4914adda6bbdbb20b43106d6d81faf1121c6300f9f9f2f87991b27a79d7ab8df8466539d4974d5cd379413ff1f2ab1f826ef5a6b128966fba4000593ce924132c26e3cc2734c38536178d34d90bb141576b80fe2ef1c4be81fde648d1aa3a4f537bcf815edab3cd3b44f7db09e7d5f73a17a9af84500c87d33b9d1ec7854852400c389473c8a13f70bc37bac6f75ce407996a3fdb9489fbcfb860a8b4c7280d3795841cc325fa0c9ce025ecb3f0c2d6c18a44c8ed8 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff44302d300d06096086480165030402040500041cdc59d2d30fcd76a4ee2fee88ea165458725b7796e06af5a9bd13f257 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = 165c3a41385c453b38d0ce2eef3a1fd2863535b993080c84847b1d5641ea24890d9726a0ad44b37dcd0269d59f44b9e0c537ee5571566a95cb39332693adaf64070aac7307c1a37877353e09e5cc17e26b45c3d9d74c0f140a4b89799e844366cc5dd3a28cfa9e94fd1157b308fac23e4006be2d0d1282670a5c2735ab9567f7 -S = 00f76baa258f67d94294939b305b41eba86c36b5ec68a155281a692b0be33d01d0b4c2aee3bb503a4f26ec4688b459bdd550dfdd029bae58f744c14b2768d184f6cdb9bf1e6da750cf10883f14d49ee5d836ba34b84eee98e7feafab7ed239b4154666eb0ebf0f3be6f44926656a0b9c5f649fbe5638d563fccdeaca8665a6a7868061a7a544b69b92abae588c8461e01e47f2d83f00978a99caaa2b4478a72c83806d24ba5e41447ed7fb6f22b1750223a9b18c8a2a08f00eb58ee20559dec8 -SaltVal = 00 -Result = P - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = e2c50870d442d577b5fcd43778e9ac0e13f62ae7d506325ffa38fc267d697da72dfb22eb03d4c4bab3a9d904817ce78056633f93138ce773257ed88c5aa16923f2010c39fa4f38b2d529a6b61c9ac058a8e55775ec7e94df885a31bb1c68e8285a602c2260bb18a54402a515f04c1fdd3003da5709e621ec4d546f7c6cc7e2ff -S = 6dfff6e5d6e75fa6b9f012a13c4e62a469d915c7382f20c8b961084ab41cfbc04dbb150d5f50c7c1cc75e6e891b0950a95df3171decab5cd48dd02a62b51f50358248b1c47f1cf7949d78bf236bcf1f6803e27e37725b60a37ede16f951587290f4eb5b4af07b7a6c06bd520adfd29e56ae61efc3ca7d436a8af7c2da47bf201ba602896bcebb44adcbb54083a26b91ef32657ee52b7c69a98f985dcb37328fd703c26303c4863ee3efda288bd9565258b93298dbce897003c760168cc17a734 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00302d300d06096086480165030402040500041caf4c1d01bf7efc97ce8b761e6fb40139563ffeb393b5ebec6f015885efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = 2a5853c37f9428e1879034feb2d07a5c454e9970f4c1ff43b21f5918c8614d4f24866c89f4da620d7478706b040e1d5f7ee028f7c610c0f8a31cf77fcda875e4477e69e3eed3c6fe53ccab1dc6402278b3c00eb632d45f56d988884fd42733f3384733199505ba7bcb92cc5d1eeff3708cf435f55d974325fd6bf3d10767f046 -S = bd10583413878f8c71938b58927ef67e7e46a56f56756ccd099e3df80dc44126566525c666f009b0bcd35ab1ed54d55a34b5e7e0c1efc1b8a54199a5d4605fd464111a40ce3c93523f6ab771d8c8b03939daf3593a020284815357958c7b69e8500d360138ab64a94237faf280a33fb257f4191b5ef385a7b9ed40e6fe77b6e85e471c3c7fa922a2044600285e2c71f5b76edfb8ac76c5b9ee0fa1856c632c9c3531763cefd999fd2f497efc4520029c6c08a8b8b2ae0cee0bc81b222dcffff4 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = e1ba864ce9f41cf4ee2ddcbeb7a05afb1f48fb88610b5da39233f3fc6f1df00f593567b29e22b0eafa3d0d035e488de0ef5d318f52244e20274932b8d32d0ae183dc04246e40b0da5a94ac3f611a80c8f511c7b722e290ec139a03fed89c488a6698a4cbdfb7e56b141801994980fa5c384d042758aceaad5e0caef604d370b3 -S = 5596571f16dbd20f8c64ee7c1fe8750910bf640837c9de5c8cf02bf1b36a4ed8e41e95e10be3038334c7ed93b80ef660b1061d3595c647a603d203d2bd9a357236679944325572748f54fb84f382a7d369899a82fdc5da17cb5a24e2811ca881fc748a6ffc4a6610a6f3ca5db07241f7bdae1d6ecfd7eea37b276d8667a536cd45c8841c5197471ea8959c253eff1588cd99355beab1bfbbcdad5c19aa507be24e826479058197313a94902d36df02770cc67a1c3f7adc1d467640ade84237c0 -SaltVal = 00 -Result = P - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = 3730776bea4bbd16ab03e8dfb6ec4b962cf4312ec6432cc1c466aad327adc9db20d16d00c8da8f201140d816fd516e3d0ed20e30fde95bd4af3b75996451cefc32403951b28944bff93ec88cc966be9a09a35432731241018d735560da8a54d951c404e60e1e85fb4843e1c783f4e4b806ad2ebd9086864f475771b2f11f0378 -S = a9a3fac88d8fa6478302de5589304fcd201792e51e7f5e2f10305311fe804dc70728623b20dcccbc996bbc7dfc2ef283521480910df1bbdf72a51151353a791319181e586868f37f17499dc31684ea8632595ecccb553f9bbd499ad291dbbac1813de8fa06a53021bb674b198c79f5c8f2f28c84c09863951501a52bc7d8076e02adb656cafb940587beb815397a9bedd3129c2beb5cef8e3771e985b4a81be0cf6d50b53af7723a0ac0973fc053004831cc3954b2356e4aaff9aafd13ead212 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = a9ba6a22549b61aca519cfec89c316889f0404eb354b5f8d7268c174d43aa6fbde87c4d20a2b9b4605754cc21bceae96f09b9ff8726598480b3785991b48d36ca5dacabe49621d4672e9bff8d0b2f9cd091dbac6abcb2e2f660391217855464a687d23f0f78a1034543fd0948fb91eb45052fc5ec9c648c7e9949014d2a7271c -S = c71119e288acfcaeca10f632f20ca3d9aab35d62f4d8ea66acb955d83c0bf0b9eeac6bb3f776efcb4bae51e47c3cd29ec5d9c8f25bb6f52956ba4ceca9e189a5dd24f1a5f314cc65c2d77b9c1450931765bca3ba701434cc9ce3c4dca806f1f1b7e11da83ce253a1c68bd306770f3d3e8be5ad242b480fab2ba73c20d3922ecfd5d3e4c66ab7a220ce1e175d19740caafc76005056a67326be67f413233810c8fabeefd00b3a3ec19178f48178c8df23a0d08e38179447e3c1f7ead1ac186298 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443031300d060960864801650304020105000420669cf26386b9f299c4b53a9cc5bc93fde922383716b1bad573ef605208ad4741 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = c68bfecaa74019105206ace85d710f160907bdffbce96268b2b63680efac8a217810a053c2d0c0126b6888512802843effe1ffc8b6ff185e8bf518fa251c025fcbf26c9fd4bf8edf5e78995e43e34ab449fcbe58999888657348019e1f80dfaf27f809b6c353aa0195ff8419965c88005120a3b84ffada04d2759973c6204899 -S = b7873d5e394de2c8d17f988135da4563f12d449858e5b26e630596c325046e30f0a66ff38b97e8bd3c7b8cfeed4021ed08b025d7c8919c9c7eb29c980290faa100d4b56c1837bea27dfb862cfb216a0965a1c6a923a65e654569164ac93a3b39bc7f533a4b64e4e8a3b88d0fad6eda12e11b181c9abca3b776fc409a8f069ad40478c3f2f02b0634d5d095316813415ceaaf8ff069d85649b8f4b6ce82ba55a2a3b0e53274f10a8cc0c7863032a38ac5bbefdc735523a683bf92196be7120845 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = 17c6696009d0ea40825e93872261234db051c06cb17230e339574b7802a4b0a2bb18b8a5a2caa8ff55b22b03e56cffc42d39ee346247008deb32eff072cadb4c3b173f82b49a24c74ed694498c0f52155952c8389fb5412415e0585659ccb0363ecbe63f67c9c45f15d1b8a13dd38409dea436bf91465b71626a70f2de339927 -S = 181e3c1d3f6f6ceb7465b6d232f0fbe3270bdd3e6fe05a8dbc3ca9611280b141c11b903c8c34e7a09b1124874d2ac93af9b3d8ff495d7eaf763edf281235066ac6c7c1dcc257049c732ab2288b918f1b7c43bc36f40f5fd070d362322109b51b85574b30987bbd2d460a53ddd694a972fea606ba2b3a4192dcb30490370454e147013d6c7ec15ddc72d81dd7d0601c49a00e61b57ce3cce8ce89b8048359a450a42ed1d7a424e725d75ed0ba5818b377ef809b3c32564562315f21c8d031ec0b -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffff003031300d0609608648016503040201050004201b3650ae9361fac5158b27993f4f51b62133f7172673d0cdedc1820e3d127314efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = 063c070dbba386b97c50ea8c475cb9817fb00be490184906d19a3535ae052aeb06cca546d21505b8080e8f00bf80b55993a698f14b3fcb9cb9e25acae2920bb75f92e3e1037aecbfbe8b36b0c1401c32e325c85444ecfa6e30be040f46cf1a37d935c8c696fac4356770e68498c4757339d6a4f5c3485ce2fed63cec21e5dfd4 -S = 97c48f987ae22938db183cd761956e3dde0cad8a865b70f2392b77f876c63520a12d3bd80850fa6cc20e9bf94d058f2d0a7ebc83186d0defb0ae256237a9fae92b2653284086d49b04ed9ffc3e10f6bb3f9de76396cb4fad3fcbda87bbb1df8c26e2d70f3d5dd0ae4c159ef3aca0fea506887666cd923435b0d40ae434a816b71d72b91a92b107721761adbc7b678d89ae5c8ecb0ab9078f8805dfa033e00a25b30c3c1c4ca8bb3bbdc36b7846267c2a8e5c6ccd97a454fe813c93f50eecabf8 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = e1ba864ce9f41cf4ee2ddcbeb7a05afb1f48fb88610b5da39233f3fc6f1df00f593567b29e22b0eafa3d0d035e488de0ef5d318f52244e20274932b8d32d0ae183dc04246e40b0da5a94ac3f611a80c8f511c7b722e290ec139a03fed89c488a6698a4cbdfb7e56b141801994980fa5c384d042758aceaad5e0caef604d370b3 -S = 1f01900a2786e048f388a061f173adf5247b68076effd95b5c174661b6fc3589981bbc03cbe75534af40ffe0e60c741745cd143f23c2d073e70856ea88442e56f6ebc26e8609b72a955f9377eae375913c032819afcf60cae66d893525ce0bb83e0184ff7dd85893443e10d7be59466c6b7276452501e105bd3e0a8f7553c58ed8700d8e43aad9efd827fafc1948288c12e380b82a9ba22340919a52a9453f2b14e6b7795215720cb6c2a89fa8bbeb46a416267f3126456cb6fdc9fad183059b -SaltVal = 00 -Result = P - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = 3730776bea4bbd16ab03e8dfb6ec4b962cf4312ec6432cc1c466aad327adc9db20d16d00c8da8f201140d816fd516e3d0ed20e30fde95bd4af3b75996451cefc32403951b28944bff93ec88cc966be9a09a35432731241018d735560da8a54d951c404e60e1e85fb4843e1c783f4e4b806ad2ebd9086864f475771b2f11f0378 -S = c5670f7a66b167b3369df23e847a68022be3f2acf2c54b1f9c8b4559466587e80f73b6b668921af9902b72a2cbcec0f92771cfdef7bcb12d3db6032b434b8aa2e2bb2a29f16756916887a79e78552254b702cf2a14c9b9c6c7dcb84745fe27c90f0eb7760aa4f98ed241bbe65a8597aa6d26fad59874b38fb48c2a69e4a77d7414b66552dc7a9b15646acbaac71aeb4c4fe69be40137e79a05ba512d40f86af2d7ad5a1893fb589ec9aa25854083f8535da0acccd0c497dd8ae3a16d3a8b3973 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = a9ba6a22549b61aca519cfec89c316889f0404eb354b5f8d7268c174d43aa6fbde87c4d20a2b9b4605754cc21bceae96f09b9ff8726598480b3785991b48d36ca5dacabe49621d4672e9bff8d0b2f9cd091dbac6abcb2e2f660391217855464a687d23f0f78a1034543fd0948fb91eb45052fc5ec9c648c7e9949014d2a7271c -S = 29bef7b04835e0020a2cba2b9f6db73583493c3702678cc624ee60dca13ef99f58bd2466b3cc3515e3ac52cc01e53aa0b1ca13871ae90317ed90d5dc810a49b0f569cdf78cd4ac2b554f272f3aa541875478901c26d82835bf482451812460da6392f801293ce370b1dc1ca420cde9af65f191dbbb57e0868971451be9030f414c24cada0d759767b93526e39cee99933f4eccee7eabf0353fef6061ee271558144cbc8c4aaf2d2b6e9bc9dcf2fe3f1902f1ef1cbd4617b04281ffae8925fa09 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443041300d060960864801650304020205000430ec65d014978f49b770a449d588ef99f8c92263e18690c237b1c0edaa8da55716adc29d56621402e375c606e7399c9a83 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = c68bfecaa74019105206ace85d710f160907bdffbce96268b2b63680efac8a217810a053c2d0c0126b6888512802843effe1ffc8b6ff185e8bf518fa251c025fcbf26c9fd4bf8edf5e78995e43e34ab449fcbe58999888657348019e1f80dfaf27f809b6c353aa0195ff8419965c88005120a3b84ffada04d2759973c6204899 -S = 80fe5722ecf6c505989f017b63fa71b2723acd378ef8c4b4de5aa611d99196584eed2b46160f4739906533fe54034db7264a19366f7719ef576d3765907f49792fdccde4b94db4b42c95a9c54b2fa67f513039329f3b3fccba4d44f69ed2c9cf3b0469556ef88d90391af612a273ada316756c36d447b4c1b36edf516e8fd0569cdc4fe2254d3165a9250a9163c9b0c629bc64fc7cf9bf96c3b51d78e378678f2309658bbb363ff462f51d145b82fcef1a0282278453b48cd8715d32dd8a2214 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = 17c6696009d0ea40825e93872261234db051c06cb17230e339574b7802a4b0a2bb18b8a5a2caa8ff55b22b03e56cffc42d39ee346247008deb32eff072cadb4c3b173f82b49a24c74ed694498c0f52155952c8389fb5412415e0585659ccb0363ecbe63f67c9c45f15d1b8a13dd38409dea436bf91465b71626a70f2de339927 -S = 82af137868d165dd09c47c95c960e636513305030879d7c4e1f0b58c65fcbc10842f7794e0b80b019b4b384b3473fb452b9e04380f84232e986dddb79957845c0f69f880a51a73cd4bdd041d98576be7220992982ffbe30fe53adfd524dc5da9d8d21a2140056faef2e059a1b282914db1b83494026696601026ac038bed35ac5bc7fa317cf2302f4f211dd8bfcfa3866d8fadb498709bba9aa823c617f8c339d17d0094f31b945c1c8138c944e6ac6a601a705e47b25e9e290faa0550549989 -SaltVal = 00 -EM with hash moved = 0001ff003041300d0609608648016503040202050004305b2dc15a4a45f199a414077ae9da96fc71a00f9ecdb0c40e214da9b370763b672571e471a8d0328d5ac83d2ea45ad2a7efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = 063c070dbba386b97c50ea8c475cb9817fb00be490184906d19a3535ae052aeb06cca546d21505b8080e8f00bf80b55993a698f14b3fcb9cb9e25acae2920bb75f92e3e1037aecbfbe8b36b0c1401c32e325c85444ecfa6e30be040f46cf1a37d935c8c696fac4356770e68498c4757339d6a4f5c3485ce2fed63cec21e5dfd4 -S = d216d9776d8ce35cbfa62808888f67d9a154c87184be9000322148237b8bb64bb75aa5a1773ca9d5b375ae4f643846d07dbc3cfc8246d8ff2f774ff42b184df3495cbadb81a8fad00c00f61fb59602c087d570db0ee1312a2747be0fcd9d563aa1cf14522ace1e202c76ce7849b818b04e4bf489fd723c977f1a2594d65d8595917ad0b575cea228d95d6e3a9ba6f6ca604b8650d5d4e7c182a487a20af05c15139bd46b2f2e48e5db0f184bfad5119a9c256ab601820b7671b6cc48394de6f6 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = e1ba864ce9f41cf4ee2ddcbeb7a05afb1f48fb88610b5da39233f3fc6f1df00f593567b29e22b0eafa3d0d035e488de0ef5d318f52244e20274932b8d32d0ae183dc04246e40b0da5a94ac3f611a80c8f511c7b722e290ec139a03fed89c488a6698a4cbdfb7e56b141801994980fa5c384d042758aceaad5e0caef604d370b3 -S = b4be3c1b7b85f8eff79c890661621f6f3e997ec0b957d540e12b51461fd711b1f7ef026e7f4ecd1298b2f179fd90a55cdaa8c67eeb592dc077d8157b8a04611c904808a6e8a88e83d0965b6f8673253ffaedb437e01e771fa652cbccc976bac41d5be23c5a11bc4027f38d7442e999dc4ecd4af036c201332f7bb1177ca523becf8bc98575d2c4cc4f69bfd9383e540a8eb70dae384f3f07e190f72b856139d5232c3b9037b7e05dbe596af51751da4fa33a03c1d3e847e5339f2fdbf4601272 -SaltVal = 00 -Result = P - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = 3730776bea4bbd16ab03e8dfb6ec4b962cf4312ec6432cc1c466aad327adc9db20d16d00c8da8f201140d816fd516e3d0ed20e30fde95bd4af3b75996451cefc32403951b28944bff93ec88cc966be9a09a35432731241018d735560da8a54d951c404e60e1e85fb4843e1c783f4e4b806ad2ebd9086864f475771b2f11f0378 -S = 204d6b33a90f2ce261f413b54563f97b04021d081789d8b20bae89ce2ea0de539a264a7aa47e4e4cfb9864fa271f097fe1ef632363e3ad3996e7d7d4412138419d5e17c245ded83329bf6805880397b5d9c724e4185b86fe55c88b4e8f01056747ce712b10eeed8081b928c805c4b89b6955219d9441289fd800588012b4a19a415f96096144d88c9a9de4ecaa817e36e6aa1123bcceeeaa6c779fb7fb67a61773fd1c8e9dda482be5882b4f81217bf9019753919c0c98f3d56bd60ab4e8ad9d -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = a9ba6a22549b61aca519cfec89c316889f0404eb354b5f8d7268c174d43aa6fbde87c4d20a2b9b4605754cc21bceae96f09b9ff8726598480b3785991b48d36ca5dacabe49621d4672e9bff8d0b2f9cd091dbac6abcb2e2f660391217855464a687d23f0f78a1034543fd0948fb91eb45052fc5ec9c648c7e9949014d2a7271c -S = 380e96b29f08c307d6894255bf104751d5c12892caec1f449311dea1eba85d63829c4f6f8e4c48bae11e6ce246635ffabe1f921de533867a738de08974c2685e7cb981c94ba95d50f2c663a90c281cf676655d542c5fb91818fa83b273cb7f55d88555068e9827de54abeeb597a7f66b20bcf542d9423826363716ad63fe29ef6a093f723d3a0f8926b678402fed69645b0fdebd943546fb0e0316e925eda23c755a321e23df6910e7b6c908b35dcd0b2e0e4c9dbaf51d050ad6d9d16f67891c -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443051300d06096086480165030402030500044068a22ec35ac1e035665d558ea68f2d2867cae3935aede53c6940477d181f9630c3c8d24a06be07e006049c545aaa830a3ab849ff91d935df4edcf4e46868abc4 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = c68bfecaa74019105206ace85d710f160907bdffbce96268b2b63680efac8a217810a053c2d0c0126b6888512802843effe1ffc8b6ff185e8bf518fa251c025fcbf26c9fd4bf8edf5e78995e43e34ab449fcbe58999888657348019e1f80dfaf27f809b6c353aa0195ff8419965c88005120a3b84ffada04d2759973c6204899 -S = 7264f99a15645f551eb08662418097e48da66f7c3d5a953d7296330bfa24d02f87f554e19c20f98a848daa9de39a22b848f514826acfaebdd93db456394713547ca172439f18473f36243eb0ce85cb7357d04f011e34c139d72fc540afe0e7a5927c8466bf28a76e572c851493f23569ccb73132a650ba5af14ff2cdb20a3dca7fcc465e6ac6998fdb2df6f3d88044b4354cec5f7f6ce7f02d3dad61e764058f9a69a6c4e63d4e0ac89567fe23cd1eaa5726d567d7a647fc2ff4ab299a05a896 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = 17c6696009d0ea40825e93872261234db051c06cb17230e339574b7802a4b0a2bb18b8a5a2caa8ff55b22b03e56cffc42d39ee346247008deb32eff072cadb4c3b173f82b49a24c74ed694498c0f52155952c8389fb5412415e0585659ccb0363ecbe63f67c9c45f15d1b8a13dd38409dea436bf91465b71626a70f2de339927 -S = 5d90ac2736979a5a789b927b6b142bf08cdf50a5018e9e75cb03363f255d4bf10e0873e39c7cfe7f0faaa2594b856ebaea0b3a83c6c1fbbd1201e533b2ce14e726ba43aff51445e976f9158d6b369fd121e17e34e529a9f7935f3583943fb82eb0e551e7a183254cd1d442ec87d3b853613ced92c28ad87c7884b8e57729fa36b25767be0b77108d2f1da7122c3c44f71ef1fae6399400190863764d2d28076953e579bd5380058cbc06671b76d6cc2bed1bfb1eb0a22e72308c5c294bc4d339 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffff003051300d0609608648016503040203050004409e1ae481b6e7360c34c33703717c48bf5c84b980c112931713bb8563dbbc3542dbc309570342b078e7955ded523fc9b8e992724b26452984214d8f3d04a7f0efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 0b86f0524108c0868477219f6462fffcec9e0c3f0bc83ef154f23be0c51ce72969d5e94fe758df4988bdc97b15a26ecd30b1d985794db76c6a9457cf23d021b84145eb1e94026027f6184a83268334b36c5b1a87b054cc6ea0152c81c8b2221d5994cee154433655352cbbea66651f6e0297fa432f66780fad7d1797d5d2f59cffed6125810a6db340502922acfd7d0c0103846e5041c43efc3551adfe7f08180611bcf21175160441b81bc2cc8d8e922f8e21db688e25a820453ca986bc4941 -Msg = 03403f0e704c5e28fc547e60cdba09c7bdb7e4fff89fa2a0c667f8d9a564715b9b556372caa4227545e9736122b044c1d17c9ad1ac0ccae2cedcec0029ef8dd3d3cca4c3a1c7c75ff7819f00deb29aa95726df32f00687a694590ae9a7caf79e53ace9471c3bb6aebb25e98529497349fabe9d6cec1741b2c0e53adc487e1984 -S = 5959dba95cc8fe826428883acbc57294a10e8e8ffda441b07f8fb2ad17f52589774c27c2f1cb54e96614bf7b7a89c4227168ccbea47a941540d2d71157844ae0210c6fb7abdb58db349ce1515b63303f85a6bdb38bd6ea0f9a340fe70d3aba17f4b5f2a36dcb37f354eb86533e4424c7ccd8377775a28f9beb6921c8b4d9e89811ff748bc1b026e9214c9c16227a36f803cabbd738025bd9f7cfa1c33ed4c00b5d8035389c8d6a02051576d33c8e83f2f72fdc1b35a0dde73fea1e2a93dae015 -SaltVal = 00 -Result = F (3 - Signature changed ) - -[mod = 2048] - -n = a911245a2cfb33d8ee375df9439f74e669c03a8d9acad25bd27acf3cd8bea7eb9dbe470155c7c72782c94861f7b573cd325639fb070e9ba6e621991aefa45106182e4d264be7068035595d7549052989b3e7fd04cabc94012c1278a0ef8672b1a51dd1a9e276816ba497dea24b4febe3dd8e977707bcd230ca6fb6f8a8bff9e6ba24fbadcd93f00126b19b396a38e6ef86d18fef945b9154c1963fb488c7025953511f86d05638bfe056493730bc6778446e59cd3c5c3acf07a0a3a64943793652f10e3292aa7a6d25a03181cc6f6ba0658d909e59ce2a02bacc9766fd8c4fbd4ed9c23a866844b8a794d49e505f9f944870a71aadbe5338039825c2dff81af3 - -p = bf96de108963b5113399b664765efe046e2dafdb70d6e5e29dc6ec89b789b059348d74d89129c7ade9ddb404c6dc3a3437c7fc9f23bc38dadc8ffd0ff757999f5c2d510b993056147ccdf421e03d0be2c74ec333a9677c430cc604f5550d0d86defdde71488e3db889c699a5cacb44dcdae2f3cca38695e783e6f6250827efb1 -q = e1e7e33618d1b64d6862c132e4b1cd5fabad20ce62bd97bce2a3f5ad2da67bb0a7f0b9e48335a33b7b95e77ec4c47e91416881f9f7c23f9bc1918cc644335c74260e90cd7b2e0fed802f19e78c5ed80a431b38630d82f982c74a0381b8ecf943c60810fae90574e216357b2535002316d9529cb56420f3cc82dea37cb624e1e3 - -SHAAlg = SHA1 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = 04d5d202ade6be1df96d263021141bd6e4e68a14c5b413df73b817df8979137377ee2df5c0e60d3f67a8ee6ea3d6f5e6da97c196cdf4437d1183d06cbe43740e6bc88a2759988919eed421ac651b870ec5ab0d190fc9f5d5bc64873e66f56147c6a90f1edec2dbb2773ae673ceaa78588b6b9527f2fbd1f15da265dbea558125 -S = 6b2703ff1a8d96808bf97eb6d297a8b8d11f479e22b8471e03d2713d124f7c8bf46225e8de2b9db432c39209c242420bc9a17196a38c1b2daa096a73e33912b353a6adf9d198d15eadb6f287c5d2379fe8c07d9e5735bc4c474c2ff9bc7ee6d3684335f7f825664d6272426b2fa20bae585f7bb306b352d916679c68c77ce0d2032cee4909fd02f4f4711ff4e771251c3a9e284f37fb1bd417d8842d030500d84bf7a774b5bbf089e2829c7e7dc27f4d88408e5b549522339e6eb98d51718a219c0fdc20e26bb32d85ef877a5fae812ece7bb04a1ac5a0dd71ae4e8d4c25aaccf8c1f5b9c0de7e0491cd754a675ab6eb8c630b8afc49e0597ea6cacc6c37fe9f -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003021300906052b0e03021a050004143d68a61abc2403258d48c94be567caa29e315c8befefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA1 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = 3efa6c9938d6bc37f0373d0baba3697acc3bed498f9dfea7fa0af06e11c405a64aba834b4067094fabf822e390ad1bf3b58112ef580d50d120aad95c54d640a14bd9c0c824a8890db7095809caf84a338949f2a63090a9250b3e255ca00c4e682b9d4c9a4a5ee578fab20605c24c9f432edbb4f57fedb2a9a10dfff65d2fd403 -S = 343014b8db6ba664af3dc07530e444976bac0a7fd3505218500b0342c0c861d508f55383c18ee70cf47516acabd50dbc2ec18a8cc2054ab87496b9cf22e4f576d5f208d0cd3be114f65f69e0ae744e46edbe0a378942e24eb51fbe25a0caeb654b20ce9a8feda1bd02981a24ed35fd139d107611cbdecc7b1a960ec57a19eef79bac1ed277b746772b405c7c29cf8e32c1c7a49557928ec792944bbc87183fe828a3469214fd35c8ca16df57a985d610ef80db9728f3d31529a7c39da03d39a6735117dc99225921d26fcee7779d7ae191934452207bddaa60c0aadef72c1ea09d5a1d7cac615a8a5b08c5e429d801f868683a72263d80db270a413a8fd9c4d8 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA1 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = 0017191f1c6b5bdf895837a17e05ca6119ea3606aedb978c5f423962ecac0811cc87471f7c2985331715cd79277a1e48bafd1a03b9b8023d7683e2208472090fcb9fbc8adb292c52817ca5ce98d307ae22fc7ace985b5e5d7e32813e392095ae25e7e128e3723685f01625687c186fd9796fbd30f2cc91359ed87d85b5bc9338 -S = 1d2db922b68b7e89cdef4a238e033500962d61cd39bcad53494663921ae6b0f7710728d9dfb8d52d7725d4f11ca058b1195b1c3c4614c32dce6a2b1b9ad1db261bfde9cc8258787fa7ac9884ffb5e69775ee76ae8af3a15254898e8497b77d7cdb161415a1615eec8ae7ba4ffb352ba459a1d84e43a04b616a13cac644b38c528047841e249ff2795ef2fd066615828545d04c82e92a027bc110c5de6a52355e02bd7888c97dfd48a925528e48890323c6a4f44e5d04ea05cf3009e838a6bf438fad103ea8ffe8d0f7d770c0034de693c7bbad16e8c6a923cc8976bda5bc08b15897075162068b39b362699149e0cd4eda9ff1bade4fb540dc27c17e4119708a -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA1 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = 1577757d0f460af152dc68b6ab25deadfebba5f68351bb6e2e51ee766fc437f71c734aa3ac4b6b7da506839b5708732acb87a8b4f7eff09e33858cf5f14a866aa822459a11355e939696ad940823a51590ace407e8570a5dca42cccba96b44cea0cd8beca8cc8a3d0dd30d2a233c19753570807abe4fb2b4dbd2d68201ee1a2b -S = 5322e332949c0f15fe63f09927e2ef90a0f1eb2262fc8a7dc602facf8b5cf74dd0eaa2638a6d4393c0167be176e8e68d3b1a6dd4c7f043dc81e702b3b2620df5a4032e6319ff88e19c9cf57fc03f3ec5ca75db70b6b22a38f40a3dc214b477da2e1400eba49c35323c8d83e5159eb4ca6701b4fdb99f18505f266ccdcedbeae59b36fec2616b04da979376403a435d3aae0113d4605b9ffda0afe72923ed2644069a408c148b4e781387fe49f3103841eff840f0b39b298ab4893ba2c292af33b57f6f6f69cf5464be470f678ec07f0ae97c9ff292d896a7daec48cf9e48ecd006acbc2c8567368be62f2178d469ae958ac0b5bd66917944c4b53d1f42ea2f20 -SaltVal = 00 -Result = P - -SHAAlg = SHA1 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = b72914feec0e16233c24031390fe31942537dfc03d58810915fb597b163147414f22e26b23f3c7ee3fed32ecd0dbcb36f2b3c2106b791d3499615119a93410740af4630021c3f87a3f01bdf0d0b5ae3cd52eeacc94ea0da48db6baa5b117770fcfe9be454f4650d022a9cda7f95382adb5ee827c1f71f861da43bba796a32319 -S = 2c2a5042129ef97c6235195df1da7b3d80e08176900daa562ea660258269e1a55c73bf226fb54d21f28b8cc02aab8f453405f2c0ee6682ec8ff2d1d8540aec1ed953f53847bc43f0c89608164532da10188400e9e7850114ece817aa854024e696fed5ff74a3747de548fe431d4a95c789bb377a8add64a8583dc7fb203fd66ec9e476232c25b9d454aa9ea7332672cde4ef7540b12ee28524b6c399be32805ac0f7f0db08eb07b93cd24a23baabccdbf5c8437fe2c3330586757a897242c8f2673ab8295ee88e5ec2222fd6519fc49cb1eea3d21d63f07d32bf0874dfdd5e74f511b2e06750ceafaef4238824f92c5da128042dbf64557cd6e4d7ee35d479b3 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA1 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = 25d08c937abe386aa08b54cb9d7537829c478e53e67df73b0da9cbf76a153acbcaaa9e7c6510099e10172016b3562dd7fc126fef5561b5c7148e2ba6f2c07378bfd7f7ce54977e25c808fe6be71cb1bfdf936b793d1c2b6a18bdf0658c74cefd6b1f40912e99c086322695d42111edc4ad932bf885f782ab81fcc33a207b73e3 -S = 93a032b6e997c0f9ed6261cc4617d98afb80cbd6450a3d9ea2f63999dd68194c9451538975d7626d77a34734d99b5992f98ed18c7f9dc0026fe34cf6583a6a36eb6baadb8316e3aa48d9da4244544da430cb8a19953d84ad4575733d887ed3bbcb4f25389cd36b1c565bf661b1c918a14e5e00e0f0857900ed4c98beab9fe6d1f66a0df588b61afae9fa31e94464d85bc743193303259e9806231cf5cdd4d4c9da5691c08156aa72f4da7607d598d450a5c852a8b3f577194afece74e59fd4ba8c5bfa583c2fa9a6f6aca7c51f772d02fe8e0bcaf5e4c2c7cdd6a38f7264d717aa2b30daa6968a4e7e7e2dcc1de9e34604f0b80c8b793f882d35497d81ade352 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443021300906052b0e03021a0500041461ba8219a8f4252ba5e715540544ffde89da3072 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA224 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = 04b9dc9e05391605d1101e84d4cbe1a08bc3e12a97e7e21e10bbe6cb1ba15c34bf5895b7f4c277ecfdea75d0f845bf23b438b50ec2dba209cffda7fc3168f5a4bf653f39e683704ef99599f8c9fa2d3276217080844b2dd33193a7ad062cd385adebc46d020567f26c1970446e7194977985f9c805c0eb44e087d026c5785e9f -S = 39b142d1b8340384b8eea14f948125101c3c54bb339fc06a5dfb652ff28df204b05561e7ff8e1e6630d7ee9dc7a6147f6f24ddd703bc753cd3226e35812a821e68b7a77cae8429202a74dd1361e8e568f99ee2799a92500a21c73f98024d091c5e29e9531bfde05a7959a3d8f390eb17a6292d11d361a0caa7a5cd2900df5fd2f09679c9a1e58e525721fd068061e5bf5c95d1f491da063532ef620d537a45dc74cbf249c97493bc8985cd0fafdba295fcb65b5ce134cb30d504c93a999909e0cee5aba1d6a6e1f3a3d25403d09bff303d6b89f6a81d8c570c735ffac0d0d415c7b6cb7a10f68d94cca2f1de7975a5073411529b48b2a148a9353c536369df48 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff44302d300d06096086480165030402040500041c330514ff465a496206061832aa09d4d549aec683133b10ea884bf3f9 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA224 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = ad12e61576bc1b15d5bff13ab66a496bb5f643dc8461bc858d7a15d3d938369d314fd3598305ee9087429e8fa1e70e600a61c8f82b7e34b2497f5bfc676ef15068b2936775e04da99ed45fe7c401414cb605e4919a803b718f27fa5d90149e709b60ada513f43f48649cbdaae55ee91902091e0f9a10d9aaa699795c1cd243e4 -S = 3009202b1060f77de9e25bc5bf80062a16fd8c8a7e27c4f8fa2d069c6b706bb981f0e2561d8dafd42c647c844ff30b0a226704bb85a3a58dbd5baaa8e19ebfb7635d4f502677b6575b31ca37ba4a51e747fd97ed2a1fc330f2ddfd10669aa9ea4f13c990b4cfa7e15e983459df317ff83506803db89d9f15f3b93ca0acb22d800d9a2c36770718b62a78998fd13471107afb36b700aedde93fb9019ae9aaa9ae4f33d7a18cbbd8474ffcd38a6b4dd95de015786e50811bf3de5dc7de6c3eeb721e8197a8cc537e1d076a887634cb7af055305218680b605055d7e999b90a348745d277bc36dfb38c431c9edb329d3c5c750afcca77ccf159276ff70b6e8f949a -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA224 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = 3ede763590291420c8da355f5e5930447317445e61d0cee6970dbf59a4ec4e679123ea0c744373fd423aa945e51ce5308e2307684df4af5edf23b0ebc7fac138a07676dbb1936f42c2c9d0552ed7f0573abf560da512e123806d46cb4044c0a712de02e96ea171b9ef9090d76212bb811df5199792b2ccfd23f36a413852b17d -S = a3dfa3b5ce640d92f95260d559bb5c40710a2d3cb38b816fd3b790c78ede96bdc213e7e6e76f35d5e24cf1a6dc54d856be83e352f55b3caf98b6dffcc952023978a5a6900cc9b0201b99c90795c38ecf0a3dd5cfd9579378c57c0083b2584a3bf859c69a553ce7cf8c1ecb98376b4ce90e1a0271c4043654f175e90477440f7108b960d1e3e2d00743e0a2db96d179999709722b046070c4ecb6f3f3650365119004b016e62272fe9e7c06999c8b1f8e0ac56f46c668103cd23f1457f37e376b8aa5c4235db08ceb577945f3276b931f5933bda713f0c8643aac2b0ad92f7c8021da0072444ebffe55d0cf183f002ffe1e8c221508e7f65b73c05f9362214440 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00302d300d06096086480165030402040500041c6622f8e46c8c838679d4e8af043ccdd2f9bf3a6820a5dc64a446fe67efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA224 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = 250f95cfabab5de46ab2bda3cdeb3228cf7330aa1b5764ad75623c795634a9cad69424c9cf08ef3b40a29df9ef1cd4a053285289b0012efc844660a0220884369d22db87e7c8939b3a63482cb79cca5a4eb721a1dd23ce079c4f549ab8bff7193e5ec4f23b16d16c229ec6266d939cc087cba5d8eae6cd3884251f4d60808bdc -S = 580511902d07b267c4daa41b6660db0d20795afe0320a961a36b384fe3537f7a88e31e09c5e3f660d2ec4e176c2ebf7e45be1b579831c0c75509380684e5936b79097d6c3b7262583e4c2f81ba09e78e542e823e855ee97260e8fc9d53fac6d452d601d07526583d078e293c0f183d716a0f7b37de31b000ca7bb095303d4eca67393886e43ac271c119244d4c45d98212924402b37660c0f7dfcd34e4672011d1aa721337b1025bdfbce502f017a573a18850cbbe108bc9fa978078906a4c1d4023f8158cb5224b46f43f70c8029793981011d77c816749f6ca9a71c2749e0e151fc69c7f4b39fad8e96cf4dc6ae451bfb506d9faef8b377b7c5b47e19a3a59 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA224 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = 8db3a4d5a7b2fa1c3cf85a9e07df0aa00eeacfe1defc527218c7c8c82c86d21065efa2c2266360797369cc02b25a24b2b35e48fdef961c450d9b2ef0ab2899bd5a132958ea82bf2ce95bf77866fc09a5fa2dedd70a52c3c246e671bf75248e1e75077fbe7d75dfdca6b72529aa2d801feb400694b7970e90ca8eda5c14e47adb -S = 9724b7c6909ae1499a06410557882d9fe49a804c68c172cd5945e40132d750d47a454f155c075c0e57003f20cef4a1edc84d427b6bd9f61617ab502ba6dc5c6b1d032a380898bacb80d5484d39783dbfac37c4f001fd8d4e1bb2310d459637be04cd5fb2cf6b32dbfd214b8f7cc0dada942cc41c9f476bf6ffa502bf7928dc8610ac0097dab03f79171046af23887c2d530463714bf7fe59933cad26266a117cd355d0402a4490472b0006f6e915c56e204eb480ab48fe9ef0dcde5660cb9ad235890713f77b5333c1314dcc741c2c8d0fed546d23696275a8d578a0d39d4f1dece330d73ff1c20c72ea82e4b714db309a0063edd35b22f12ea68f5c5723c8a2 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA224 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = d6fd570826eb30d7f3173089ffcdc2f791c60cb4bc5760e6e3e9d3557da92bc21681ff7a9646192bc6331ff5109673c487c957de276455b85db1de0eca603132447c7ea51d9e4be4a8611884fa153e81eeb81dd46c227643ea7f167d3202b56666d81db0425b8faba289625e44b4edd6ce7aa7be13f88d30923bc4cb3ff78006 -S = 4c142307690bf57792293509295ebe275716356260e0fee39e72b64fd6210f547bbc8eb84ee2fffe5bca0121735f934d1832079031d9813902269cb6a814a71a09012f08f6f8ae10907ca0755fae622328feedd8da1ca666d2b713ca0d5b6de85b9b1cbbd6874dd980f304a313ca07e6c70a44e9dda1bed3d9a2cce521473661f33b7fa96c496b8f7a9c77e9bd0ae0dd47bec92c2a4dc9f75af9280402a04014523957efa5f52985eff48e4f1bd54858a956743dd2badf858d00c83213908baf95c527afcf0e32f7c97d4dde5dbb936ffb09500a2bc0bf71839d55489a21d642ee455dfa8b525a4d4890b2283eb043b3bf77d2ed7e2885c32b004fbc89693380 -SaltVal = 00 -Result = P - -SHAAlg = SHA256 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = 8457c53956849cdb39bc8e7657d62a2cda9e13e1a5c3574142f1fd041c3add70efbab5207c7b78058196e9aae89b69bc3f330dc96804f44892d5d8da68f3e2cf87d3c3ec36f8006b51178d44877a9eabc6a2badaf2301110dd060fda74a9319136e91824ebc5dc179289a2cc9b3971025632419bac0f55a20dcacb8ca92372be -S = a2a2c0264dbb8b8810aae0b9ec7408553803dd02be6247358ce39f98f0c0f0339915347ff3c4dfee0e0a49b675ba69e376f3dbba56aae846cf7f986a0a5f37fc9971a58e3217cca26dffee8655f3025bd61776683feecdde546fa88fb881d619a8ec2daf092079a850340f6af41b2dd11d9935bb06c2253bdbd32a6fb8bd5317d3c9c3be5b683e7fd6366e1816895664d8ee312eca47ecf862be009d9df699a7d2f515c69e3093fd50a3babe9ebaeab6267086a3185a908ea29af8eecf81e2be7c9c2ae33cb2380c73af264d24961b5c7711b0289e1a095f2966656ead1fed95b6c33d7082c3868f1f7b706f9442ddb76e3582f73e4839a0a110dbb78e9cfcc5 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA256 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = 6918d6328ca0a8b64bbe81d91cdea519911b59fc2dbd53af76006fec4b18a320787135ce883b2b2edb26041bf86aa52c230b9620335b6e7f9ec08c7ed6b70823d819e9ab019e9929249f966fdb2069311a0ddc680ac468f514d4ed873b04a6beb0985b91a0cfd8ed51b09f9e6d06da739eaa939d5a00275901c4f8cf25076339 -S = 794d0a45bc9fc6febb586e319dfa6924c888594802b9deb9668963fdb309bf02817960a7457106fc474f91601436e8954cbb6815350b2c51b53c968d2c48cc1799550d5d03b41f6e5a8c3c264d2e2fe0b5b8ff53fdcb9dd111c985cb488d7086e6548b4077ec00721c9cb500fe07a031c2030e8ad1dd0112c34ffd9091d77a187aac8661b298eee39eb615f9715c4c48a6762ede55a466ec7f3cdb6a937cfc80188a85d8f8d3a2a80b199ce5e6375af8f02f06d706a34d9cf38318903965db54aaa7d3fa7a7ee58034cd58c8435739c8906366e2ddba293f2fb2c15f07fa4951014471e7f677d3bdacffc4c68a906e08d68b39f9010746cbacd22980cee73e8d -SaltVal = 00 -Result = P - -SHAAlg = SHA256 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = 4ce993829f7b8112277cedbf8b4ec59244cd7ef79a7bad09cfdbd1109a1a7348d7f472e57cd69853cf4070c2d66e5ce20f37e2eb623547e154265f167d92a3f03caf84eca981ffe3cb45728d0c10ae43e9b44d09eee346cbe297bee73fb021ece5df72a10ec4df4a85539926137ce23c3a0b685826cdd150e1f4978bc6bc16c4 -S = 29865f133c69122e1b309b299270b5d693db89c5192eca5c829c795db460cb1dad3d1f27d200790fab035c90c00b238384bb30ee30752425f2b7f424d71bea79993046100760f3fa3c6e019d025338c13940a97778ea67e6d6138d8e8ff601d2309f02762add479d85d25fa31bd1c89af97927dac2ddf818cfe2179548db4da69c163d8cbf5f9c98ea33957022a52d6f33b19bbd3d05f40f2dfd49d999184cf5f9bc69fc1b21359c3c85ddebb6936c4f49015026539e8c4aad2dd3a3b4ba309021fb317348d12b560ec608b74f812e3b74e4c8407765f30d6d03a5c20db821adc4c844018d57fb5364d0e7c3d55816782200ddf92b13dc2e0d4665b4cf3e1059 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA256 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = c801a9270165955fa4d85fd502c0e6be0c91e1c453ef734f331300034a6f3e8a2f958f9361558e1a7e25e7eab6c76d617e256674898029f2f4c9ec0dc14fd716869b5d886698cb4841f8212b28d222b91490a731d70838cd52e9dd46e959329b34dcba0ff77875705517b59f402c2d4d34994b0325d1c865b6397db7abd578a0 -S = 290d0d444ee458777b5fdc3207d37054407c0dfa6806296869d3ec402a18209a3d06eb63d995293697e8c0a0e72489bfc9132857d6c7a17f4852e4e573a48d2a2a127fdd270092f5029d976b060a570c90d685bd2325d80c9867a3b245455545bfae8cf87cff314f4d0a968229446dbf24adcd2a52ef9abd30b4746c2e04c0fdf52655427eb03bf63fdb208c6a776a3852052ac225eb33d7246f7ba624723f9c22abaf6d2f9219181ca62e44bb53a9ce8b45e7c6d742586a234e5de66df4ffbf7bc9e7f815a7d5aadb2f727f3151afa6ff48f6090d9fe08c8b0f1505598ca4a4ccbde6ab0f87b43059065097c737e53dc17f200c3a54b00d709a5b8bdce80f2e -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003031300d060960864801650304020105000420af8893e585e7d2dbf3b8d3dec0802db4ee1ae86e8bbe369d8e1eb3aa634eb2cfefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA256 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = 2466a246feda6fa5cee22c2f33ed9d643c1f6824d9f327719225bc7678cfe4c85cd210ed4077701b0b5650418177a74c71b8eda3306e2ef3474f5d326990eadea84a9686e822878c932997298e01f2b16c42e019e21bdfb67b3df5478df444366c97df1bdd23dc82ce23abee44d3a61e9484e88ed642634197b52dbece451b59 -S = 79c3b93019bdb8a6d6a79e813e4d96928f730afc010657b1eb870f2891219de5fbd464fce97b2bda12a9d84a3d5c120c660ed0f70457e223809b26a996afab7c23143b411a1aae566d7e9d19d278044567b5064bc918bb101cadc7a521c31c5e1962a7437d8f799ee6a76fc2f0a6733cfcb63246b1a864bb14ae70daf848824da565892d750af7c5da6e02e4889143a746e7e58b562d19cd3cf3d97795e50e1dcfa26d43f00357c92f01b327718d6cd292498dd29d0d830408b568b2c91541a76b21b5d4efea46bc128d9c4aea4e9f60a4a601c876736bf9312a00a2bd81b4ca5d8e37ab2c79dacbe7d8e6abcc4691db64649cdff212f467a9d805b2c38cd031 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA256 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = ecb6731a006eb273f6c5404a2e2d1faa5232f7afdff5b69be1dc7927fe88af17b5077b11e84b5baf98db08d3f1c99d3b86e4fa55dd2e6b542e91858368cd51d975b5adcebf9bee6ef309caac05b276f874a70b14cfce2e237891f003a8d3f3dcb328cff98d45b3d78db5507c72cef20aa4e4f094bcbc47304543824ec480dd48 -S = 8831265bcd54bf33d8c46cbd48052e9357c31afee92276b1b744e2521da9b83968e9ca90446064d8f174b248f64e792f91f4fae15252688e0f8ad38b28a532ddc7dc59e77d81b7a51dda2df2f2cbd5195c87b66db297b74296d4058fd00a060377dc1ec286c21e4f84c17ef315d443e89912e6b5d5f7d4ade31cc2b1aaaebcf09aaca20041b5f9b799b5b532391f85fd236ff3fa794baf4b25a2a188b0746728f1cfe0816b37d8dd648c53d76b81ee42ce27bf07baa27016b82c9ef3e1f5523ded7d35622d4986a6699b261f483e9b68b9c99e17e4aeb1c7baa84be1177264894ed5aab8592dfaaa652898b37aec28c19d154df27956f604bb6a30d0964d4e97 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443031300d060960864801650304020105000420e45bf84dc5abc5c28a27625b0c96d7399fa1bba8fdaf1d5b5354970b2ff9dec3 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA384 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = daf4399ffab3de496e3ec347b4ee6f4ebdbd83cf434ea81e5d2dc6d351577771a9fdbb458985ed913fd2f5ea1cc5c0df8203eddb3ff9c94d191e7e05aa7887e16f6267aa1b8c9b393143cdded1f34a02d2eab60a125eff7f0ab28f6ca6f5c60853aca79559d1d1886b1bb1ea7c80f7fed5f94624658530fd587061d0ebd51a2d -S = 38aba878044ffa4572749376a12fa96b3b8cf778e68baa7ae05b4cf0457242f3a1eb8451678e79ad73741e169efbabdb0469a53dafb627ca3d14fbe392fe311e792b8f274e0d8439de0d9a82c14082abcc4253a5a7292f846ab816419b34c57587f2fda5c6be4f4a3c4130acef535dab4f0e05f5c8b18993f57b167298ba24b0d238964e0fa87114079fec872c673cb7d961ccf7ceff7fd5ada8a6f309de2d96a40224b12b921ad987b20e0ccafad43d0220e24b82aef90151befdbaaddfcb5b35e505912438668b4f61745734879c54c1105983c83a569560f35265be0d3ebcacedbce139c489f4be3c3befba6dbd6c5c92e0441a4a789ea383516be0f4540c -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA384 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = 6cd8ccf65bb3833c81961801ec68a9735fefb8a5f7e3e63c0e47fd6b60f934216c87af801e444692aa9b8737bba4fe62cdf5b485d7bbf54a2e095684a66ff765facf06f16e6c84b2b2444cae0aa05196ace9274069bdc5579042895210ba7ca2dc58d8309452c70661386e4c21842a77c47219bdf512ddccfd9b9cbbe5024b41 -S = 12eede9247a5fd5579fd51f172ce798d20f8d932326f21ab0dc698711899c68357158ba1eebe07bfc1a78a08aad655da3a26556896267afdcd5e55d2ec91fdbf79960321ad13788e33eddd06b2f25347af73db9cdf628e8ac7a57b2a03555aacfd4af01afbd049dec0be8e279ad369a3c606fb1663e4b0f95be5416c5ecfeccf73c5d829ab5041e21ad0d1792b4536033f518b411c3c82ea162cef14dd704d23a278c0d71ddc9adc4014379c920e54ef8487ab3f5f6e991e50450c609fa769b60e057e6afb511df74ba7cc6458fe493a7a23e8267a742d20600f3c9261efd554b4c0b366ec0562c94c4180f34ba40780a24e8c36e110c40b6bb28b22394177a4 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA384 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = 5fa43f0df5b0d9486b1e5f80a604230cb1159cddc9681462b47ca1aa547856c97bb7ba7c0183791014215a7fd00f71dd0f8996f28351162902b0a8a920b8a2c103cd6c89736435c63109e60f8aa7542e2b04bac9378b6642974eb2db924b361e9dee3c7c74d8743469dfea76fc5634c8ad8ef0aa0e9c6e751c5da989cfb87ca7 -S = 268bf5a0977722b24a174d83dc7dbec6ca1c392ad4a48d68af1b1ce30034e471dc8ccff5e5da865f677eb85c1e3022cadc89ec82624bc8ce5c632d1863a4946f364718f3566d38dda330ed68deb56130d10126fc9dc4f501f36e6e94507d5a556c8de76efd8149276eac52d16af495679cdd4361f66b7d963b9faa5ca0f8920227071c519f3f1ddcc7c03870a9639e78ce5f1e61b5291c190a4f9ef237116ebca742a513efe5fe39b1dd8914e71b60128b0e180685008ae206a64cc51c218f45db765c1af655457af34f94789ae5527dfa840a1cc9dbaef8003d81d3f59b7a3c440a9497da1be98182cbe368f0c984710f9ec986428f5c7a38313d43bcf680df -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA384 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = 40bf49cb5825523aa5aea4c0e6b08b7f857f5e8a1ae01af731c14a364d272aa12d670b534d99f93eb04a9c78dd715cd628a4c8bc328c3933b397b23c77ec0b65a7a44f994a37623c0b34e7783d3660d11c13970056563efecaf0d25f8f2ac5e138dedb4556e7d55d3fd64d670ee6e199eb3393fd8d26707ffc3470459cc89e3e -S = 825731d01b0c197e2b27c4314b256ea5bc09ce9f012ca120695ba38c0ebdfa8c8802ca5137ef675f76a17038780f94f753b1234d0531be8fbe82e557d9357b18bea2a5c1cb83dd129e31e9c2aba44640145d2ed36470ee57a9486fe04ae13d1be2ea4047ef405a53a2d4f5bbcd21c9598de98046191bb605ce7004e3250b128a0d7d075ea7bab16a30f165fda23318547481b8b6c9bea0843876934bf7c89e013c9f19a8e661ec2e78013b89aa6beed57d88cb27ac34cc18f231c6e6dfcb8cc1580fd5ea8185b927147b564d31f724466d64692a17dda68e0b8fbc1a7cfec4bfa9c9f96f73bde2d0ab8948d09e1e739d5277a4d3d4e70236e9a3dec388986684 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003041300d060960864801650304020205000430e57e40b2774ca1517efc987400aad5a59ffe873f0532d8a092db7b4f7be006eb591eba4082d41eda449a261187bf3804efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA384 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = 752fbf49ae63c7853b3ef6f52ed324e53867925bd5d4c49dc42b93f3ba9d7eae579c4169593da98f10e1a61e1214a2aa2fb511a4a75849dc9be89445c29184f85ddc877c6d1cbb45230a047a98ac5bfcbe7b69a397c454cba44fd90fa13f9b546f39ba0a52c8a8ae5c0038932962f8e3cd00c1e00be28c70c8a787d9be6f69c9 -S = 80d7286710e5f165eeb63d2936e8e313ac5999bd297d35590c2b6ffaa4b7b7ed30003f0b83c1d1996c8593a37bc5d7b501a3d126ac6124779a23718497002d9dd2ce891b83d185e333af05460c6deb65a509640f775a0d3c70e55112c2e4af19f4ccec7af9ebb34226164f1b47d50b8ecc1dc3e0fc09aa15abfce5aa3998b5c2b1fde261c35eb43220f0d64529f723801d7faff841faba8709f6ea7751f30428dfc58045c84995107ee013ca4a84f65b99adde1abdefb5428f834ac8da04dafb9beaf1813f73a4bff2ec94120e3a702aed1184c387ebda2abf1959970724299b9a05f4ad313d91beb5344fe1fe13b3fc3386c279f031c77d74bdc9bc97e22455 -SaltVal = 00 -Result = P - -SHAAlg = SHA384 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = 18e158ea033c33dddfc57c8d6c8f132d9b129aa64416cd971bd3119ae1564fcad726028278288f6767c0d6a8a73906840a67b50dec8a302c20760fe62bf10dddb05d171a2c97a309e41e43c51b787a9687d1ceb906e61e5f8e2136f76205a1b08ccdbe3a875017cd3c28ed6d3013186cfb990e30fcf041374b1cae57ef5ab24b -S = 3491d346ada87f5585e13c5e3ed29c35f7f8536d16b99a57e3519c6c0fff826e6e314ffab85c3d5918473cf49dfb066cf107db8398840c53a1582a2bfc792c7cc1b72d3ea0a0ee0bd9c5aba576a9c1a41836caeb61da3b019fd553ec455b5b2c66da6682595e1d2731135ea8681e3d0b262316763f0840f030e6e26c67f11c1bf93dbe71b82d593bbe869ebf8bebf831e62ef31d2851469145a1f618734baf114716c0949a28a27a83521b5c68bc5b11081f6877562ed33ad603b436b7a9f98dc0f2968350810e24477d87df566a77f6197796a835b1945418667596171868a6b14d0617a2d76fb85130d8f5fc397326ea5f43587ce1812eb86e1aa584bb936b -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443041300d060960864801650304020205000430cc8f60696cd0d4217858fd042c6caa3350dca7c9e36ad539e96052393204ff21a692e6349566d013a30f59c2d6bab449 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA512 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = daf4399ffab3de496e3ec347b4ee6f4ebdbd83cf434ea81e5d2dc6d351577771a9fdbb458985ed913fd2f5ea1cc5c0df8203eddb3ff9c94d191e7e05aa7887e16f6267aa1b8c9b393143cdded1f34a02d2eab60a125eff7f0ab28f6ca6f5c60853aca79559d1d1886b1bb1ea7c80f7fed5f94624658530fd587061d0ebd51a2d -S = 091d2c61d369410e236653b2b1b068cab3fa6632220f72737520838b7febc00bfbec8e993c3c969d7d4825ebf03a5ef7f087926ef7316f97e57e515f9aaa76b3a7bb10e64d983e6c443906882028dfb7e5fd4558a3f24b2c3b863174b011e8587995eb425d52e95bb27f98413cf2a1f5999990df7f5d3835aa19b93fae1b1734ddfd2be99b9a5a071d062b707543b47aa650faf640afa43a51c4013e27d278557d4429584bdebfe5fbef4c9bce178a496c0124aadc24d9ee8af3e0e83ea72ea93751eb687875902c7348a212819097860041a9773d810dae6d3c9eb6049ffe38e2a09d976cfcd3dededb7f374577458b25124669a85de7465b8ece756633c1ad -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA512 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = 6cd8ccf65bb3833c81961801ec68a9735fefb8a5f7e3e63c0e47fd6b60f934216c87af801e444692aa9b8737bba4fe62cdf5b485d7bbf54a2e095684a66ff765facf06f16e6c84b2b2444cae0aa05196ace9274069bdc5579042895210ba7ca2dc58d8309452c70661386e4c21842a77c47219bdf512ddccfd9b9cbbe5024b41 -S = 0f8e07afaddf2b88cd2ccc2f720228e612ac00459aef46f9605cc609539097e60b10c6507ffd3fc27a15d348398c573bc8d385edb18fe0246af4c0ab32165f05a0b641d2e016f562397d3080d602d9c734b4d00b27f8a016f58aff098be7d09498b8e1775f0d7a3f69c383dc1abb2f177fa53ae8c5425a82a1a9ef0b428b70e48b7bd99df60ee016c4bd02f428a19225d3cba5e640d297cd28bf96a45cfa8e4e222e245b55a5528301d71e12b70246338ae0f4754b74a45fb670477aa1b1794ca1067aa1289819290ac7fa23bcea04442fd2c5ec835bb4a2d007fc2f9530995409f1e707220ed5b845feef66537889c85a89592d2df941cb61254b7d69ade808 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA512 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = 5ba7760eab59b0b7eb22f2542c627352ef1c75f931f06dfca949644e4bd79d38104078a9f91296cd52fd3ee0343f00454d5f98d2e31e156f17ab3adf671624dd77072d6b11b011676a004f5fa719d2a69f05d1a7e3a4f47afce9b8b5f346148517655dfdfa1967adbd94ed778dda329e6e76e920376b5246de6da779f651b657 -S = 8385a5fe194a10ad210c8dc069899df18ba80008a47f0f8479aa690eae5588c04401b96afa0d8bd6512b98a46d137b32b48cde633f04604f8f08f63daf4f35b836374750d08cd20d4553752d3eb5d27da8b8d12e86cb81c592d39b66ac38c04f0d5140039f165ed670b3757282816f6b607e2708e66fc699dff5e81cf2861b64a98b572a5c417056fee1335e909f3f7b9d6930f399c29a92750b486263081e6ecc2a2da06dc1883f687a9fd480f4366c3099c7fe0d56c5c7a70b5a710ba021c075b9ad46e741189bbccc4f4ac936e71121a3c62c577f8157b1919df586569e6bb52158fd0f8d08ac1114981f904b5f8b267a12e1098b2f77918ee9189dbf29b6 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA512 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = e703433ae230a79291405dfaf58386e63fb5028088dbcda5c26e8f30efbb6e7c918a272461fe5d0d43bc31a77a4f126f18ccd6b9b9b10aac7113878e03f946425403760e1f4fcba2e99c185638b020b400f8aa365e6fd35088c0a8b105aff4c719b5578184ea98586c293c90976e58bbdd82a380dddbcf9af0bd1a235ba62013 -S = 25181c5f1450e2179d3b6ee166178c674fc572507cdbb0aafca5da9b54f10a3f223670db1122140887e68b9fe8365f316981b3d611157e2d579873a2292daab5e8ec6844ec58021cd814040cefda9f7cc3bed4eb0edd3098e3d9e5546060f19df911f1f89b92e82dd7aa118623e1c707ce43a2877ad085527ccfb5d5aa2775e089e606192f785f3edcc02c59e28dc9a9eae82647e1644aaacf05c91628b1f9cc55c683ca5e349946799f456bf8f2e943a0d93966521e2c35e294ca610dd93f4d871cc80b15bf4990a0999ab392659cd81af705ef0a3d84968f85393dd6a53579c3e463ff2c08b9f68efd4a0cce43c8118fcb61fa2fc47aa9ccb6ec0453b7ba51 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003051300d060960864801650304020305000440df5bda9e56bdbe752f0af28644291a8d0fd9925f8794a485f27fdd5b3c603ebd68742e334ece1969a14dfd84e782e5ee8c8836b93aad629c63c826c84cba848defefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA512 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = 5cb7a0a74095a6f284a13d4392aac30a73a9211df0520bf2f7e9831240579fca2f7d8d24fdc8d4161306dcf8b678b13be92804598f7c7308d10c0ab3bfb1092a3adee799113498b76a500c3f64e8f8a4fa16d8012bf3354e576823daed410ff54383b7edc5007a3d5228d200e3221fac6e1ca6fc0adfd92e53a6d96f10303994 -S = 25b408187418c512e7d36eac17edc64999e94011b4d5088ab926d29e433a69e24ebac43146a1371635fc78c3d215a66ea46d0a734b1607fdb9c3848a1404545ff60582abd579d978902ed399eb5dcdfacde0ca02145480246e1a22af5ddca7080aec216895d3528a8756e0c1a2059d392f87576fe896e411ddf02bd6be81ae2a654e0a15542a6b533b776703e2057b01ad02f5430d97c691f80219e46319de527541f0bfcf0b4e1b510059fa20779eb44b1ef293b7a8318447ed25793037ddfd1877cd98514c81575613f36d946670f632779eaf629a593fe99110e781cb38101a3cbd54d7871983dbf868a00cfcb17bd330309d43b8df8d4f05eb4c43649cdf -SaltVal = 00 -Result = P - -SHAAlg = SHA512 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 290d117f97d672f3647c2b24402832b153d22a25820567688645ed95ffa6e38d116347486ab4b485c27aef4962653bb60257ef82256785a1d3d52aa0e0b94c37279dee7bb308688aaee98108de6f1373ed2c12429c9b8770756c12c03908b346b129f963bfaa38a8937190cc656f057ef1a812dd0312f51285c4f46f9241f3028ea6a61db0e9255976469f5d5542ced55ee2d6f4afe766c0a70f49871d369dd8f3a82a7141639efd4a1f4a4009821c3c2b9f5c5f5eef99a5f00fbd8bc8191a3654e8f8d8ce12d90e5ff2a4c530b76306c8c56e0549a6f277ab2af3a60cccbf4bb4b2cb47f04f211f8b86aa653bf6913f3b5ed190c51b5958e40597a2dfd30061 -Msg = 1d9589c9227a3ebe444b5fdda538adf0ae8f8fd69b30b58e3a41fb91ef229065fca3576fff758d09bcdfadd41db2904f777fd9a90f0790d4ddf30ddb90c61875d20f4edacce3c7d5ed8af51be779cfdbfb802f96774579317df17e490529a0c6254036b391ab324d5eb501590b74b2bbc1fb5b45dad1b8cda1a2168258356f80 -S = 6eaf91209e0a5f7d985231c7226732f64e2592e6be2886081f830119018ee427b3293ca3ab4156a41684824f26227401f1b10f7d993b000f3bd5d82d831bcdf772137a2982af4f1fa2b57b49833b97f448aba20458f3bd8417872f7d6b6156300d87aa87f2aee301ff53b6c367dd6907b61b6336d1ac97c4aae90e7919d94b1cb0d919a33003f05f941339f5c7de72ca94d9b65d42176deb086ec259df9e29675c087ca0d42f51be4324f8e1bff094a517083e51794dbb68aa229f7c1560945142c4e66264cf8d8fbd43dad4de21b96522f4ad7d1d121fb320204b008ccef86a22427b59b8e58d7e44fad62921b44301249fe1139ff656fedd466ffd46c27703 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443051300d060960864801650304020305000440b1601c43923bb80b35c45d083bd748d75a3fcaff22044525ab82d705d5465863cb373e069fa40c9b8e5aa4d5ff7ad45700c7a8da342bf0b16686db87fba0abaf -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -n = a911245a2cfb33d8ee375df9439f74e669c03a8d9acad25bd27acf3cd8bea7eb9dbe470155c7c72782c94861f7b573cd325639fb070e9ba6e621991aefa45106182e4d264be7068035595d7549052989b3e7fd04cabc94012c1278a0ef8672b1a51dd1a9e276816ba497dea24b4febe3dd8e977707bcd230ca6fb6f8a8bff9e6ba24fbadcd93f00126b19b396a38e6ef86d18fef945b9154c1963fb488c7025953511f86d05638bfe056493730bc6778446e59cd3c5c3acf07a0a3a64943793652f10e3292aa7a6d25a03181cc6f6ba0658d909e59ce2a02bacc9766fd8c4fbd4ed9c23a866844b8a794d49e505f9f944870a71aadbe5338039825c2dff81af3 - -p = bf96de108963b5113399b664765efe046e2dafdb70d6e5e29dc6ec89b789b059348d74d89129c7ade9ddb404c6dc3a3437c7fc9f23bc38dadc8ffd0ff757999f5c2d510b993056147ccdf421e03d0be2c74ec333a9677c430cc604f5550d0d86defdde71488e3db889c699a5cacb44dcdae2f3cca38695e783e6f6250827efb1 - -q = e1e7e33618d1b64d6862c132e4b1cd5fabad20ce62bd97bce2a3f5ad2da67bb0a7f0b9e48335a33b7b95e77ec4c47e91416881f9f7c23f9bc1918cc644335c74260e90cd7b2e0fed802f19e78c5ed80a431b38630d82f982c74a0381b8ecf943c60810fae90574e216357b2535002316d9529cb56420f3cc82dea37cb624e1e3 - -SHAAlg = SHA1 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = b756bc9af8682c9473fe98082ecb72f33f6199099baece582cc6672924e3472790a90dc330af8cd6863c7c882d4e6e726ce106ff0b6d641865b1e300bfaf067cd8f8af38c1299266efb6eaa88fe66a30191f772528649449891c1eda921539b6b5c80ac255df278bd7f44b2efd9c4f766fa455459b9a4735bf8f807e441cc81b -S = 20aad3d29d4bdf75f18d3617771723419920e688928a0c742af8b11bd2e05767afa0256c868c3538111359b7bb91dbf1b8bfc383a1573cec0bf0c62837b13fb5df21e7e07bb5d758ba8d58171d22b46147d6f7bd3b8751e97ecf13a5bc8c9b5ef7f00702c3ca400b6adacc6de96779a48881fd7c3f544f95f99ac1037f6b9f49c308aed1f6634afcbd46dd6fcecc015fccc24716cc590687fb2492c96812c9ac037f743e3b47d60420ee271331031d290fa6179178444256acb5697fbcbfbbb4fd3c6227566de99b246a8914721d5dbe58c2411df01348b63bce4e3659ae7ad09579be43acadad01ba02eb4c118b23ef64b318c7424920c5da7176ab2cdadb84 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA1 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = 196c5dfa45aa9b9d8c8f0459ae650aeb45f1b05e06a6ecda44194fbdb5b5e7ec79b0656c583d7b2c4c0488253fcf77a51586e4e8ed5d81e9a44cb9779bc0938bbb90d8d9b63278a58f2f2ad85cd453534b2a2983e32918368c2965ad529911f2e6f3006ce5ef5ab05df8329a8edc659dedc7c5576f72776803989a8560aa29c8 -S = 4bfeb7f6d376548f1ada66742eb2320689db85eaca0f75845aff7cbc91faeb1efe96ddaeabf8f9bf2b3031aff3711ebf9e4bbfd46861a8bb5107aea784a78205e067779e98be0a74458c0c850903f58dd3541636c2160a8854914798310324f852c3806f0a0e59ac6b5d3ccfd2580443d09752640e27f41b1e692b3ffec67c39868f4605230b341a2b56ac68bd2fa3450df2ebf4867ac0156be6513e03bab686f435c931532632adc177e95971bfad056424230943e5757d0c5384671592b7b0bd4a454d4d73bf312f4f46f2f310e897bb657be3165d040ff0d8bf72315ae313fda1052c37307a31c2f8d4edce4644b5bfeb5ac37fdf0e2a393692dfb72bb4ea -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003021300906052b0e03021a0500041476e8a26a34cb08f8f58253d073c53dd76a749c5fefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA1 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = c0b251836d180dbcb995b4ae6e18856be5e8bf067841b753394226efe507c7801312223eb1efa2b3b117eebe001676deb8e94cad96aa36abae6f013d5d6f18f680665514e33b164efde094cdda7b707858c38f7496ac28ebaa461b0d92e285556d78910eec45911503b84de0e48f9abf2d3e2f626090b59c95901d666baa3627 -S = 0cc0b5e4251083e72898e6d239dae55489a42675123fceb8abf34886846e5af39d109fb65d55fb019c43c3fe91b891262d8ec0aa721acd97848f455f049d6af58b5e579b92208fa48f7afcb403dd99870bb25a15b33a67b5a1ad10ccf3df04fbf5fc42a2a0dea7b6c689d18da14757b2b5ebeafc39f62b5fdbe58f44f03e148d4e5ae6ce1bdce9f316daf7722ba6622ea6eb964fc3d0d9ab54ac226a3371ef96300d9d737767cbd04963015781d14d9f0f640b1981219d391ae1d94eab184d68f1764e7dc2aa2890b08c16ac277aab85e2912975702ca0834ff7026be694f805fb2692a605635a020018342dd89b8a53f8b5fc7b5fa8b13fbd9f8b5deebbc199 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443021300906052b0e03021a05000414f40c85085852eab21192fc3cd95f0ae92a42c3cd -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA1 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = 9df2b3e0f8035d92193f0c980e8ce31aaf7218078171f907da982db246533dff2a8553ffa7d641cbc14fc4bbc1240ad8d7d07394046795b9372882a0b7524da3c03acad4719996f0e62a578ea175459c2ee5ea0c062125cbb59975f3385f7441a939a2c91ef464e8cefb4d7b75289b4efad905d84f47b4259a138f139222bbc1 -S = a82261947dd0f5b3f34197bb91401278dca36b759a7402ae65d8db6b6a12fb2bcf67e564d16030fd1b7e4e4df9bf0577c5dd5d6a5d8766009277003d0e7929675ccdfa04285e74ecfa1a937db117a130fe4662da0a869d7d34832165f86ad8c345cd6aa027036d818af45fcc8fb7bf55975c948af26ca363ff796c752afafc8e5afc5ce5208bacdaa98601046e69e648975a87ea34b011237bfe5f734d9470bfe71cd5053e2831d321fdb13e2a4221f992670782b7c584634761b7b96a28e33b69eba97ceb45aa1adffb29fd4705e4532e0fe1890d1575b5e43d4aa294c27936999b413a3086b000050330178b0f71248a0a92af444d8fcdaa0237b7952602a5 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA1 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = 3f3544b53b09a91b7f1a27d5fed879788432e604a8b6d121fcf98ba886396b657441211c0b8d47c9e1af392c4cf127851a3c689d823811055bb5c7a28c4ad16ac43b71686ba07506d8c4098bc4cccfe3fe99329f61eff73c04d614a8b040c60297eddea1428c5b59cc233ef94eb09a189a11eb122c21a84d5d241cc1da6571b7 -S = 8caf5231442d5352259da89fbf54888cd32774b7851232b21defd3ae6d780a5387ec021f0260cd299ced9fd814208d1102620cee37b2d48b5c9ad90c061f0c2a527bbd1eabd7aa76a5f4e083483eff1a9b5d62dfe57c751d9bc49991485569142c65656a67213c37907db465dc7225c7fcdd7b9a37e3d6b887b07c3dd07dfcbdde86baccbdf6fd13676e062f9f875f912058536fbd31d4dafd9c051bb79236e6e0f90db221acfae0690b6fcba1cd7716145afabd39866e393dad2ae99b24f9d97682e6c1163f5f442c4e49c7422923625b63e82fb1a3186fcf0bb81ba38d6761156b1f723c0de7fdbb0c678effc49c128e655f36ea465d41e704ad1b449294ef -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA1 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = 2726543e530ab04b06a11cbae1da53aa966dc51642d390fcfe95acbfb0ca65cb28db0f77688af52f423392d2295104594143bdbab8517c0b59ea7beb5e2fea1e86b69d77688702fb076b5543a6671722de83bc88edcfa4a651a84c539638c6af6c3c6606fc0abff77cd2cdd50124744d95b229498a58f0150e5986c0ffecdfc6 -S = 51d57b3e66fd6e271241215438be99969c40d0ea4a5b7c4918143f68f58e5cd9d52d90159e7bdc9b73ac3d3d908cdda5e402f0fd352931f9bca9dd886fed30c791efd2466dfc7c6483aa32c2865cef82a40dcf5c5bc3aad547b8e1dc9d973c8b90f529ef272a24645a6b76887925b6e19970d9f2d7d68a513f2e1638b184aa8cd20967618d06662bfe1450f03b72d19790fd1a591694043b310d982077285deafc28f95b3c6218edf59649b38e9170fb3f18483fb3788a14b161648beb4ce471c0ba4c041b87e6b38067fb934f50908b755bd126d2904b75ad7ce75a8a5d0c3540e1d9c7ad52242f2e5a5511d46ad8099f9386299f369e69e53107c6f51fb985 -SaltVal = 00 -Result = P - -SHAAlg = SHA224 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = b756bc9af8682c9473fe98082ecb72f33f6199099baece582cc6672924e3472790a90dc330af8cd6863c7c882d4e6e726ce106ff0b6d641865b1e300bfaf067cd8f8af38c1299266efb6eaa88fe66a30191f772528649449891c1eda921539b6b5c80ac255df278bd7f44b2efd9c4f766fa455459b9a4735bf8f807e441cc81b -S = 3840e121a02c4d4dead5197cabbfffd00005c9474df11252853dde2cb83ef772e2a533d7e51cf524af80d1a541994018abe93fb5835989e870ec3400f171ac786678fadd6e478ddd2d6f95719c559d737dcf2e5fa0b875827ad8558c70f6b8ab725d7344ac5197270e494ceb03b89680b8bf99ee9260cf91f0611060d7ada8d2c7eb672a2957fe4eb1d3b027c4062f2d2d840304e4a7faa243b816b10bc893b2ad48e7ada998eabd1e9fca72c0820b9b4feedc3733d20087da09c26e352fd7a4962c707a7ba9e1f66b18ea89d96d0059ebd13d177bccbf2d80a502a7362e198d7bbe1199d5587c06e1192ff539ff5276ee5ee8ffe25df0a1998e5c8ab05d3097 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA224 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = 196c5dfa45aa9b9d8c8f0459ae650aeb45f1b05e06a6ecda44194fbdb5b5e7ec79b0656c583d7b2c4c0488253fcf77a51586e4e8ed5d81e9a44cb9779bc0938bbb90d8d9b63278a58f2f2ad85cd453534b2a2983e32918368c2965ad529911f2e6f3006ce5ef5ab05df8329a8edc659dedc7c5576f72776803989a8560aa29c8 -S = 411e75af44716f884c084569a3500b74017141ec3f1c2768e0720d3df6cf221a155812756068bfdc74d998743647757d80e15752b0df1ed038ac316aa202a5eec1d0363e773a372d9f60c4d5c585f1111ed44b02c241280d2b6980b2cbb09128ce9b6ed38d50dd0ce10b73961b82996bc82a48f0d5a574910a691e55048136ce8f3668cec4cebe5c791d6b66b6c54617bc70d0d578080f22d9ed09030887bbeb5408155187a03657b55680c614e57c2e28e2c837eb7bdbec6985af6b596fcba378084d5f1a4fb80ec426966d9a9f914431811a06133c4e6df7a48577e16a8b6cc5af6873b70dbb5ef191ac9214866e73f0c99f33da2d21d313a6bb62cf03ea01 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00302d300d06096086480165030402040500041cc28faf02c47ebeac647f99f7cffeaad70df6513830d41a12b1d05b62efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA224 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = d699ca7f777828b13679a9e2ca89568233b8cf479d90462186a5ce71236ed6760053f007e807d8880418b11746c59106090f408ef1133dc1199602c16de2893054d10fe7932718eb6e24b39c0f5aff302cbdee60e5f94961eb08f516e70374841a38ae86407ef2c2bbc538dbedf1a9e9e6e961263fea73e945222dd95b7a9e5a -S = 01818ab2f8883d5b580b7d7fdd6bd15cc59f59842dd14649b27aa0aac3666562e4ee8a716d8f9a6fe19bcb5f505956457fbf200b8f0121a070788a546b86f8149f0aa98f2c6439412ed4a00114259b348d1f9e583eaa54fbc384c52c518159e460582051afee2d4163350bdba58112bf0fd9ada18346891ac14888765a68d3475f8f8f92ac9e5f4b02480859f239405d8fd14a05ef95fe9b726affaef8c8d54e6cc3a01a1399b2c2b2eba18b7e3dd7ee337c0f108dd53c460112a58f7e6b09db540ebb72fe8e3d1afa5224705f0159aed4d94d4ec0711e58873682199c90e9aa0046f81c3faa3fb21a0a05991f0752ec7e1c04d9009fcdf69d68098f9eaaea6d -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff44302d300d06096086480165030402040500041cd8a970b5e7e41f37017b8160a04e42a8bcf502522a1ffaa739d6cee0 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA224 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = b1d87e6e67cf95799888c51383d6e6cb4fd8eecb4d2959ac7e58ce8f5598ff69bdb8d19e5e55bdd21c4e75fbe178cbbb9d93cfee8b7d387fb5a6067fbac46578cfc8d3fe04108588c9de077eb009249374f205553bba9d0218b2449ed413a142eef0ceb7e068b744a420c3c377f1b7faddddd729e5484ee0ae64cf132aee7d70 -S = 3dfbf8cf23053223500b1cc0a4e43e7754f3490f33648064bb9a806d17b8412075997148a76a152e7becbcc26783fb0519df481711648b35ead7fccb9937baf37e4b86133c15ec2ba0311ed6cbfb742daccd68bbe8f1b49766366da644302a04ec1952db9fb8e50641e3b0cf9c04066f5d49cff593581beedda78e50615c5f42f31444462f59e1e3a8331c1494867361073e5ebb8d6ecbc5b356454a4d24d87ff4dae556442384aeb0cbfadb3437074a76969b8f213a4e8a0a0538114888c95436582ecdae288c4f142612e5ca9e273da165cade52674f7668dd170cde6d7f8e6c02cd1cb013c87ab4a5c71f9f04c20a0fee617968f4862a101726368a96f3ef -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA224 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = 51a9457af4abc1b75f3bdd4a383b7ad79f1bdcea045b15953b4bc15ad216f44aa2fe716fa4e91d68061db3537e48b8f0dfc3b202ea1795f966c17ecf7332a3301b1a8add2ae67a523f8730a72476d2b45bf52978f9970abcb80215f347f4a365e484f98c2dabc2be3302bc0dd1cdb16c3c39a913dae25e245898f08ef763da31 -S = 9c7b10642d88022ee6cd2816c95178a5b163ab887a3b663c0236228b72a6a92eb18d3a0fae84526f1e17442a2dbb199402693f166d31d30105b7929046db4b1812cea8d7a1c5d5d53f785130cae9816b8254de0aaaeecac2992a1df4796dd423641d685e65478850a59436aff0f0ce36f1d3111719255dd376d8315905f4b3db7439ff2b0fda6226ba64df947dec832db48905a3f2d0d9a2b46f92d91794ab98734e0a7acfa0b60216f728a0a4f6c3e188978cf745e620cb3a0fa836c1a548e1b1bd2c03926473ef6b145d6fd99eb5d512632334a2588fd7b2640e0d893e6fff31350a467543ec4a18f51853bd4566674bbc2867a18de04953b1cca246a558d7 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA224 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = ad32c2e66fa67fa97cbbc8736e36a04dfa8aff5f734c75098fe711306e9181d6d87e7aeec7535b6e25dd0da5d6032dcff9f96de76bb737bc8daa944748a94d3c4e2a50dfa2b654195a9ac0cba4e0c962077ddbacebcc3bea5c3bea260b45ccc695a0096208b7b4d3a45aab8cdeb4be2eab7e1356fa73c8b98204db74bf4c479d -S = 1c0ee89d483230cfe29503591c7d002e1930128999e06dab41d60e55ed7fb191b068b2b7c606e0b684dfbcd7b43045f10cffd72e96fdb10af7062d1e3af334b2db7d79f3ca478ba4d21f4e2d9aad635c47c15d26eb86643ff15d5366074d009bb4e213902f8c4ed53f5f3c2e1ae0771f0441f68257aa9705a4044d6846103c75f83c96f3d23a450681394e0f6f816fdc5545d96321e90a4c0a90899eac77751933f502c4b6fe72177ac1e9d3f3a67b9db66b96b78361ea7c47317b742d6f6a941a55c496cf7fcdd73ffa79274898081490049612f580a8d1e7edc95c10902dfc0826be1066e489912bbdfa2c8d6142ce9e1d3dbd8c9a9b9400f39579589f003f -SaltVal = 00 -Result = P - -SHAAlg = SHA256 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = 585e2aa15bbe0f218e5119f95a252b57ce65d9474d35c1c284de1ee79f2b9a88bd1364e8a19783c3aaee6a8f05e0cc022170b1d463bdcac61c2a01e3b8bd550638c5e59ce2c04aab367b2a14257b0a157e9c6411a9f8fa94970a6992f91401efb0bdd44485ff0de11b40840e21bf8f97cc321a8785aefa33dfc67e7acbf7474c -S = 2e02460ece0246277d4517b9c00d40ee669251ce1be2d8c13bcb67b7e90635d6a68f8cf7373bb5962ff1d182f3fe706ae3e216446527cafe5e763432141f92995002f6c6c208e85ca3203de5d6602db70c2302c804abcb7b3a22edbc120a3b59b1febfc485bd787ff0053cba05d27800ab41bb431d9b7d7ccf0f1a5f52eda8432fc70d1bbc5fc766b08280124df71d7432542d5caee7d88db6654510ee81c3cd23b1501679a2fc2b050acfaf9218d7c6d4b260f9e8b986e9dd9c158820379609f11626d6b35eda024aa545286e884b6e135ac3e18d52c9be687004f0a81fabcef972cd2e82d954a43ace6f1971d7311ba9f267b262303cb51121fde66e073e10 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443031300d0609608648016503040201050004206510c46f56c48ac0b28992c5bd0fe4047d3baf1fc7e528f67b15f3b9188af1a1 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA256 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = 790ba59678e1eca8ce7e7723488b181ff1fccb3e339df4df3eede794ae30add767c006f8c4a4aa5af263d4df961a01a1b6cdf5e3d6fb004761757f414b70a5cbf5d87c5a51e7261146f7693556946be27ed6b9fc5ded8e6799fe537b7f2e62b2e9fc0fa465d3e93693df3d0ecf21dc4a10be1e71109d27a9ae30692b90926af5 -S = 91a2efacfa4e8642b683ff7c17b08743f8bd03950a35ba44372ef1814fbdec087c033d6eceeee431efdc6a3fac97f85b8248a92b601dc4ea9e02a23fb921655f084a4035b42c0e491ddee05c4d3d4024b6446caf77e917d28453640c0af50d937b5d74b535acbb3ef9b2dc87bd3cfc80f24d2aa9b1feeae7b549c197cca6888fdb617c8a5a1c91a23c6299cdd1b7d292b0227634bdfd415cb6f12723fca2edcfd1176a485b2a2cea075765785077c84de1c50da27daf89407becac9fd9664f2547c5a9f66c9ae3c14ce318317c58d4c3d3b07f07d2f8a58fc10b854b583a628054cdcb9f7729e5707d151a4ba82b1d99f339d4f8a0674f260a8a6b8665169fa0 -SaltVal = 00 -Result = P - -SHAAlg = SHA256 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = 4cec86b6da42bda1aa66d9f6ee0ec6c30f4f575ca2bcdca198d2f67fb494aaba4372b5e9076f1fc2748313971f3eee2173af967da5840d74eb7246ffe9d8370a6c9f2f795b646a69ebd9e3b8116869c73d1af57e45b83b919f307f02d439aae8313a9d6ec068c51e772fef60aed45e3dd7581b69699f8d811dd249915d012bd9 -S = 89a014c41636b64663cf381dcc399355e2974e1db624e36d5fda7d3967417a3810910948813ea58caab8f7cf2dec7309d26d5cf7db0dd60a0ff42982b91f64f17cae9195f2955395e9ddc7335c441de9b65a0e252f98db17a805ffd0d0b9a68dd6be098107f1a6f7cd1292b2d6a9c23cd631c62709b72eecfb9fcaca2a3ff036984bafa785722c3fdc8398479ab77a3e1678c7af85f75f7a2f4f54a13ecddbbd4aeec7a96445c885d12aaf236a9c4058e3e669335f5fde34d6905bed45cd741d9a08f8501706d03c7f98b2c7214eecbf4759d661a32eb9c302a9c0057ab734b46dc3575ab42951298b59d3d8429339fb58bf035173a84dea90cc6354dbf68d31 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA256 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = 13f936517eac73d6776695c1ff3051850e32fab734cc46c280e355dca079ef3949810e7edaf19c783c187d0e0c32d074fc3a72a276ffc405837aaf74ec5fe5659ff26961531c51b56fbecb6b28455e78ea7f7237faad131659d9f290eb69ac5bd8f54fe233561bf5daff85bf9d9182f9a2a9015e07fcb95fcaa72617e6c0ce81 -S = 2eed7fbbf583693f63e22bf78eb4d389064c21c37b66667c1b1994934bf9ace14c30279253e9195d176535e28aced6719292b064f2cf99124d55b347a14c960af52e912afb53356168d1f19727d19b65c5090c4db0e4fa9ea0ee3d3f28ce0a956f7011765bb5e58a14b8854e58e04723bc73de96278c78efbed70ebc8052d3359ba967dc91b1f982932baf770d2d2f252f37d274b9131e8c5d4607b67115bb18200a2ead70c6882ff721284d0d0876ee85e68dbefd4e3a9d5d898aa9ee6d2195c822fa02d74ec85d7a93d9688fdc5fc0c93d9c7df6c1519ce1384174e2aa5fcca3bf92e260274f2e0430ba4f008928d6ece05f0ac5a26683ce956fb7ed43f7b5 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA256 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = c81e98ab21239d9d887553bca6ecbc55a1e4593036f8e670080d44ba3793b79935075121d5bcaed3a5dce2c17ea9b0f35909fd08644283205602cafaffa2545a23ab18ae889a33f04ee0d9ce7f2d9109e7eea21b2615c81c03182ce6033c93783b13d698624392bd2a8a202bd0ffc860f29b31afa2f71c2bb85752c66ce8dbba -S = 36403d0116aa5bad635f855b1aba7ccbe7787bac4d2d0678fad33163c6a19e88fa53acd13646466ba5e11668752f52ffa3333c59d9e00bdb9cbbb9e549a47c700b1d8be5e1a778056bbb0f4d0a3266cf5b78b2c8a224f460a20b31963105236decdb49f4bd3adad75b6ef5331cf0d54c91fc0337a5ea3d1dc94e6182b11d7eb6690096242d84c174a0c01869c81b193156a730ed08acb516da3a2b1646da3fc8742191e3620d813fab2f4288768388b5c2892ebe6a42b7047401437b625b7d87368991020aa1f4831088343c51af5217334f852c49b474fdee6676cbf8d78018061bf3c398a75a73503e868468136afc187ec1deec0e2a852b454befc60d9873 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA256 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = 796a46d728d7d9d6418710970f311d92f5362862f71df0d47b3fb63e51c35712f2cdb8b205f3668628f17e4dec9dcbb0211d2f1d555744d297a9423881da2473755106372685d2dd5ab51bb6efd9499f1cd8f7d5fafb990b43a262ba593665b98a5efa0d92766302613daf7b1fcddf866ed14833eff238a70792dc6ce3bd610b -S = 94c00c47cfb2eabed6ce3b04f88e797b1b2eaea162dac2e51fcfc8b9f9242c0f48f664f0b65ad4305867758811fd1cebc244f026684835b451e97e6806ad2427700f2d9c12f681b2d601fb6ead7953209a0c47db678ce0075f34705e4b1cc414f74574b4028bce76a69e160ae8180710b31d42950b66f70c6c28b15dbe38915e8c36d7df03ff5494a1265041a801c5916ff73e08bceb792c536608262d60ec34f4d3ffedd74127e9d5b237af1d300ec58bd4475f05c568978860804818fecea2781c96752821cf22164b1b917f3032c58cd47996e3ff5284004723d0c27a3d6439da0cfb725b991601a801c89a77f2ba174e3980d7d3f1b342c4b6cd16121656 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003031300d060960864801650304020105000420e6689fb887124d3316d9609e412b959be86b7b02a1be76f300ebcfc82701a77cefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA384 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = ac481c957d422abb5ce8a73366bba51b4b718d83ed3c59d22a4f0464f59f3f78ace6664aa5eeb27c0b0cb0bae8eaf29e828a04d1eb88a174d4a027bea26f49e6c47e0443437cd4b29acb2738c93f12e8a5224307727b376fb38fad3141a95a7e9b17dec87d75f724b42ef4f3303f6dc15b3e326da99b818a70277c06fbd2d909 -S = 3da89b974fb03b26a5617a391b68413d62d03b7cf27daa0024e7b0085c1f542bd82adc66102c16c57c7765b1bee5ceae98ed54fd5fbddc1dc37a3a75f5695c49dc6f026213f79cbab37093a9549465370b7663f363a232c81ecb71074166bdaed7a558c5bdab0a20aa7f5c1eff0258eea42374ac3d4b386586fda7913305a602c33b6ef6dca0718fc330530e65f44d8824b4d1e137bcd3aaa9fbf0e4079cbb02a541971ce5a25d8aa91918576bdfb774ba70848db5b78331c71c26c0682b812d03197970e481689c39c56bf1bfb2d7f4c0d5c8bbbf5b3b6537f48572d5f79788362a0a7172f20308cbdc64f0dd9d0416bf09c608e915c070f4bb444e3b7ea492 -SaltVal = 00 -Result = P - -SHAAlg = SHA384 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = 8603abf63e1dc6a957770c225394c0223874b3ccf069c315ee26a2761519d9e3d5fb0c0197a57f945b25d9369f11284f831b26412ce6bbe36618c2318db11042ad9bb27ae881770018e5af72b66d31d8fb7ea3d7440cf528bbb12f4834fc6d70550b27c7fa5cb6d7d7e0143d6051e4a5e5c6b2f602857bca36187021d2a3f756 -S = 27d202a060e759b168e451c6bda8a290ce96aa70eaad61e65a37962a766b851ad506cd68755341f4ce2858c24c27953fc8f85788fe77f90d17e7427f6e487ee4e41bf64773c79fc1472e89ef66f6cd532a1f485adb2cc3952a15e5b93eac7cb2585f03206733a142b8ba9465653e02843eb5c70ce8d7b59fb3b8cc2ae8d0405a714fd55638aca05b0bb3b5dca25dc7230eecac2c8fac049a0891e1b986308814486dc9d076b780b30f1c2a9b8292d2e3c56ab2980c3b3cf87292a300924c30bf2633f272deb8ada1149d3e347f930cb5a4c7db035352915b031f524ff07889e1abd54ab5ce572c63d0ed3ecbb522e7a4d087763cbb712eb44ff81ced4a9ccc3e -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA384 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = 44935b571d8e202a7c257defda42c57a4cf3deeefa104f7fd31e9b7c7f73ce8c959b55380ffb12a9fbb4b0b373ca3413ce86d5f518180ebac081f1f791b0bec1e3ebb42813712701305ed3e9f7ce7086024587103c4f831098630b68030d8f94974d212f113a87b985ea8e975096a15b4ffa99464efbd70bc38c90d6bdd2698d -S = 64cfae08fc369c5dac6c08609300ad79ecc260f52cd9ab810d536f776aeb9158e8745474c76ee9119ad1d3780f0175bb48e239998e0580272417f9129fc778f5679d277102551387e23ea1b0602b6617bd323deffb2c894e24d6ff5de645efc49e9165a8cb3752dc59f81e0e205eda79da7dd64baa300743919969a1a3313c2e5b211d9bb3627cf6cca4f406481b95bceca64c733ba51a04bba15c7977bfab4a776009b82d152279bca00699c91d9bff0e1f78e3a81e52e2367c982a421cdddd7dacf0b888c36d7b9ffb3254f8140fb6aca60138f196b1c65690b40476a371ac2f62899d253e730d60bf62559fd4aa3196098a0ad53c98eed2a0476a4b51f264 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003041300d060960864801650304020205000430bbbab81643e08d7a9d84d488c6845a98389c05737c2c54103cbb497d3291a181a2ab6b4e5c376b90bae7af4405e178ddefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA384 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = 69ec7262fa272d2512fe9281a0aeb2ceeb77a0692fad31618b0cff731a4cb43961f5859ee975fc952c6ffb0bb657fe19843ca07fb0e4614e501ea6e49b54011d4d60b3c84da06f588d4d61dc32086f32f6b6bf77ca8e79c1bf70ce1126793983f6d404c86fd30fd6fd3ecdde5feb8f7f088e0539c6d30124a1aa7fe206e2e3d2 -S = 3ea196268020d94c900f39ee2eca7e735e0cb478de58836b575628ef46c5e78898c2d76c7627fe36baf3eedf4d89c2572aa3afa8cb8c5ee3433e4c2ab7abe8369047d21cdcb00e1467ccd60cd2bbddbbccff5a7e0f1ed9d2d5fc4fb587d41ac538e66d9b559793e0fa8e44ea72e9c603d236f1c82c4ccf665a5337fb797b001ac0f4acfd90e54d147cb196f4169dfa0f72744bad275a748f4b402bb2cb2ca9adefb057a6400855483bb12c8e51909a7241f413ce7d84f42f8e4032acbb4a97848a0f2a3c473af3f6e218100b4d446616d55d55571c0fa9e178f502370008317456318115f8276aa1e569cf364efd5c7de9734eaa575802b0db421de6309c175f -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA384 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = ab5e706303ef34f4f855722eb521454bd886ea281c677ff935b40b3cfcf7bfebcc2a7cf62ccc95f0ae34d5081724c43cbfa126c93b02c5e63a4870b1adad446a2b802adf932fa127f3a6be93a8d770e2c79a09b4bcb8fa423142de4b3228bb528e0684068041e2028e5333b6b263d4a5b8199bd2e7b0a874e34d5ef1d28fac0a -S = 94c98efaf358dc0ac76b26f7f52b6a9c35bd8b63f9517a5b679af3cf3c48fc4ec99e5c75e7b1ef27a4dcd5443f6f4286d798cd96f746c63c290e501938196421d691faf84a5009e410545c407d920b14174e66da700b457b8a8e2e59c094e33ab1f0b3a5a954cf814da7587c95681d990ef86c4f67ef97f2ebfefa600c190a49ac88cf1c6bcc8423781117fc1686da1ed0032baa42d00fa62c38f5d3d27c355eca2f4b79b57b54b7f97c43df57b546f2391f5328ad295a16b1fb6d5eab36dcded973a7f34a0c600bf8008b96b70a3e8ce0d706d16dc2c1f298978c95d4823e406f433a48c6c98e41341704abb7860120db033591eab0674e1b2f998e58926111 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443041300d0609608648016503040202050004306234baf47b7e2a2b38f44db0a1103dcea4fe9e2f3c6b951228d1b7bad3672f8bf772a915bc9bfc52d1e5c51165c50adc -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA384 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = d2c5b7edd8611a62e537db9331f5023e16d6ec150cc6e706d7c7fcbfff930c7281831fd5c4aff86ece57ed0db882f59a5fe403105d0592ca38a081fed84922873f538ee774f13b8cc09bd0521db4374aec69f4bae6dcb66455822c0b84c91a3474ffac2ad06f0a4423cd2c6a49d4f0d6242d6a1890937b5d9835a5f0ea5b1d01 -S = a524f38bc8b2104d55275efdcd8f1bf9d529d9565a757df8b3f8bfa067d5278721006eba463365945b81ab4a504122021f8234051847938ab3eca24f95e4aded34f9e57a7b377aa16fd9379d0b703accee4aa78a015d0986e20c4fdc950a579494c56eaef8b812e2bb0182b74da9f1c0e1e3b56142481d18e64fa797293fdbf7d8d54c44524fe6b957a06ccd292edf0e0353b96e047813662a7326c42c8bcd1d231c6a486699b756fd1c301b1891da6d51a3e5722cfa46592798e91d8df31cd98a3dd0b725391a4f9c6fa1ba312471f8d1d85519f8df7ba66244c5dc679a1348d2d415b8aa22b02a9322fd2469f9da475a8d832862e6a0cf24eee957eafc488d -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA512 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = 302093a4a99ea31b8a693aac1743663b725aea8e19c1e35fb01dabb001a1fe5f413c5bfa9410add4d4272b598e617d9e4eb1203d1d890b5f4793931a62a28cfe8be8b1eaf36946249baffba95bc014c2294dc7d8982ce5899f09bdfc9c583e71988d5b1ccd90b433656b7246854672cf8a96a70a9391b9063fe5f2fcb8a95be1 -S = 2efe346135008623c56353482a684924e55455e5e75746707de371b9b14ffbaaf5b5f2ed85bd7e28ce4e1700af5014bbd315c32b872d567ea214af56e8c3276cebdb0f597a6bf2b0758ae2e5d1e2e9334a53f838c668bc9a1503010bc5cb97f6215847802827ce9f88cee4233cc80a1afca84cfcf7368e4518e157f05447586cfdb3ad9b2d79bba5a6c4f7494375472fb9075d61ff42c7816e23550f1643b758fa26f4377dff2034f5e68c5889665341d482bd4175a286022f8346ca925e925f574cc961146c4e2c3e8ba12e083a0ad31394357d099c973a9ccdd4a7a6649085fc1d4a377911be767bc9f96df50f991a9a589c5d5d19c3b3e8fcf7127b7e32ad -SaltVal = 00 -Result = P - -SHAAlg = SHA512 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = 634de10919c2ebf47f5520cccd2aa37f484201b015fdab5c4ddeaabd548f8e6e6625a7d172a478ae2cc6691c5ef8bca57ea6c2a586b84ff3005d6bc360074acb97b77fa5e57a6c75ef33fdcb119c96cbf588498b656b4dbc5d1bab8d65d83bcc1d8bcf4e1a4bae92f02544a1901d1738d570fd29591c8dff8da2d3e1090b48b9 -S = 8e11eaac64a60172d6bde00aff7d654c61661c4e3213bd64b6141294b3d2491bfba0040ba09eb060a14a9c754b1b3dc74dd5e6de8185eb1cb71eae7464b1511d0b302864b34c08b041528807301c01b33a4630c74b1e6fe829518962c380de8b9094f4f90178313a7d2229a0fec1a798056b871a25778813cd70b35e713cc83816549f11717e3dd4a1412251c1082df1c03c0def3ddfdf3d7cf1b7654e5af94866392ad32330f45b7e9491a4d1cc2ad64a3b7ebaac075cb26d5115bf9a846dbc29faa8302a5f6337fa2ba07f9987ce1bc729e67fe2e8172bd44cc79ea15ced0cb49039ebc4749713343f136b7c32f5760d403568a4a6bee7fd697b82d9d44983 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA512 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = e532de1004ff3af1c5cfd5459c14e3c07acef7fd9f0d731fb0b143b90975cbeb542c1dce5a4a70121aa5cee6187d0c18f8baff7e4b76ed94a9bb4266008e84b12b2c8945c793e8ad4244ad123448515df371e99c62e29da709d15c036b8cce0693ba8a3cf1e48a0a6434db91987c99d592791b1f895a6ba0f87cf956f1789034 -S = 522fbeb9dda25bc573f9112a9f91c17edc93e2768e3500b4e2a4686c9548624900f28c878fa71336798cbe95dad6c3905ac04e4709defb972c13b6a532b0f827b86a8c809699ebcce39f38d71612ecfbd030d320d709edf5a0b7ac3f3ea49ccf8429066a679d4a9f42cf2e21bfb2616918fd80fbb7507bd301a6c650efa802cd4b139f02f65408090dde62bd825e04afc720ff8850461d5f1444bc49ef8f6f4f06e7aae64bc0f9ef3beba8298603aad62547ab8e94374cc45f7165e08c612408fe29ec242b2db649475dc2b76debb660433a2d2af7c4f82fac4b858f0b715e1048933d54bf2830f6373e6aa1ec2f460889c33b3ff78a2344f33929dac1c728b0 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003051300d060960864801650304020305000440ed1dda6011a1309b31409ff9a5f57605f8a6d33d91249b0c1e37bdeb6a580d334c89f5332a598379bb1f37127bc39366b275962c3bb9b888d6d576fe89f6ed37efefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA512 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = fcd993a231000dacf06ffd5d90ad238d5f67c86a9f61ea10ceb2995a2b31a1f7752b69c0f6571b48c00b05b537af40cfcf738f57173d899af7e5fb4635a5887b3ecb922524b15e8ae3ef721fe8cf42a0d4020c5f7d9101dd3516a597502b7822e023d67ac3f81c98e0850c42adf57327f57c082bd845980013ab60f681abbb14 -S = a05058b41fa7d48c6be9420c6372d559d466a85e174c272f7394cf3896e1b945ab8941462cde4042d1da2a8b4ef11b5de2c720595855190bd113d566d420b31d51cc87365a2b8d7be99e2ca792b94ecc5364cf63be7a16aaed3a723754d7491480829c0cc9fdc1791998f30ef80291aa756fcab57ff5f3e7fa2d6ab001c52e76efc8dc18f5d5fa2cc762ff863e9d6d1fd921376a8f20d4dfa61f0a4c389e42db2adb07d168d438d1ecaf8e4d62006a29d944b1b5e5172d99579bf03addced9aad16038997d2721f365629cc5b065f656bd306cd76a01cba35c806a476f47c7f9b50d211b90d882201bebac5204fcff51a28d7b95c12eafde637bc50a10a0312a -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA512 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = 55268a860d34f9ac8071c4048c4d6b9e5475b9a89da448e178bc475122157b3828158444ce016206b21237a7adcc4ed7fa8b5d079a5f07d8f619a5d3c7a6465a339cf4de38133a534eb6e3e1481a03dd7c4e3cf723b33ab5030d80204bdb67bdbee463be1313897a9c844e1b27df929622e5dde10248e860e5c05fa0755be547 -S = 7150a5c72d046e51f58b5d2bc60886be8b5d95edd49ee011986915138b53dc6f1c20913513418fb9a5edfcf4a3a9e4c6302c5bff2227c81d447334c3faeafda5ab5ccf2f25da8217cb3acfc8778c22bcd1559180260a8d9a3df3b2e1c7f1696bde815b4ada1e44b50b500a0aa4b880ba68176aeefcf96db028383b124f5bc7b587c6c6a726e2af4cad35b85d25fc158fc44d34a5bba69fded3b37af8cab2c53233a6e363e153966e10d6c7606a23a51b9358bb964f49ea3f19af1c038c5a1dba87b68b5802fc75f8c68a5486479391e54e743ffb64c185286140db15fdaf51aa2c6173fcb3d60f736a460623dc351f035d546f75fa07aa496f65bd8e4a66913e -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA512 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 3babb27a2dfe4e88cc8c030cae74839c9dcb5ff5be29776bb3b2dfbb1f52596237ac9188002864684c470a7cee03ce84a85aab0d4dc8eba4513908dc549458d4f979c0e057063e879a5bc6a1dd8959f45d9d2c1fcf156169d351d038cd0246990d19954b04a24bcba380e52a38b2cbb9d5b9db1af3ac0df31a458bdf4a9e1bf6812b9c2469a8e384a96d1ba29bf009b8bd0bcb098f55523ff8e220ff2aadb50cfcc2eb927e9357b51c5001123a46016c47bb7a8ade6c62b5cae190a3c89b7993d130e279f0571643f039940c5e0e6c212f39bc20d014217ee8065090eb249237873bb3d05a2ce846d58134a4ef435eed617e4435e044471f86686db1572d6531 -Msg = 587e0c53dc96138e7a0d05f8bb10e6d7d8cac64a87e538e7154e06a2b53923f01866e12d3da2643b8b90576d1da9dda35d82cbb6d44d141640a385b1e781b2172c9030dc60a9043eda985c084a207db74a40fdda36b532bf3ec0ea4bb9295c2abc845f29ecb3dadf90ac7c93eb7dad5ac88dc48056247a29362d9e38d33b0b70 -S = 40f0315cfa6e8180e68c9f409917bf35f6feee875faaca6f63d41caf57ba81f1994e4781bea5476f58feae8681229546e0b0ad4f6965e08b8c4b5915a7ae72430c18e556c9ccabf9b2adc9f4a188bed3b70982ff3561290e90cee779fe0c0a98da503f700815b9720126b1c6764103df4e05aeb81adcd11792e38ff4f072b5f403e458459e2e40e453bafe96773c489a3b55ce8f3a2dac7b5fcfbcbae53d6b27fa9acce6c3d9da72c355e11e8f56290f75fb53bd41bd0fb822662d218c6e6b8148c5a058bc2a8855e00d7d432db7ec3207be1f106cd1497a55c46607989fc295426b2f06bd7bc4da7ed40604efff01f037450abc3a1e0a657793e782f8a2389d -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443051300d060960864801650304020305000440f7868e28e7d36a3691e196c831ce747400ae162cc2850af22ee47105eda53fe7b8826b1599e66035a13e247406b04b27b4336859fa666279991b18ae997466c0 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -n = 93397894e668653afab24bf55c15071960a81157e680444891c42ac0cebf9ff99e3739e12d0223d62ea048e77ee284582a707050fd11258f27fb6a4e2b583ab37ed0799708e3379e41b191092b2f4631c974dfe81993c740f21bbd0d828ad398893aa33101f445e5ff02ca498b8a851100e8d50aa2fe4c88ee38be966222657f943f9bed73f018a4fd371d208c362cb2aa4d1cec9c68f8416ef00ded34f4a1ee4d59a8ff4c5b3deb33c504542dfbd772ac649c8313644a32205a602cb5581819e4f4a2b8150e63e20669690429a4b5cc77577295183ff6b760a1b5fb989f158107860751c7808c54c1c511d3057b5e9537e009576b723dc9073c0b03f28955e7 - -p = cd819c9501262da3cf149709f0f56e59c2783263e399819dff248ac9e674c5d1e281e2f6471aff294b6e1db918d1d52f20bd4777b1175440c9b40da42b1c6a0cb28e404ee6446d19cdf7559304a693400d94e826eb90772fec7835cec7009be5e6b09ee7052d0b8ed413eec628d4ba9ea2dba3e53fb6fb7491eb3ce3bb16e88d - -q = b765ec141594c3a8503df7bd3e31264a88bf76ada5d529ef0969724a991787e8630cf8ee8c223fb9894c98679235139a5424e778e72309f7ff60fd5766d3edf0aa21f82d13c1ccd9d75d7799917b7abaf05c1f2dac240dd0bf3c1af0d1f5600bf46e93da91bb36a7031436e305b427af5a090b484a2c0a397d89f92c5d9c9d43 - -SHAAlg = SHA1 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = 16ae604b3a4e9c7f1d616e2deab96b6207705b9a8f87468503cdd20a3c02cc8da43d046da68b5ed163d926a5a714a4df1b8ef007bca408f68b9e20de86d6398ad81df5e74d5aaac40874b5d6787211ff88e128cf1676e84ca7f51aee5951efee1915dcc11502a8df74fac4c8451dda49b631a8fb87470f0ebe9b67449bbd1640 -S = 3a0751f873595e6c75cfe668304ce23e37da8f2412bef538256db7333562cd7b7457506912e176b8af543d5e01eb9742c8a42d356453a9d2ea9b78d6774144e3237e8fb3c0822c16a5550cc8dfb52af497df73d30643b4a8abe07c8e04cb165909e030faffa2429089ab6ca3d88584a0669e4955334ad5c7d41bc5efcb901f7cafe0e31552da57833d595fcf955247545cd057781d58f27c9c1a835f19f40deed90628de42de3b3efa4ad1a7311e67ee3354f6234e7aace3d39751a84611ff53d3ba70a552a78c74094c84cd401eab240aa33bf9c1492d1e173750f7505966ce83fcaae886102cd139f827386ff3898e7a1fcdde095cd96165a11b47ad5a43ca -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443021300906052b0e03021a050004140010617ed97007b337d2736ef686b8bc4f438f2c -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA1 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = b3d09ef22d893ef3cc09eaa9b2777e982a84341ceaa00d45956f73e484761ce6c61b31e165ccb0edeb7e0fb5255922ce27b13e4790399f8110730740276ba8032fa544919c5493d583cce5eb593a087bfe936c46f9ca85fe0646715bce93db6bf5581f2a5989ae5299ddb574d583f948b5110542adbd88657fcff95c01567cc7 -S = 859c4b66e9843f82baf341875b80215e16acedea013b10511a993b8407d72bd5dd00589d4016dde5b082f8cb0fee5f339d3e4167ba2399269e215afca6ec2c1ec3d572e214f9513086d281a4ccb5890d75bab00eb4bccc44074de6fef0e8c21237f7630557374da6779889016709aec7fe8c2999d14cfdd9a617bf858c941674737cf0723f146759e4aa691f4bad8af3296027f92fbb81476587f76759592cdc389a34d06d2bdab0bc87742e0013a11b571b58cc4990828d374268995b34d7eb8c09928efe0204cc349c83f575ff70ff3d4ffc9026561ce0601f17c8cdc945a59b44d8323a8c3dcded6158e880c7e1a214c2d3554e814a0b9c64f35724261452 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003021300906052b0e03021a0500041486b684bc197e2f935d2cbe5ddcc6f94830a4ce21efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA1 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = f41491a2448f0abab25b9f4958b6eb93343282e62dae1d2e5485f7c369057685a1230e2ba66c63d8e03fadeff33a612989f20ee551e784bf48b73c633791f4a47ced9ac80e7a6b26bc585cf4b588b95a4da10ccafec44094add106b52fdb78f00cdafc2183a06ccdce0f74fda7883b4d0aa645403d2d98d60e3d1d615ccc4a94 -S = 81007a0eaaab1b6205fb5579a55d50a7d7b4bb077eb0cdad18756b4bddc447cc6f1a427cfa32100cf5c0c00db6d28c371059e6341d947d843722ae8fcd0c81a4650fb96857ca5d09a270cbec62a2fcbf997b67fbae0763a5cc28f526c452b416f25fdca7bbaa82c966e7be2a5b0866da58b05e024439f15428b0815117efb9c08310e193e7e7a5f2371f7c2c2edd17616a7fb991c2e173b7fd80ae4537d38ed647c32dd16129e56600d32418575c608f360368b750faac157a3a43ff665a5ed5c545e07f413e9475e7d79d542356358f0c554cc206c3880406447308d1e0d1871d90a84ee4a43152488acbbeb7bf55fadaf3e8b32e01a363ca8e3935efda1e43 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA1 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = 7cf8f94a517da2e5f856e8ddec29ab25a1a3b1faaf0eeb193326f92e7228ef8fc02d5a2aa1b67ebd2d88e245b9ba0fb8b30c94f6ce7a4dfd5f11e55d07029aed93f540bb209f8949839783f6e86562bab8dc8016c1aba24b912e7dcb228a79edbdf8b4e418614af2c22cd4d9c0542e9379bd7e42cfc8716a8f25c85e0be814f8 -S = 636d180a954780e947e916eabfcd4cfce80dc0cba1cae58342e142207fee42f3f6655ffb6c78f89fe1d2f31ed54e991d14b814583e8c84723263a22734acadfb5bf00dcd6df8bda4ebb3927a36b13bca2991094f1f92610dcaf953b33a4d1cf571085e297e3cca697e4aec953ab2134e23e62d176ade623e3e2efa562e7e0a87fb7ddc3a169325cd01fee10b2f6ed2012b9c9db99089521d2d15a15da86fcb165501eaf454bb36c8798e0476f59bf2a7d5eb395228744e266198032de0afe58cb10f81dadf57dfad47f764721e54f1248c00f98d7fd2fbbc5aa0998b8a480a73df7c2eff9940bbf644cc821ffa9bf570f2b24c43570b81c103cb4d0c39deb507 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA1 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = 7ff7ba5d5e8aa7de3ffc560672a9c1b0f2eee1c39a8d7fb89553475617f81ec04a46b5b28c7d5e08d7f71f80800805c02528bb9be1545b90c1b184937c73ad115efdb92e8649cb51518b5be216118a52146eb25ca8d7428bc4cdc9fd9cfd5066a264ed57b5b695c1950132b59b8df56da708ee9059dfdab284ef3c1adf5dafc9 -S = 55fd6153dfbdd9850218c3b48a4f5e74e9aea999b7e0bf0514481f29b9491d62a4a4dbae2fbaea27cd4dea5ddfc17052d3598bc329eb3ec437d1001387510d7d0288cfe298cc5fd9f7b91c887d41d81d6685853285d67e874467c036d52be31ee49bfcaaee129a3cda168b59ffe523ef64f7e972cbda2afedf1a0fe7c6d457d79d9a73b7424fe6ec4290988dd81daa58e1fed69ddec52f8482a27da34b70114cd07f04591c5d2a38eefba0abd33d4c1f500a4073eafc5199548d7b96c772cac71cc02e18fa998f143132bcfa5e44f2dd62692c90e9a96b243ee20310fa9fff790b04a2d8811b46c5c97e66dbd5e36b03aa290cb9ae27ba94018e61430eac223f -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA1 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = 3b9ffc79b59b069fb97124a6c13d51ad413638c1e8e09dab2383f90be4db64aba111b80d9feaf446703fde0fbbaded1a3b8d65a20a26c44620225d17163f43f0304768069b4206bff3ea3ec8095f0062e21c2afc032af407eb938b06e21afce4f129548b320b05b24a5b8cf633bd512d3fcccff75953f4958ebfcbffcdd45830 -S = 7f2efdaf79621804a71b9fda74328b00a65d949b26f739e1b9755ac860c5ad7bf63453a572fc54d6ec790230ac91a150ec428c252f2f8e222625b3e3e65e5abe5155b55da30fc2a89e22101f15a841058ccadfcaddb5405738d86fbbc85d82062dc988a945fb2afb9a9c4d52494f0cfad39f120577931632c31a63f06a370d1150aa4a45441bb31ccab8f7f742f5419a14a302ee0c558de496c66002a02266154ddf2b5808e33b920493e5db1719c9e6f7f43a069455024364988ad622d8d61a5b798a5f9849cf29a0d59eff8459ca65dfd0ea1a9381e8f595ff72d59bd86eb04afe1c4b61c239a746eb102effa940c011321dec7675d99ec4d03261ac254602 -SaltVal = 00 -Result = P - -SHAAlg = SHA224 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = 16ae604b3a4e9c7f1d616e2deab96b6207705b9a8f87468503cdd20a3c02cc8da43d046da68b5ed163d926a5a714a4df1b8ef007bca408f68b9e20de86d6398ad81df5e74d5aaac40874b5d6787211ff88e128cf1676e84ca7f51aee5951efee1915dcc11502a8df74fac4c8451dda49b631a8fb87470f0ebe9b67449bbd1640 -S = 13c5d85a48e10871542ca7b6c7f7fcc0f86da6e9cca9fb9b8f36f30fdf2f320b61b73ca1ef0b9c07af8e675f32b7a648ca109885c006971e821f09a489d1f8b79dd2d03a20b5d9c02f0117bba86ce8b419c67b90093d89f2631dbd38387a847b9490ebbfd7b6818f70e09c3ac25223ce2199030df51bb5da8242d1dd2396c72062a60f481c73a830c109e74b9fad92d7a9a414643ccb2e392afd13a8deab2b4433b0ff5eb3c01892c71a00a3e2d1173506b6340f57ad27e54a4bc5e16d50de2ed519f300f2afff9bc2a39e42c70a0fb02123db01500bb79dceda3a33b915ba095fc1269542832386a19b3ef65f56d8bf64ee4c83d5411bd0b6f097a749556917 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff44302d300d06096086480165030402040500041c35674247cb0e952ef2d28bf3e3c63c34d0ea8b3f194941d3678440aa -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA224 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = a9db46f44d85c4414d15a62541906e6ae498c06e2336191174d6bdd16993f13485b56b674e780724a310bbd850e9cd06e03343e6b39e9c535062bde4fb832e588b538637763824b62eaf20dbb09181e35996b1e1fc172ea7331881e9f28574a062bc80adec4c85bf93fcbe768810f3c9f8c7f0a5292837d6c5fef22b76222bd5 -S = 0ac7106eefb290dc2681c447fae564aad0e73028927907b323a7e1c340efa53638349d3ff6f9bd393431f085c84bd5a447a82ac98cbe6100eca7becaefb20fcbdf3c13cf883538e39a7c47c92e0a0da716bf520835156c02ad30d357115e467f9fa1b869ed1e6e1736402c2df62276cc766a0916ccebd7854f0b6f14e88de01164491ca82ed831e6e2f45b636b4ac73a3a0e0522cb47ba1758dce66ffe9e6afcd09ee6820bea67ff7351a157aade87d7243e68d3a14824b07c0a831260fd4b21020ad943ab0aceabf2fd259a038d30f786ce3a60c6fa68a5d7b1901380b19912a7eb61da8a224b9f0d2109bd161de1d3892d1001cdda4fec492bfd1fb0050039 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00302d300d06096086480165030402040500041c062e999e48e75ccabd60ec5e67bdede1b8beb5c89c5b8455d638b0f5efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA224 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = 659bd5f2edf90ba229a140bceb69036750477ef4f4ba4a646565882ad8fd2d321b669d21cb197cdfc7c9c053e4460b6de3a1396aa09134538b1510c75c5b54fb03e195ffdeda4a432fd3db59cd96fbfc1a4f385234edd06e70cbc719049036d20354e6138f041dd64a07b8580d217a1ddd98a4341a96c6bcfacfd4a736637cbe -S = 8742d7f61cd01a1cda403f08a9f367dd2f62895531634920eba3de112e3e5dc30752533851ffdba2bb48905d3532e2a55572ddeeade4dea7f80664b243f951282ca678194d6b91a9fdbaee763b01823ca4037d77cb3aef976a90bcaf195431b3856c3b598bd2c0e9000970e49d0938b3492b6c710ee898fc719b40d0b5cd98a54de06cea29584361317f4d8adcb23b982479513289c4729ad5b39fedb2ba6a6cb83fff0c2dc35d8997b9bc0d8bbe45857ffe3da67655cffac7c89e33257bb08ce3d10610b53cde7d8b31d721ea34fde8f798cf91a866bc0a52a9aa03e24454e0ab27f7cc00219072b3cebd9883ed1fe5dd02d4b59536488931d5c6059794da49 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA224 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = 25c6f8cff7a49f5c0b7c1f02e3d4b8935c26cd768f33e79dfa9bfdb6dbabf3a6dd766033f62794009095dabfe718faa2b29c021205f346a47670a6497fb10fc523bc4562d44edfe5956f93c15c4ab38bba3cf8aebd2b7f60161911d477f8a7b13fc02dc459c087f16131d2700911ec36bc2f36b0818298b721bec6c18c29c254 -S = 44e33dc3011088c96cf066e4a3b93487d86779cc770c43e7a7b5d6b722cd582ce8988a28605a4961645d9bfcf60b68a83d8a5f2a85dd07f358715fdcabcea43c2816ac12771e76e54c14fe3073e1eb43312cd0e2fa0c93f07b0c215220c59379121aba72fc7e13702d9152386f6554b12b0323cb42d09ac5ad5f065fe6b045e37812a55cc6132a6a9dce1a7928a974e3e35213719b3175f96ef87dfb1cb84a67bcdd5f5b15fe2508bb6815809404e0e6b1d88da4d7202feffbfbd76010279fcd4f6fc233b27a934601c4e3701fd00eab581fde1d2aee3e27ae9b7b627e208d013fd0590c3718731c19f105258acdfd10fc8c542982e6d86b7c275372b8112fc4 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA224 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = cdb5d9071fa3a040095d41253a6a8081200ed6f4aa095b455181eaf9593c7f255412e380e9a28cbcd345be172c40f72dec3e8a10adfd8a9ab147e9022524e1aea74e934807e5ef144a64d381f5d477fe883f080e4868939f41b925988c7d31b1ce4f318701d290f077a3c88b1b8cc89cfbfb981703b23ffb0bbfe5e115af35d5 -S = 1dd48357b45763f1bea1c5a7b0f346ca8aa1ab19b163e05c78128e5f9625a22a7b3b1d8c18763349089725fe41f7431bcd42b965ae6f7dd00ae046f7fd2161d344b471dee5ff1d9fd4d5c520a6facc3bfbd8650598b34ea6c94d684b0187a2437c529e4d6408852662fe70c807c1270427b02db59f04b8df01a087f3ea9e3c80894763de195fe7f92dea8c70a3bb85864e410a4e8313a836e47fcf5050090742fbb1eb64703d5d599fab43930bf4b8a916c134f4984993e2723c4a5814265c500da5caf709143899c5a5d8eb199479aa0cf68366b7e80ff21d1352bd2bac2bb2c63a8235a379b3fb3baaa416243eed20c2c861e4924b71de1a74bfc96a85ad74 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA224 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = 14690026e93115e009238306861b8968408c9f320614b61afe54c1de47fe74eedc2f4c65bc00cf3e485815c5ec04874b0109e71ef23891b99e040037fe91930e080d91f9d3436c36fb6d42f2474aa9028971acd3c6e511a497e9def2cf161b345eaad8c97623722fec0d1375e01878f3a06df738ca42c044b1ac63f802b592ca -S = 0356405c184af63e2f550081e8dd7dc7138bdcbc44d22e6225bb4babec42983f0556989ebb8bd6df4fda3b1a3d4abf2659a584ec0790379c74c7bf156d14531939aaf920fb9959d5e7cd0d2fa4f86c8029e6271522faf29499d50bfdf1b20e68de2fe4a52a84db86a39491e0e599935c3b726f6b7b876e8bbc633d05ccbb3aecbb9d1e419bd2bde528f6a7ca6ab4c9f8638a67d9aeef1491af6c5fb1c29f76a68e981bccad09d3eccdbb2fe5d44a9bb23a10f9a0fd594173b126fcf145ac2a3420e78b6b195ca4630aa2a48fd62192f21c34e8885187489eef8c79a67aa079fd8d2811a5d41b73a1cf78133424943b3414dd183d8ad242158e3c3c956185a153 -SaltVal = 00 -Result = P - -SHAAlg = SHA256 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = 266a05f02ee6137da278d709b7504bf55978e432c215c5aa4cea34db831d4ac57f3eee07718504457b5be1ccc51c0279cd1cfed7fee8ba8785cedce5609f82e8b7b3334a702e16e9fe82616e7935152cf4e5e94b0b898325bbf9eef077b1499e77d1bc015469b133d2f44035fc22ead677db8bd610808a4c97745345f0db07ae -S = 598ea4dc537da91b6e9593fcb39d89f28fbda380f1b42858666b6569d40688929ced67f6df07eb58bd984fcf51a72b863649603b6e3be9f99cae28015959ba7d64fa4c0f188f849774760074d46131a5b78b712d50266feb110ab034b62bd67b38bff88eb5f04cc174c8c9e2d8f8daf6c33038a1a10088698fa09b6c397db2da169468fbe2eed851ae1265cfc05f19642d8d6ada114f4ff065e6b7b132d3cc498ed23ed4317a3d0f5c5462c9afd7dd196faede84f5f8e40b3bc8913797f1e23ebb3aebcfb23749207c95685ecf0e3f164291c1fc9087a49c88fca0b4736c7c86fe1a159b6b34dfd30cc626ef4c458f712f4a879a730e8fd6b2e075cd02b96011 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA256 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = 58718b3ba6a4ddcaa7d3f7bd46cbca5591f95d87741fb852c74b004f8c0ae38a71d937909ddcddc9a8d3ec08eb490b61fb0e1f3b70e827a5eb8663ee57b5bc6f6ed760ac7f90ad9c6fc25044ffbcae8b4cae83499c60c8a15724db91540adac756524fb6d72713ea048a6c98088c797a8dc0d0d980f065ec150fae600c6f0438 -S = 29c5a0ab72d0219034ce32ed330a4b388573eb804713d98029fbc1da87a474eca1f1814dd61e26c7bed630f3a4f980734321d56fb3309c751953a4dd9110c293730829bfdc83cabf619b220818e30151c38e6bb9d304eb7204029f8af86209275b1b5fb84bdb12aeaf3013db78d6dc1bcbc23fbe3dd7eb3c3bec332c8453de3ddd2e39cadf7e062f00a682bf18ab68ed3c6bddaa9dada51c99117eceaf6f8179eb9a59e6143a56d5f26d4138a5c31e49104c5982cb1b202253a292786cdb94a2b383c9d96afaf83d52160eccbc42cf2568744999a662097b315ded7fb417a823e3e9b6c5f7a822bd58a4e5542fbdfba63f60266c0b86a363153ae0444e0ee1a5 -SaltVal = 00 -Result = P - -SHAAlg = SHA256 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = 35524c5781983f729374b6342099239157485a64b9cffd112b50386849c3afcdfe3eb5965174bfb5827d189756d5d64cafa60ce75f4a41283e0b21587b2e73752f314b8f38508172444e61852c71a4f284cfa00770c8bbddb8d425371f7fc7acf1b17609dc336df1006ffac6497777cdfd497c8c91525377c130accce0bc92bc -S = 77fa540194591f2d49a7740936cc5c909e73e970fc833bd8031dbcfcf78599095bc8d185cdf681c4855c4e4527a75c5552ab3611fa7788c424c3b051d1236fb1bc3e7b65421cbb1982ae623fbd65210035c78032476df3d64c8e8136c74c47b694a881479608568368fae8d7374d32173240e55e074e4a064f6309df823269f2a2477a5bd06c819b67d9c5f0a8720af431c3edcc85a1b2cac7d2288d90b446b62cb070d1cbb87234ec41c55b89318bd852aeb60779246ffd84532d08ea27e27347c7997e7007da4680f4b7872ab89499a1b0381c4837893fd0ca055bf1f0fc4b1682044190d40e7cd4b6c077faa077d27cf5a9966e95d6acd89f1dd1a61a8a4a -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003031300d060960864801650304020105000420b7cc7185c6cff2f0237380831075de8079252edb588ab3a492e600abe24dbb7eefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA256 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = 31dce7cc7c03a063b9879e0343e9b6461db1992333a941bfe34a8f86bc74327b8662cacc82dc4daaf3aeaa57dc5aad810c0a23ce58c83eb828f13b9b35e7410c90078d6de7dbccbe0490c8b696aa471334f6302e9fc0f0d247471c4e116e58c958b477d63266e449f4144048f8414ca59d5e0a6b90fa1fb64a337cc8da703d5a -S = 8be14c18fba2b95cd0d0fed4b171462b07db0b5e5edf5803b595182e97ac814eb929be28d18a8f45f837ce537475fab819244788681676ef73930ac28062082b6a593072b2218862a80439a1b9e2c637ef9806463c7c3120a01473ffd9df2152d871b83d782baf6512af6979ba3a9b8d68828716539c771161b81bdd056f7535e2cc654489c90ee5c1366609c775c760cac8d084ee6d618d25a70ef64fa631c0c4caea75296d97237da8c977e711374620f232e71163d2a2515d71e30985f84a3d4839f4367a2d273f0477bc677dc830302ac423364f4628d7cba5b92d5c9f37de4268f8d957905072f2cbb7249dad4f55909e41e4edce618535c7cf62001f52 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443031300d0609608648016503040201050004207f3ac72d5591ed16096abd35813dc29dfaa0b834e2b57e45315b3731b4d7292f -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA256 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = 2656ef08c07fc1ec469aa9c73b677af225a9f5f6f8d0e150d1d65e71e6677609bd44f5859de97ad6436ecf75d5ab76a41c9f84f6ed13b311e87ab2b3661cbff3ac7378ca65d5eed14f54fc4c34e3d7681cbae5c1c1fbd3274395e2a21d6881b358ab21ddfe8b4564d215d8553e56c4c68dc1c05f5ad1691a48ef9546f495e4d2 -S = 849d23a7f9dfd0956315dc9a60c04dac1d7db660c67d2ea57db40098a84d258b111457686821134dcde66990015e769311aa53e1920bacbf59d214beb3fb79cd6482601f5ac3848f90ebe864428d0854a245c1a51f40b10899cc08fc4dcaa6b322fbedaa7b56db804009a0829fea827065ff655c1f82497c5d59998c8a577bd5e170b4734b7a24f574db4ac56fd7cf96039c594e9a109c10185e69102e27105533d826d50b5c39bd964d88ccd2e0a467a668ce15a84014c958723ce6c09230bcfdded9839ef40bb5f80ec2073081e5e6565454270937b8cff537c0b065a923d173ad04a31592fe699e2424d8bf6bb0b947ff161a33b9b03fd69892a0d9a8c711 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA256 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = 1c58bd7408d1d2ecbab294bd48408178d4a95be7ca3c89e963d8bb7c6ea5cd1c4f03ee4c48c00172f78e43e720b42e4fad039e26f30c339c3790f6a371383f464f86d63c7d0c58bd24dcdc94b13fd776d7aa3d92d7ede969ffae3fe07016109325cabd6d311da0764884a7eb814a42945a848052fd4875f8c21ade5bf4a708ad -S = 60dfbc77059709311bfa31a69dc9db4703d0fc44d715598afc39331e2620d73423f2cb8026c3dd9a133a7c0a62174448128934c776616f1f9bf12c3936f52340d4f034725a759cda95a743602805f0fd7bb03a8d6fba9947d1692f6e7615ae3b89f4251542f5c902f41661f443101da8a666654c86d3cd8aa93733d677d6c4e83b527def0db12bdad93feb76e9bf986a1624834de5febd2b0a970db189c878bd99d3ae86decfd0842735361bfb1fb0cf548a9bd43411b4be4b8db8db1a585555d9fc5066bbdc081ade816777cbd29723062ca7709429331bb52a2e5967948d1d6aafe979a9e12cbd20a30937bd6965d1a04e3060f72a46fd3af1127dac637a24 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA384 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = 47611125ef346ddab85ba9493e92eb1566bad85e9d17f99664bb63900b4297dabcc0a74dbcf89ae2eecf12c899002cb36a10a876bd854ad418537f93f89744d3d187449e50a940c0e344b4d97b15b8b0914224ca6794f73c90e0fabdb2c6a0ff8b9e314032b0271c9fa3d9a56e3956b5e039948323acca75d34b1a35c0397307 -S = 2fa1aed1f8b9656c8216c2ea8ba98c67a6d52cc143816c7f83b5f72e572d6953c28249593bb01332ede6b991ada2ea1004e594966f1aeb2fff14db6ae311bdcf439c8c949de248d7870b0f9f3edfa11705de95b552d3a0bd86fb52476981df2cde1df65de3ad7b957fd82b7f98d8c6bbd4b7e2b65e143c627f5e4d2cb871326ced2f904947ec2250c5ff9d330a74a480afd38277909d4d040781947302ebfa6ecd229d93b5261eeb237dc99b9060749bfeb189f99e0164ce36cb0b64935e52870fdc8cef93a0e198465f48d7ffd87c9bd1b40a127f0fca14d559ceecade77d30486cab930ba50a3358269f641ca11ccb30d3fd21becdb50efb778eb10d424b76 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA384 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = af84a31d1c08faade967cbb5a016837fb2d1c0bc5eea5b75d4e2a6449b36f2c3307b5545f0adaac437c5d81bca89587572a8f106ea06c6f9fb5593a9e6e5341302bd678ca6ead2af4917489ae85e485aa95ec6a3bd8e2ec48ad0a7db0a4a95456e71615908667c566786a199c43d5b149d1ac8fb9f299cc0c97d6842cf0c1d42 -S = 014773de1e3486a2d54c7a0a0a1a70caf61ce94868902314462c2bfd9c640de7b499578230a41734a1822cd0fde610c487c1dad10e35d70136cb162d79c403c7408cba33b72fcafbee2dffad251ecb6bd4b082aa5350b194c587b8bb1ededc902df1e2e6eb03a5744c87ee49e087759237ea133c8484d62cf142344b56cf3c5e1f72998c531129f66e0458bfd4e8b1de1866e76e3912f680bbf8a96ee4f2971e6fcf029788e0dd586db744a7f9a0010a2a27d98b3b04884cf269f19f1937e8612cfc5b144b7aaf9b2fb0464a26f4013de9fd12851c3f8c9bf1fe6926fe512e0543114cbf9bd86336d7d2aa6c2a696a3fd071467784c2cd8f64e8bcb00fcbc792 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443041300d0609608648016503040202050004300c4887ee786dff1356756432824889c71e522ca5d478d9cba311b11a51dae49696d1f1f454ce4017e74d9f45cb17b797 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA384 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = 5c95cabba94825969c306fef29fdeb104955f9e7fdc63aa29000f57d1d41b9d85210448d732ea480a2ca9c785df4492d485405a22d1c8cb4413b5ef3a9d464b23ceed55a8b6d5b041e41724601dd114c80ea8d2b2e3dba732c075303a74c9c22a39745cbf7eb924799fcb9021c9f8c977780572d08130c06d9cd9d552193aa50 -S = 019962ad704a78fce2306273ff3a649fe973dcf2dcd6d0e692a592f357c9ac459a15b0bb0ff986f104f99301c87579a321b0d4ab9e947a9de47b56c0094e4ffa6a8949594348e342f8eda30e68f5005bbf72cef70c522a124eeab1d7441cd65dff7e1ad36bca0534c09c284e8e931766406b43b62db89472c2514c3d1a6911a92e19a0dc923919daeaeec53746f487e06afedfcb679b531ede784d9d6072dad50348e1d8f01094f29cf5cc96f6c1f40ab455be6c98788e9d7615ddb6a66b893913ad0cc63a72b9dd357ce086b2df7c8a106c0c363e3e2317e37815df69b22a9d52d6e5e47d8be17ba61b2b2019a0f85fae30e1d4f2622be50086848cb405d578 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA384 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = 7f88a5d6178889bcf09ab7407a01bad132cfa7456ca0fc294f88ce56214a24c5c5cb9ea581c65aaa05c017a7a93f9b5ff737539969c53a72731ffbf7c4cc5af3ca10d00674ab75f73bc3244b631ed9177e945d1233c426ee3d0778e9b6a2d19f96408422779fa44c9b8923542f063ba0d1d00dda51078946b4268d537f365170 -S = 91584aee68fc0d4e7d24afcf4eade5fea0ffedc4d49d1d75e673029bb998ad170ee5d1d28a2779c846e617b8c9783119f4af4602461434a24c1351f737ae315868a78f615019234606a12e3fdc3cbb05d2f0cfc877b344fbecec5f71f0202b507df23e4a3917cdfbd1691fc69c509598e2bd7c71ac39a71a295ae0ed1531b97dbc6666ecdb830917f04cae848f8b18b8abf191091b07632e1632ff611432b7a50c0a7654d59506ac3b4c058eb16bb66174a39f933a4c389cc86c9c124a3246402928a3e3fcc8d35a817027c2c2448b792f2009548516642d75839b61c6e2d5b63c4ee4c0cd72e559be3cf0e466a4a566681b66b71089f67c1044157d78215e0f -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA384 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = 97e7bb62b6d35c8e423a4c98de8264c14eacb2b12f36cc76e54064cad6ef1d94d60f9db2e1fce4f610c2dc6ec68331e92a1962b6dbfd19afdf67b877dcb734ff8a14264f68531f83ae1a3c138345fb5871884d4c1656ed921c02efb66b259cb59c3f7dc0b1a1b63d048a960f7e906b1709419bfa480bf0258559340febfffebe -S = 6010444309201677f71890ce09e31f671208b2804c309a85a401b275eeb5d234ffe5fc6dad17fd9781cb00ccccd1d1260c2d7090652add1b635633170ef5e9eec6ab240c382a3850fe0947892870d0424bfbedd434db4084ba29cbe7c8a27b4aa858b648fb0c7096db4dfbaed09fbd7483a2e9d8c409f87c9a2a26984137000cbe451140da9bc56c4382a091bcb171c3da5f9833fd224a429353439469a39033f2e1ea20283c643eec651952ac9853ac15a8a8751ce72a443b41e17e41fb86e69ec0620660f65361035441700652619c9248b2ebe5cd83c00bd2b232c13b544b470334d7314704dde6c81150e54e9ce132a5aaa3ac03a931113160e93814e968 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003041300d0609608648016503040202050004307c1b2374e40835303155d969bca1d02f901e2569823d83b1b8ef0221cf4af285fb3535d60dcafc85b0b856d7bb9229a5efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA384 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = f167b1c5e4e480c6d96035630415b83c9b2d137a2ecd6efa37523eaff2dbb9416e078dfae400d1e349b83c2a1f7295c790856a5fbd5c056954c29c8f605cc85766773802ad05a7b5dde10bd6cc5b10b994f0c47ce959942fa9c87738b56e69f600401ba5e5fbe982be650c2fb2d61158cef8899757cb03955fec377397168468 -S = 6e2cef82eca498f7f1bb521fca7f11b31f1e80f5d1face48609d78b2ba79b8e82c6800e92d419c4c48b7bdbc6c41cc2b9fcbd05627c1f4c567629929022baa4ea1b431f361b08afedec6eff545b682b8d9a6b18bf62f34a1596048f5455f51d5496c89eec6e7f8431ee271ae84658347df2d1a52a5acc37b0b5eb1438342da02f2dfe44e50877221a8623b1d1602339223748df48cea785f94c5ee719e95ebb2ab7d795dbf53d4055be0591e203c6ef69d6b08aff07be7e546f501e42c3192115b5f2c259c4ab2dc585cf37dd3ff54e89f0607c5e3a2f198e2875a7550bdffd0eaecb44adad438b3d0ea810668eabb123baa66843d1a136b0369332bf74d91ba -SaltVal = 00 -Result = P - -SHAAlg = SHA512 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = e946af251dd8b043a9c866cb4f5e4b65e5a983b4587203e4f16ef982d7b76891d67d13da5ef99d83cfa3eee3f3a5d995cc8ffbcb914ce6e5f3557f43a424a4571aec12fe918786104fb023352b7214fb50e072263f07684813219591090cb1e73ffa7439bc69b311b156cd69fead45c0f805b06d6a8ad232da3a04140d55d86a -S = 839d586ce12b7c22bc2e0d921d11756a9a65e8275f61307b1bf1d6e350ac126a50c52363f561e2d2f8edf3f92b9fd88af138178ee34fdc3f4d288bb142dae2e5378c50754da25eb541dd80e83f63a356c760e8efa03f07efc420109bae6c701fad5b8dc8fb266e2ce1cfa7b71f04f63c692e4b0aece6b970baa77914791e8a25e5100a2205811da238a451f5a100355b28abd39964d43dc0e2b51a8e2ddba0e94d02ef11a5cb2058acf3f98dfeb34cf939b5bb0525eebb17bb25e517fe3eb3e04e04afa892f318618cb66de38503bcf994c9d2ec20effa04d68a0df7c76dddf30e88e1fdf5afdcb2dca0e124946e7f39248633b03166027611deb276bcf2c0ed -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA512 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = c41b35fc1669b8663a14b3c37c87f27c2d1b7a539b3b1da341c74be93ab52b84fcfeeab942b854fa4a7fa168411a9196fc5cbb90e847211c4478093f8dbf08033a0d6078aa938cf95b2818b05cebb65d052a8f52e583d7c2fc49a43c2a2a0073e80e3c40364188ead4d5c1a4b5428a57b1509ea27a376520d104c5e9fa3e3a5b -S = 2ce448ee7ebf21be380247cc3f8472e440f3911128025fef0adaac37d4dc977bc5f81224dde9df193907c17fbd624ddb51c2b54c214af57520d3f69d12885e3b47cb2c005c18eac82b86d5d514cefc99794badd609cd5cb8775cf685ec1ddf6acc0272a4a58311c348381bc24c4b85626993a601ae292b13c3e8a9c0262fb8deac28320810e776c196454be73d5ad08f780ef45dfaf7704435f2b3141ef32c2d7ecb1f26398a0dd8c01c39367987f22600b07979627b391276d1c444ec87e430769fe22ec3e1d5cd4df358314282d10e2a4098b6658ffa44c4135142c2661f2a80d4d380b5ad3d2727d0ce12f1e6d67af797c3480100ea50a0fdb0bd1cb2a78e -SaltVal = 00 -Result = P - -SHAAlg = SHA512 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = c069fe30bbe18aed9d39d26f4ebcbd89a9f18f07982822e5795372bfc7176089f623af809ec15360dcaaebd8f61f8c3b3d35c0783871ce4cfe943cb6e4b893ac589c620c0d3d85d559a6a797db080628600d7699076aa968a4b4adf76374b63dae7d1ebc507daab3dad30f9445a0b5b8da21ba524f3c3aa23358ce6b8c7252a6 -S = 5e67fa94c7e19b66548220ef4e07769ff75d4e76917004492334f0fa15ffb8b14271301c170e3d325811bdfc1dc53f1b4369a2c0a99d261d9de59a73efd4ecedade05da9faccaf35d462057bb8bbbe29e3f5d4c383908c0b25006f779399064889441a84e0ce569eb474ddfb83cda6be253743693bbd551f6ac0b8cfad225d5635972d4e508ae5f7846ee3adb61958ef53146af42d0c6ce32559f661a3c3a14068b8b488f85d7e5641e250bfd9975653ad86f93ba5e5f57f5799ec135d9af7c529e6447ac43b114475060150e98ce86df3f69cabfd5a59158f0f8c4043935e0fee317901baf27aab76a2cc1561d969bb3d69de65885bfec00a522c5010fd2ae1 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA512 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = d99885b2fd968ed1385f0245a8ec086dbf33cd903c4a1c205ad0303b4789c677d74876df7a1242396c80708b2b6595dd2eb1f33fd495040e9be8577492ca9b2e1187fa92a7bea8d054c2bb78f8403d3c0c227ff890b4b1ef4405b0571b911f19ed1cb9d26ce1e51d59ec8b14f8c52714c14e1cc158ee4a4abfefe2efcb2579c0 -S = 0efe5b7647f3b6bdc7e9d161afe8591fd21c818276311c4a04a3922e7da47c9ca87bdb8d2d8b8eb267a335ada64db1f19cc35c6b9bdb06589233a834f106db34b75284f943e7426edf57b63d3c23032fcef1cc871530ed003b3a62d994caf8c4c10a90528af67824f5e5267b2eb284c4310706aefe248d3a2d98e922c859be49b71c0278f537fea1586ad9658da5c59ba11b6abaf2433500be32c862796de6aa58fe7955fa51845fb4e304adec80941f70e27ec24f1c6bafe0f2746fa102040f2483ba7e3043469c6138adaf8fe50b4274d9548b30ad0bb048af103454afad3e536c2d95ae24fb2feb08ac0f469551edcb3fa36ca078a469c001d5637cbb1bd4 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003051300d06096086480165030402030500044065183a0ec842001ad183a8b55e9118f29757c477ffd30f57dce02a218238e0a400d6a509c69a74dd64b400c809026e9e3ad8930f550b594be664491b5732f3afefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA512 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = ae898f661a8614a533fbbae90eb5e9810ca4a205b9327845f4d3dc7f51de9ed5bb9bb1fd5e9d2f3bc4529c8c3dd86f248512ce1ba1fc9a640a3babfe0df95d6e72ef4b6c5cc35add7095fa0139d5a8eecb57b73da7a95103dfa4b9037b41d2211aaee51adda19f7380ed59afca539dc5289ae5d195e1a50abc358cf4615f07d7 -S = 0ffd86aabb2861142ad2833b1b74cbffd660755d58081f816f28639bd6cd70b6d312d6722f14e4d608b154891eee96ffab837e472286c528086fb323ade633cf1b778427b504701bca01c1a8cb18547cdc3af6afd180a65042c072c741525346be008dd2dddb53d63dc7b33458bc59fd50b35bdc291a2760ac545c4fd21a37b710050fcff970271ab9ef51fc5953fad7bbd28e9d4f84d27c36711afb3ef2e21d55a3f5cb028667c10b23a334ed7e7275b6830588f4938f2c3b9ff795029c5c9eb3965bcd784ed3bb5a119d165db4ed808d388423059ffb091fcdbb1e6e5c65291b1e5fea5bd17e2c5f16be05c3d13bc8249b7f98720b300479b0a25d680cf3f0 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443051300d0609608648016503040203050004406c4c610edabaa9eebb437d9c62286c4f159bb471247b77f443153bea722f2a86de52a83f4c9561ae581f8b3568bf9977ad8696ca8f310ccecd598238b3edf845 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA512 -e = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 18899418d11166347f1db7538f58d6843ac6ad8ea66ab60c184b5c7577ca9aa99a5e89a587805b4e5d1ab6d13fd06b640712bd62d4d830ed315491b7b1e409c89522beee817b33efb59d982c31dd365da1937aa6aeedf68ad3049f82406c78996c3470882afe0ba6552b21b6ec97162d8026ce2c707fb76c27b41fc3bb05bb95028eade0ba33868ecfa617b98f829957ba83934f2dd4621e111058241e3c0e08abf7222f142faa81652c625deb28d2718940679869dc51fee3e0e38830914aaf6c0b670a04815c5265836f4e9895c6a2e99111e0156c92f3c8d23b89fff18442876678c2b2c40c5a7c6f7cb1a3d314b689d48f06faed34047ea1237df9a3a2af -Msg = 0c84d0c19e69926823ae89727d7dc8f27e2dd6a8fe0c60dd2b5c2a8f219b4bcebb089a66a86264bec1f3600099cde47a56545845c0fcec24985486ae2b44feb027928ecdacab8467a6a13ac35b7048674085f8c71181fb21203a5aa6ee02afdaf82d943dd3cd5c2b7bc00101e9ed5e81e3ca9e781822f59d6c158ebd9160c415 -S = 5af917efcb50475ef7d9b555885d07cb1f38149cd8f0102760298131cb6737f5d085f2762682f98c5e5e9918d9ab5ee4eb6e94989bff59af8ea042d0225d71690bbb770ffebc0610afccadb9726c9fba0ad7c716a0712fc4ac4e14ae7c21adca56d7349e68440b3244ac4afae225e7d70b68b4bc80fa9ca6a0b5665ffd831acd05403d8050c35d95caee2d6ad1eb53523a531e87efcae11cd225a102578f8ba6fb4b907f22b9515eba4449e145b9301619d5445723537c16b8543f524f37301989026d0b4829dbc5386fff11b74e54be9f8203f2a2cb16a2181f1a8767f1f161f650f7559da91578b999a34a2eab985aa96231b7200ccc6f38c2a621ab6b190d -SaltVal = 00 -Result = F (3 - Signature changed ) - -[mod = 3072] - -n = f33d3234f13272c3b2b6821ce4805663ff2e8b0d2a47de363d97fc9cc879cc6b40f9e53aea695dc538a0d2b558498829aac327eacbcd889e172b34f90745c5d528b7e82605f1a58fd228ec7fd4b6f476f393864f48dc47097c8a780a2ecc02f748138dbd7df99c52d822a2e5154c6047fb0eeb4f49da38edcae3c32d3fde435f291f96cad1e09e1030ad7efb4944b69e074d0d7964becb3cb86238d8d293bef3030d141d14868bc21fa133e9de1115f749991cf86ef506e663ac162b2c8567ff131a6b467a6f564d6c588860becbd88970354198ecdd4f1f4baee8f8bdaf7255835385f5673625f113550b123628a0be3994d91c3a19a82e5d73448dabf684ee6794fba7a2b1afbee0287e5a11180c29ce0896795d52ac7f408fe28e8e9116fe0b61a1083f95c5227d62d5537b5040b79e21b3a8e83c225bf3efebb2f808541e97d28a2468359fc60f588e74faad611262064628a25d8d61f9d03d8b21cca515595aaf2343a759b74a6a8afeffca139a389aa281995cd18e16a9cf7b7ff0dddb - -p = f3fcc6aae575312778d9e896acfd7c1aa4c5524f20453e8bab255363164afa7124b2425587a077fa0bfaf61b12ef3f0540dc4c9e777122a60610a53d1d75b0a5859c654a8ddfc2ff4860758bf5a6f264bf8bc2baa7551eb7be23bc06978be992fc81d890e07a3abf95d20eee3f6bbbc089985cac96395b473b2741c66bd2ccbef228432f66b906c15b19694dd786c29f06cbc17b2e6400dde4e3db85819382b3d05a4c3009f092d40d05ed5b2e0428a214e15a7aca09b47120b9ea6cb4084fcd -q = ff36fcdc519fe10c69aa0dde2cf3bc72cf2ce9a54ac063d809b523f4e5d7ddaa5413d500dc21f409ce661bf33018b748fba3966d874bf96f4313eafea9decfba71d540ae0508161a3658c4762d94ebb3a4e228c45661315db30c20fbd9e20e24c044e4f0b49e6ec80949b16e0ab07f3d32b248b39f48332cc3686df05d29c170a7276acdd129259aaf018ae3afb49b6e0ddb9e404a492863daee7be71dfb11279047794e45f399a9665796d32d5e65956a13a6fbe992b36bf4c842f5f519ac47 - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = 9d1f17aab0ce96c4d83405d1e3baba1dffa86ecccee7f1c1b80b1bbf859106ce2b647ae1e4a6a9b584ae1dfc0a4deebb755638f1d95dcc79b1be263177e2a05c72bde545d09ba726f41d9547117e876af81bfc672e33c71442eb05675d9552df1b313d1f9934f9ddd08955fa21d6edf23000a277f6f149591299a0a96032861e -S = cbb358cb77cb2f130b7ad636fe7ab00d1964ebd5da22bef0139a6265a15c6638b17ef3d84a588710adc06d0242085f155bf5349064dac7481ed79d62b3ed60121f010729b61bee45554bfd5d494afc55405fcc1ab8eedc9c6251d2d0512ccf2e4f370dfc523215a09553ed2b7a46e8bb0e63d1ef0b09664b42c35e303e2fc3e2142e53a0a11569f8dcd56d47542618e3f3aae3790e1f531240b52b0a89f2a24f018116e513e876c8079f3ea61210da71e481ab89934385319de3275c0d9fc9ab33ed8bed5f704ad40ceb364f21855a5f5cb1e1d2b580ee4724fdf61f308d7136160127247d4db3486170cd2183047f15c8cb54368085f595f6bcff02675d6945a1d9741768820bed442fb03d5087e793b62d3d0d37567020475268c8786a5e5385970728cebd6c027aac15240ace0f0beb6c29f656f6b3f3d458d20005e41aef294de9823722893021d9cb621b29c2730cda7b6703e3a66edac57019b8404eaf8483edf91478f294f88907e277bcff47fdce9ab7f772ec256122530ed8bc3b48 -SaltVal = 00 -Result = P - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = b33acd11fefde3f71597af02e49e821354a0bed0080b31a44a4aa1064531a8ff749bc3e65a51a56f742ed1e46c8167b18fb33e26812a34792f6cc20a0688d4eb63b2d7a04a2d13235a6e3b2c007e42aeeca071a5c134b70f11db403888dc483b67c632c63457d41db09d16620a5bbb1352ae7ed430f0616fd6dd421933f4aff7 -S = b1f3ee7bf9b57da11da3a557d311e0d00e474578d3d798ade0626105191f6db1d8d66da0a35259e40ff746d9c512478d8972cde6bf271f679ba2f8e49444002ba7f94b65ba9250bb5710587c9ea0ebf31802abb7508a785405f8ba7e0753ae1b95675d4a89227a93a96f3f273fdc3aa7fe48b94e48dec9ab2fefbbbec394a84305b0237232394c21cf31ae14e5b938e825be9ef35605d0200b9c085cab040833623e72fac9f59a2297e17cca08d3a0e11cecb5b35b3b86238a48be38c6c03f7e45d7c5495d55aab57bdf8edd871aa9caef624466b09721ac7d27a74f5ccb3645bf0690d0396fb56e424b716df6bd9e10becf9b7b10210266d0ebac4cded6510b02528ba2d3b5318b7e8f43462dda97b523b6f7355896cfd8989f8d9dac98e1f98f125d60a5d382513426565f3b1d1f305c59b2b7f659c41fb796aa6936e4e845c4ebfb14bb62b2883edb1580e68d52d62e0143410f5a5d2e8f7a2d82107b2ffcaa64dbdd32bff2d3228ae115cd86a27a3292ff43d165b174e7d77f6dd73402c6 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = 7020d49c0b19cb515b193fdd410abfa3638fb66e2cf29208145e2608214e4debad45d1666bc08bfba568cbcbc78dfaab21d07d79e91fddb17fe7253bf5848c87cffd54dc07eef2ed55c56faead310e6508d82f04674973b6153121b82dd1c96a5daf27a6e98c4950f397f42ef9e045fa9f0f94b6af569d405ea4e226d11c4bbb -S = e4ce05162810343296c8c774a21000f647973dd43615237b9f753c522d32aa6ce6742fa8c9b702b0a074ef8adbd17008226e7718c4c94255b01d7870cd5cfa3aadcb309612a7b0661ce1af202f7df92885a0f70886b8edec606b1923534c75f3cda19b156a2c90f6c412d33e2e0045b6a78aaa2fa991bf61417ce8f2c74a50aff9cdbcbeabab3e404799a8091e5ae1637933272b082d8abe7305173b0ebb619e4dc1dfc77015861c073e24de4dfc28e0fd95edf45cf540d7ecca1bd30cef47fb5e398c16e7f7e41ab35c932235464a91b3eafaecb1de97708a35c39730e58a39a2af7ac71959ece442e00d42e7c1f2885c49e5b799bec3d9735e1cdc85a4c3ea58b50524a51552f230525c834c705c1f1252f85433e42043d10bd5ceb42f8213d8e9db29924cdcd127f97778e75c1626b9fb68d6f0baac56d4cc30d0c03d80ac2f92b8ce2e15a7500b0710ffadc94c54a67a9b27c5531880a60491bfec5c78a7febed2c9b3e5c45474e156ad09e966e18f9f74ad2d60710c63e6ef36ffd478b8 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443021300906052b0e03021a05000414a695cf2db3cc4089154364865e1f75073a39e420 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = 856d1fe7642047ed19e96d364e5a2efa2c85a1041fb33b09dd59f038a4479b12c223a07c5b16d01367c58dbffa832e8bc8c4a5b4e8d55effd8cb6b50c2badf79fd277750d7bf80049249f4b1acd9e7316446213679df0d95355ad2e5aa0dbf493c61ec8a5f831e69a25cec33edc4209506f260b25a370e73fbed6c1ee5aa042b -S = 24b57099a2e8840bdcdb4461260aecd17534f76d074c765b9944bcddf9b31572c1494b586d0da7f93e7d25fcae44804562dd13ad676b61e70d19fec98cf6dd2eb917faff448e29b951a77b1017a8650d0061bd77742e04a44c79bec6ce141bd264824b6e553a3f761bf583e231f2152cac58f71dc7198e675e364103012aae9b45a3d1a7d61cc25cadcf7d061bf36a10599a812ec279a996a486d46984ff3c10bdd6a465b93eb1796639e499d865f38b4de2b14301d01a359f36017ace359ad1e3c8c223ed74b00c6a113288e64a9c610f5f06d537edb11f520bb4eeefd055cb3560fd8b4d56311c5546b07ba1f3fd0d3e105f3da24f3bae8ed44fbeb6512fb66cf155e3e61475436b95f196f452e612aa9890cdb48938b29b624094e36f651bd305700b39176273b54ec9abb996e644be39496d8b88aa26dc5d4bafc343b9850c0201e44fac6c1ac69c4e408ad5769bf58fae1b8a88c160c0d193a2c807375a4550c4cf56c947a9afd9498fc220a469affedecda22bf44a8f6f9bafcd913948 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = 590c04975accb7dda8c07afb60a7dec74d2ab36751b787c1068c6933a412f384266d871ba851d86f1417acbffd10e103cb19ae22196f2c655bc5152cc494cbe067b39c289c274460a53cb34791d511f76100001b6acd215cfa61d91c3e4655676305cb26fcf70396a45817f9e49d778c57072fb80b796d8c2b873d6bdbcf9802 -S = 8913d37eb20039be9bf34df63a3824f13f20324a3c2c2e7adc705f418c77d9be7f127e406d765501663b551e4482a177f58273483b51b3bb4614054ccca4a157eb6f4224b6c0b6e4e2b92d11b87fffb26237544c959125d2047165fc8dcc2d5766b6dd7d79abc37b79ea7bef2169e80e74237f5574494eff54b15f4ec7a5eed2e982a3b8d76b64801a37d888b079ac680b0833b51c2bb8a168c63cfb0a96a8817d8512fa4812eb457c1ed8ce0d563ea021a34e644e70689595a078ef469dea58a334207c6930a5ccd82307311ec25cc56807f2a9160b5d738acb42925acfbd4206bd92a24946e2a3fd8e04a1226e472be33eaaa5eed4c13eabca68ecef4d9c005b2f132eb827872235217622284833e339303162d866133a007e27e88af86b23c451a846eb393e05af713a59a929edd2943e6cff60aa906459c667595154747156c52c39bd369751a7a7f926bfb7e42bda447faa314a7593dfa4a06bc334ad9e52339917fc65598f06ff61ee6d7854325d40284e12505af8c57b857887f15d29 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = bbadf4bac5fa0abe2abf1e9993d33b798c5f7476dae4d6bb0e809be75a6da0b3a4ca1ad4d99e8423841adcfb9f1e0ee2a8ffb16cf888f15d513ecc0eb6e882127f4f4618ac433a137ade9a99340d37894c4b28f1aab0bc2f442bb356ef0cadd374c5e250e7f114d83495c23cfba69fb69ecc42cd98661f7810ceb686adde0a3d -S = 257d8b3a2fb7ca6d0a78adf2b6e11dc4865c63888422d0795773249865d18519033508be2811d797d564687827eed35cc4c24bddc548e7be68a14cea7e8e0a3a6ef801df2d41519dbc056fdf5cb23dc60a9b8e94581a8beda4f4e660f699ba5a649bd5724a1d48f88552c3129bd08e2ac8b0ef60ecb938d4039a2fdc648b6afadd04683b40f144e474b8a99b3a81fdc623391eaba2111dc5aa812e3fc6b9c8f8711e9986c0c2f012cc1a0120c79004eae424dc4c90f24c8f52d536dbb50a101ff04498887eab4d2bc76902c2587a3b32ef3a8a58c3cbd11a9dd14055da56e7ba011bae74875fa631a0dfa524fe396b6a5ba1b92730adf17b2e9bed78cde226ffbbbfe29d3add1c61262c0ac9624f1feec48aa73de41627514bebaf76997b0350ea4d590c6cb59252c9d693020e7887bebd7a25f1769433d39fcd3dd46625208be410d50ae16b4d8fa6554be3d94a848ffc3211a915453b45a3328b001a5b605d686129a4cf4862b5e3453ebc42c2a11fe180adf5c12d50d361128abb1555aba5 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003021300906052b0e03021a050004149a135a3d21fc0556fdd6fa7ab0a3b1e4ff330f9fefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = cb4029c463e243b9f901855447fa2af302441ee117a3622a359fb3ae8b356675d3cc97428f6b826b922831e7c3e458a91e357d2cfba45b5093198964c0935784041cf925cdfde7eef72e83ca9310fc3be75e73f1b5615d9bc16429fd8d68224267199694a50038eb30f9c3223fe8e05065a84a55ce4430b3c66adba07a1c9059 -S = 3f5e4b911aa319cfc15e4d6f7ee82b12a7bf827dfd244a5e57a52bfeb04bdb9e29a1cebdc4ebb2139906c42a5ea92a6737495d35d43ddeea1786420e57d994d880625f0c4f56594f80a732b549c65132355d56c8e7acc857344fc736a7b3168e8e892921c12c0cf8ae7a5d66a9d95d4180b1684ce3866024eeed217fe3d386380aab1530513aba18703fed501984820d8bb050229daf0467fdf13020094be24d8fa8cafb8a6774861b4a2a0e32373989fba555141d7113804b635c0ce480818ab755c87be02aecbd69754f68c3fea89dc854996a05fbd3d5f10cc7083f893297c63dc384a6376fcffc8cfb170ac7e0363489832e0c3e9b0400d928e05411408b7b12b653a1e4aaee79ee46fe892cc64fa21afa202c763b161b7d4f1c32e7bfc75442f1a3c31aede44374939b64c264f9b1833fe04172ccf818108f74634384bcf0208492fd81a77282a27987a9001754fc74690a021880b7f2324e65a084d88c3f4486fd974d50edf6c206ed616ed9376f1855a13b51c914c48b3bb0cce759de -SaltVal = 00 -Result = P - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = 58a1db581148b3b2a3f3c967d69d3feae7df5a327e122103dfb4276e640ca59b2b11cbc60c895888ce6e69589a958e51af92233658d6deb31b1aa4e53401a11d42f897e13f617634b5f22e182f57c150ee1f9c6aded527fdc96d9b30c9e3147b031ee7b2921a353fc246c0ae7f2bfe700d4f6cd8f959256a4f75b3550dfa253e -S = 3b93e9611a492f19acd725d92cddbe696e97f29c5612d7a1c57b7cfeb7c70bae57cb9c75b6c611bb1ba39e48dc99ba9ebc091d7ecb5124bee1596541ee337746c86c6280a2db0f434e13735148d39db23e594ceaacb36bc29fe005ba204bca2d90cdb083e9972b227aecc588f601427c8977ace25580481db532f580cfcd54f56169fc2f31cd00f22834cd4ee3c6d9c5f708a9d26e10e341771ce65ee4233184506a17f891cbb633fc4571d7dfcacb949523f692fd44f08cadfce02b6fc54bc156a684c9a706742d5b2d33f45b01001e777ff13f3b485c5da6778526e1f80bae0a812d80cb2bbe2fcab984754b3ae9532e24e9c930ecedf50cb554ad345655e25ad118f40e9c729efc53c67f8c9e533ed434d57c92ee71fa809aadc3c6c82aa4bfde5df4b1a32d43981b9019c04ab9b32129158d302f780c22cb47249a1f767861730c4702b8f599b594aafa691d423bab81e8de32ce7a6e988839a55a94c198c8b10e432ba10567e8a01d264a9f2964016ba1f070592abf8f1eaf25f5c06f39 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = ad65063815129120fbc5875461c916131cf2d47084800e5270475cbe620d7959fe345228c1995d9befbb2ccacd2042fe11f4257397f4b55c558abb289139c504513c32a1146a8937bf5d0fcadad398acfc549d4384168f0c8a1d6be016a68f768fc6cc2a764fbcfc54f355dcf0acbf25c65b6367b5af4569f848936e571c7eb8 -S = 2f264e0f5c24603eda9315230f23de193fe6ccece8de2d6b0ec8ead9803798b7c66b9ef0ba801b029c86bbb35a743031f5ceaf19881948cf8e2dfb52a4c7353de5844863a8a6ce407a0c88dde7f76f76b8a548930f902c974462299a9065a2a9c90b639bf017f77cb699b2c255bd18999757ab616b39cca6cdbdcf176a0057620c88bf0727133b3c5607ea13a454b45ed8d29178ea182f54329921677f7ad9b01ec3b0dac78dd82319f5b04d9e64da052fa5b193c32806a3dc6182d2bd2cfbd7741130b5d6d32ccebf48183d8b552186bbc8f6f6ddbcfeb3ac86579794bbdd51d9b231d4520b7aca40379570861f09338185e120850e989b9f708fecdae37c95507a46eef059bf7cec22a8728d03cdc7a758e85ed2c7d78b61caca723a4daa85bc6acb5e72c59fe1ab459e9d181aa2c3b0a8019f510156d76b0712678019980f2377d1ad7f126fb81762090a394a172513de39d388bc52903725f20d476724774ab0debb48e33fd03c7b48765cf91270245b42416b504c97c335400e36367c06 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00302d300d06096086480165030402040500041c1600b15747d006f8765132be06c17817a701f2b805bf6476a1dd5582efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = 0484eae59ee761e0cd361909a014b9bc1260356bdeb74440933a1503e9913d3f5630f5a0ddd882a02761f462d4b813de1324973f70cd9789ee7e447f56aad7c4ceadc840ad5541c58ea1d2f3a4c866594d7d76dce9727c5dec1bab9632b4dd459385cd8db86586992c7d1b82b64e9973e7f63a0befaedb02b598b01026b8370a -S = 74e96c2236f61bffc5830647a50f32a09b5170c586d38b83506c91f6337bed6aee942710a9288e17f8e9fa3e48ca99c23c8dec0f963f8a28c0a55db3d05fac86a67039a6c0be46d28207be9ec12e389bcea525386d4a0500d64a3d2b846cac4c5f9db7fe8a226e54e28e6524145680e8aec1b5d5f531e7cc5595e3f9973bf1b682574ba48bd42d55b240d2c9b6929b4a8fe8eb6493a2a7aea700c81dd8126c4f5cf2676adebfaf8641257d4281945ec771cdb4e45601ca20a19083e0844b8ecaba048ecfd2d76c24324f368f7c20563524271cbf5aa4239ac6259a3eef2c80e5f78ad3c7bddf786a090d7ac2f0b7e0fb5851c5017f9bb84001261038f79cad754d183662cef7676caa122fd0fb763944dd89de28f06fd40ad4721a02618b1a0e20056e265c8a2629fb57df29646df0ba56e94682bf3eba253a08fac1925d39561090d8f36c3b5068b26484e134cefaa7613898fb12c4a93122b7224771745ff115d4f70eef1e47c0a656ccec2d0afc46ed9d0fd5b29d151d23f59723d3818f1b -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = 469ce940f2675abe473f931292c7fb141eb1d11ab62fcb1065aafdcb80b7fd9ae647451e871dd85c2386291154443845cfcbfe23e7b00b08535e6eda300bd59b4aeaf53e97a22cb90400655b74e83d60069264c397f345538978e909c2fa1899f7efc2472add9efc71151199fa9d518b4c6ecaa0cfdfc1188f6237003d6e10bb -S = bb0257ed939f61ba105b2381a70acae35915a625a5728e29287bf0b1928e7c8a82d6b7ca4c1d35c6dc22b2c44895202f147390da4a1d3e64f416c03ced1f2523d586cf3b36046fb221efe1375fcc2d2ec9f1c0ed979e901573b2184385098a0fe27d9263ed6054410a3230f02b6258af4f183e82a4fe13597b5c805ad22536552b222c065627d4bdb929718bbfbc21cbd8e7d688a350ca2d36ed325c737af93df4993a9cc3be1d718cb092f48efcfdf21eb419de0666e3bad14abb09ec86890dd925c54b228b8efd5f491a5d52bbf508f15bd83e912569aeebdf9b570485df348e2cbc42395674aa69f3aeaf0c9573a27098253fb36f913b332f90466b18e2e78d8c504cf0eb835b5373e2113969f935b710013ba340292be2be396256d6c6559621fe96c1fab4b92e0908f71396b8dd2096ff1f2edf1ac6a31cb3b405e0ffd7c41b8edd1de01910cce15461176e4d2706665fab3cc1c9fa4e810e15b59d64e9a46588e0629d8cb16d60bebefdcfe58cd87c37c0e8497004bc42e29f024db067 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = 207fe949bf4eb76dec39e361e5153fc593b59d2d10607c306681e8bc9aa19bace993689d51eedafd53c11864f8810b281246c32cc43717f844438c0fe013797c3f3c68afeab8be870a979fb074f20c2fe2214e3b832d984fb788e87d13fc2e05ace2b0269294ad349a2540eb614f88038dac06045629465c46b9c2af3c46036e -S = 7fb366be277c3653fec8f65d741808e0e1676da31ea5388d2a87ff65d7e9dc032086be8b0f64642b937a8e0e563ab44b91e79003bd92713768b6caba087c973b351a340f3cafef865c6631da91e2eb55d9ebebd5d71c094ee8be88c43caa7c1f6a698070594d76d5b036ecdfbf0f7a9f680b56e6012230b1b91171d9fad3b8dc3c4ab88949acf036968169b9efd622cb52f485a2ed1bb6f65ed848761a67da1f67278a04891f663ce4bbab7f691b0ad1b8b4873e9bb4875d5627d581c262882f16d2c5f56e8614346934311408954b77f407272badffd3c2fadcb8a8a43441d612f6ba1d4ffbc00fdbf7fcc5ca0c9002c43f47f145ff0ffabb8c5760d4abdb6eaa01487555ff1ae4ffc632473a25831815f8e37b60cde1c85a537de9a75b5189fd5cdca65284165ee8d03082924feeea8cbeb72a1d5480fd2be13c4732f2f98ab7ffbb085c8f6c796993dc10b4c1187f32ecf2bb8bf592c3ae117be68a30e8c92d094e674a514fe9665643befd8e2c545a14e1b9f565eab37c3d913e18da9652 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff44302d300d06096086480165030402040500041c49c8f2542bf9c2bfd41d90d2ec3c717718ba9a1636f5ad048011cea9 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = dbbd09ff7b1c707c2bd52014adbb773ceb146aa72637c8724f5ac39fb5a5acc4e18bfe04be599e3ffe0f6186b870cfd2565527f5ae46a3d06f4bfcc7bf00317222e885959e03c6531da3d59e127b63f25ff9f94377d63b34bfeb6d893b4636df667da49a61427120503885450205bb05d0a9e879c70e1a0409df1dce709e4473 -S = 2e4d98c10e126e544d2b74bbcf0a4f03f081d4725a6661c0683d3612b01ddb2dd6f0391ef3679f39dc0785b37ac275f0d6841ed3a44ff7f6a407a085129a164faf63ff2aaed18ec6a5f7d27b48d017a50b24c8c4859ad2bb680ace5f3af57f2eac2d7337c0dd7403ffb2e8bac69dfdc98e62a07354b2fc93d03e499ee2d126647edaba094196b693e98cb98ad2817ba3f7f522c8f786b6ef82632ef5a00d5d4f42db6d26709909ca751aa8174037c924628852ce78e2829493d6c741d3558adcf713734697754e55e7b3bea0d8717da8aba2b2874527a0b3a8d2e1433344dd6bbaee1ebc7fa352539d94c6b45f915c6979b8e18be8934d28d770806c6ff893660dffd0e948a8cce11ac870507f88c1f86caa875ad721326dcb4f0d5ecc2d2538c4fabcc6c756ce4a59bcdafc44568787cf2bd9650486da8c85fd0b87794547e179e498cb6a5b26f71f9987d703f2d53418411c1f9a3a2e6705637b7bbda9660641c0eb037eb432b2d7515d1ffa99175cfdb8a2a4eed013b947faa4bf1c3cbd59 -SaltVal = 00 -Result = P - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = 4255d5da3223d2f6e33c43abecea1ea7926f7052eb96a203438efb73bef867723f3f77d88928a8bfa4aae8ef83ff569ae3fb4a4a769d951741e40a1d42e33d2d57188ac35bfa593892d1a13947caab78b34b19a12184269050472fc11919730851891782f1c06dcb745a75718174a4a9ca06e5413474ded6385f744789c19169 -S = 6fb009ed4d66f18ae694d6e383196b02f4d82a1c7a755ec4989af1e2f7381355a5cb0bd7b51e48de878c74c9a2b359deecc55ffe4e67c8de5666f7a23144a7a67cdfb0a62d0135d4f58c07fe467f044c1ed33afee03eec57f8a0f83b451f145f1eb598d3997b67d98b5d05a6b28d74eca249af0129ee680b9055704d803f32ce93d77fdd0455f5002fab33b30bdc0c8bccfc6834c9a260168b366ffa6f0421324b673d7e697cb266a09e03afb0ac6fe89495852a6e90d6e132b54eb0b899bfd3d9b4b84bd4ef4b4566beaf2884acd26a27c0241f820d6612fc8fe9c5f4810c6a6a32c924a7b532b63bea39c535aea33d50eb388d5efb7bdaab3864830c225c642353228cdf3e0edafe39bb7d9d9bf8143285b18ad2c941ffaa67bf4d91f94ee1abdc9e5ec6f141ea0df5a27490c51d0b75e5ba470c9e02f071063f89f7bc221170f8b67203ee6997029d53848868b8ed144651071b14eb96da6e2cdb9b9f6183f548d500270a20bb1cb2e12c4a43c5bdb3fb97b36ec02617248242e5a59dd7e7 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = 3a463bbff446f2b5057c50da18fcebff0f2c5be7e91e4144e91d88e2f486ea233cdab6ab1b10d15c4130fb85121d54564ab21f98e311c59b38381d6f6ad6ea56035ca67ad9567edc36fc9d8d3504ad206fbb9b5fd7549b3de3806d0ced3fdef0d8f59194f6c0ff1b2909bd5a4959fe44c66e58a58f8fcb14321cff224469cdd8 -S = 26502431034a0f2baeaf1cb7d8fa138b32d53f808d6183270dbcb24267c71564377a6d470ec42a02a7e88711c8c1e46a8b3868d15ac81146ad6c9ce9c40a1b09c8bada5020cc52d3ac2452a1b81c4ed0052a79c6e5cc275a032a816698e5f39004a340c13e52e9d672abaf2f5e230dd9f5a40eb250e8743a46414961d347a8828d5c1eb290fbad7eff81c7204bf377b9d9f4f8a2067cba6a6b7a088491cf42eaa8b201b5d8b37033d6db81454faea89417d52dc4b50ed920ad1e863f083e1f6dba595661adfea362d0e7c8b10a55fc58a1202fd222b4354c320dfa1e466e49625bc0c80dd620ba3cc2027ada7177ce44483f5dc8caadb3ff7d812524835f402e0d691e0be9bbac2bdd0dc6881e85b0ef46962b8441c89f7eb2a2d14bde8d2ff933dcc0db390f225f2322544bb95b34c2c2e59e6823f56c048508be7a3011a3130983185b47305477b19f3c701ff3009342c19dc22bea62b4bd2ed221ae9c2213b3026a576f8e25d72f9c72468e61b6cfd9530ccc1c183e101df9aa3228e8ce3a -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003031300d060960864801650304020105000420d65f865a519cd429cc9d221cdce15d51363697e694b2cd6c09987f0310b5e8d8efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = 631b9db77357d87e004b61ebda972db826db2b9f03c913136d7f5e2f601395ec406fcf96785f768162e849f867dca77667ab0a195a7cd253387c44e31776d20393a59ce373c638578a70aeccdaa8c78100b188f4cc21f99a2f3a2bd25a76781c24640d86acb3a668408c99517e261641b994ad199fe1104f185e1be6713b119e -S = b3fc32b58ff28bdb60d7080dbd90e369d5b6ac8567f9953a3155e42ad86f671134b77d5f00cf1b686708da2dbcafd637b0e1c9dca59ee74b1bbdc339aac119661a2a1f3f837271a67c5788bf309f77752c4d62ddddbec71bf7b066acfd08b96d840cf4aec4c52eff42bb85038d78d668466458dc7d69621206ee831726f28e49a8a389789d39733abd67fa334c4ea1a39081bd1c086dea0a091e8eecb06d413799f88711084310c30cc824fc8f48d0a3ebdf481123a30a5535ef0c8649ff42746441bcdf3a7ffc23cc13c5aa75b2fd8a413b0cfe1388cf724cc105c182615902f91caacdc7617e349a553738d5a329445c710787cb08b87332a91ef8fa1ecc4f86a7c56d6ddbeb3397d2f92d2f325d29fefce33954a6620e3bee73411f11a152418c5cb6f37e0305530bf510589f2918204584a9126a3372fd7f915070bdba48e54c596d8693a9d18f848bd5a53982e8c8c33fcb3959ccf4a56d3b942917673aaa9246a5baff5f5aeca056287cebd950968308d535b1a62a5aed92d95d9d6c2c -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = 50af2bdc908dfa76ea44c19958ba61f2deaf29e663434a30bfb98acc157a3c14635d6f2a57256695654c482f16ff193ea369e9e1c2344baec04d0999d0e81617a3c5c48438b137c2f64f1a24f818908aa8a16ecd8f1ca75d6b22082882b025be376f93b3db385745c5d79f3fa50fb01e15df207171044586e9bfed42d4d84f51 -S = 6b3f7aa014e45d369cf4cbfa86fd284af19ceaa355a00f55bf242f02094135e899529b0c64538ec409b60b6c9666f8dcc61fd6060c990954f8200cf6a477e8a114633fd8c9a62c0e8d1d171ccb5e09d360d42d868edc0bc0750338da5ab69f53ebd8f9ee99c55d9e1cf6bc9e9a8d10db7cc267adf5e525af09568c7d6ce2f59ce8c5be5562f2ba88d561f1d46dc3aa765b3a3a2f5f156177d5de5e959f2beaeacc2b265fe5f7f3638db14a97d673489faf35be8579071a09e46f48967d46e251a7bbf460fde2528e36709b5b4e13a51ee53423bd4059f38a1e3dd2720dd9c037fb6ee048ecded10e5d7c199fc3b2ea4404110e5a283b4feab8048487984c6972ced45ea31b1d262f0b071ddc146f4db71cf43b56ff887679ce39e9a6a3e449b04f3d6bab80ac393abb472dbab9ad52eea3b936ff414b9eda99d710e7c836c86a60755b65cbc0135b71f87fa96897c708cdb69d6c6d6d4ca5fa850fb6ad9b2c0eb5483b3641f211b2bee68ef6e1b32188099e7752d6776168adf7f0667f7b2017 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443031300d060960864801650304020105000420e4a129a7ddccb2047e91b87062a92c5672bd3bf6238b5d2ba1175f37f458790d -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = 5c78db3e64375eb7325e70272bd431c10a71e34acb58f215c987313123ac67e1633a0a4c62bd4a76666b526f8efbcacb70baa05100db08f8b40ec10fe5559abb791336a6bf660cf69ab7b17ce2905a2e07ad9dd8f755770e42eb93657cc0c9e3e42be6b342dcab1d166d18b6ee3aead418736245796f4841bd43309cb194fc40 -S = d3bf9e41c55375a032394a403ebe35dc800541f87ef67f9de42b9a386b7ed0f78403eadca167e2f49c5332cef85c2bd821511c721ff4b3bc3fcece51bb10921838384da4af0c40c1031617067656cba8eb2d2b7f1744ecdfab6874038163a97cd08439aad0b8f959364a0cb0154a9606289909a1a6a486030abd1dcbbfc113ac34bace0b84f1b7f9cccba5dbecdd1932f7993966f5ced9187692d03b8dfd99f87c2903d72bd7c0acbb942c6f1f321d43a357a21f6fb6b78f91b92346ec2e577cb8aaf9e7affd12ee3d27ec9dafe50b5cc874c374d2e2c1bdcb22f1b6105035c393e4f8f23660e2d54795757a0d1729ac12e053aeb239b7368eb991278f3a0c2f72c551cb90b96cd86905389582641d6c029c6622b2f7db133191966901d83dabdc5e634f6c8ae59aa54e6c0c2db7a1f573b825102777fc8961be82a624e5ce01244ae8279794fa5ab2fd62590ad8a00c5d0b0ad11a0154d9bbc2cf129514bf193c715e49cc75bcf8343ea017906dcab061658083ae11fe7247ec95ba18cca761 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = 275a91aa97dae189c61fd1b7854d49899d9406d958a8401143718a853103f90683d088b3a71cbb13dfb2836144d662270a7acf0f05b5dcf56c701640de63ad73a240d5ff332d6b5cfc78dc57608643aefd0dd1da3283722cded7ad1b6b5eccdd0c103e3442f4398ba5d9a441e1473345ffb5d4e3e6fc4add210c17bee2dea06b -S = 270c4cf3272ae89db2b9b2be30ef1167d1b8b67307e40f97c81c3c9ced0924ac971d669e6c0b35ece58b5d4d4fcb4fda5776f81e99db9f8ea4ec5d65ec960f2feb0a4166019e5bf856246952a9a68567703e505dcee51df9827c51dfe6b13eb6038eba7cc3f3443f0ef6f28ed06fcf272255ccfb31f3a956a36744b878af8eee1eaf0e3ff1277ae602f6b3c1940697d41a5acfbe1bed9abdf73f7882c36647f2f8566d3d5eb24ff8758ca4ee72405c4f9645a2b176ee0dceeed37e8decfe2a3894d6d2118cdb7295593837e2ef96335066dc899a44dccc93ae1aa1a6d2548d074be21170e3cd6c73555bfc3a95897ac9a4766573008ea7559a08c3ad3c21bcdc32e4dbc7c5982f279b036bf790ad0beb6b129d22d834bbd74a204d5d60bf39a3fb4ae819b772dba0ada94a45a5fd7ecc79cafa31dba6762b5b51ee95c0651b63309004923b77c010d4b6b3df457aa0b0e5507c3d804fae26b0c384c1a34d1bdc998005226e81f2b9fae100776f5e3e410f53da6898e20cebdbcdbde9efa1acbb -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003041300d0609608648016503040202050004307f87c39e3367aae5759a4d5de9ef2ce5f95692c59fe337dc4087aa11be86c01655406490b00224111fab085cb688bac2efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = 88af470625e6b5be3358cf6a8698a5655ef321838f044746df83bc55b05e8529df0b120aeb1c7b3a5a1409705879f887a22a7b78a2f30186db5fb7b888cd4e8c80c6feea5d8ecb57ddf9076b8980188594947bbd0533091a19b87906e2f727fe3589138ec3652d7d86b0d0455fd78cc5fdda283a00ebe76c5e370b25060498e7 -S = 879c4df9b66227ce30e6403b620a488c72329b400ec67667a600bcfe3d0ea893f3051c8076eee81e0fece30c4153552ae2b2c774888657adb5300bedaf4940d6d6ce9310a476093b3590fca889e8ead464809be4da3370c21784e4740453df999bb9f7c290ea16e4b0e4ca666ddf23c757474fa9b0dbef769b1876e1eb553ee3a1c14c201c101164d5d1e5f628a7ebaf65c0f0f27f239ff67a4fe659d347cf50921b5859d79d86f8bfd2a25eabfcf76eb606b4151516c482c74ca3e54ede03e99086e61c0708e8ad9c94c1fe3640bf811f4e2c0e62d17d593f2e86adfd0798f04616adf9367b0f77f40de77135301debb490bfc76ba710878ddf91651a5fa025c348b6066a49853d6ece7bc79cdcd8ae709a77b96701c1ba9c4a91663e3790bad5c5c48017fcfd005a1b03d47d07dd3c511aefeb4c766dd19e377d2d82329a222b18ee0899e166cfb37c0b1b3226123f80a33c096fa4ba784719c4d9e52e60ccddb6da8575e705a36dbee7d97093f830283c71abbbb85c06daa913f96dede4ce -SaltVal = 00 -Result = P - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = 78c938a5628ba2973c2b793348ae3857f599e83bb26c930c026cfcd7d3a58da90c3091f565b2a3357b2566d424db774cffbfa08c50df4f9c0b2746832f6f936955b9c3f989b353095884677d2ac4be68d3cce6756431ac86478bd79a8b7b16f47cec367a7798985bfccee3f40573f6f5964821bf966a9411dd1f17e48ecffc93 -S = 4009022b370d46f9b15af306f177d7aacf5949bb58b68c05680eed83ef5b35b29c53f781ec1910006c4a7756d1c0e67ae52e7599f691352ad5c052dd6fa7f33121841869f1df1884489b18f4fcaf4b790f6818549b26f2c764acdea5113427c0aa6f0d0c3c688f10e572adb610240ca1397a96964861a562625f1a55c2d369017585136aa6f473c368d64f8ee85eb21aea3de696e3a258890c458b1434936f48c5725b6c81de0d2f9019a4ab27724526f64f6ed1e1dc09f1d828c1d6a1cb4c593d4e554e714bf55ef5fa2915eed46497215957abfe3c92fc06dfd73add5c2046a97b50c4d2366a4ff6c03ec4ea2e916f58240744456cf57df158a7a4c3c0bfa9cee2fe72ebc2d792a99aedfcb7070841a691abaed83bd55df0408a8555e8c58c0023d2000dd7589f9e3b5e5fc9f6448f47e870ca13755408fae7eaa16e2dfd4d41b4de4099b5e224222a520b87784b2679dcd66cfa94077b9c5756190bd25d13fb40015f1bdbb73526ab6467d0eb1aaa458f38adfd539a109eed0fc253af8e8c -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = b82dc25af8993613cd5f5e6e851dad20d155f1d2831f3278971addde70a82283655b9aab7caa2db075e933990b78d9ed763ac6ca3448ff3109e708a445b84df3452fc0533c46c2b0347347444fd7356953b80eab6531cf22152818ff9b818c6460917b79c1d6bfbc0fe5e398daa38b3a6fb80fa09f416af2c2c55316fc6ba97f -S = 03ebbcc4ce14c87345290d77a652ddb0a27143e11278b4083cc33a70e4395dab1dcc8468f483e6b8fc461e31e1d5331fda53e5ea595950888d05203b06316f7e5bbec3a2a3ba3d8917e56a657d04c0a8a8aa123119facdd323114f9a1ae78ff5d9295b4bb244443a4e3ada7c00985e74de8b295dc898ecd6c891331cd458a040edf8e8d2d9aafbfbad55f111265723bf9b04636f211d853be40c9119850c2905bf665cae93968363e82794faabcb02a2f1ea1414ff05c63c3f32832e7d786809603b41776554c973560e69c3d37eb295be53c5b9a9769dad97f4a99d15e11c5268e10387b1ba13b198165f78423b61e2c203de534f9e331c004bdf85d1413896d4deb83a8bcf8a09c26f43725ae9a1f0f6ebbba092803e498a9fa5e3d15042964596817ba275fcfc89cace5b0b566afa19fc3897223b2eedb48d1d5259aa576f3248ef1647e6c3bcd5d3f88f5894be8006147a4595d416404f2de4724080bfbdc5dd58262ca15f1987b09a80a2a38c8594e1d2307fb99c1336f85e7c0cbc8ce0 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = 18201d59ba48bd77abd33ec87a68c1bf5ab93b471aab100857b7e4e6f08fadcbba050da77529e0b5ffb211ffc8a0b124861f4a592aad70ae127f9a938021309a4b5ee57ed45f47653c179462d4ded03ed55b147852a8298a6ab1566ec2dd756133f14ce7bf311b0fcac872f886694594b03742ac7ae26224c813bf819e0ba5a8 -S = a07673ffcd2d28c4dc9ee2f91ab9b1f7f59aba09779102f5832409a3ce9d9193ebb54fc122018602ecf9d52a0e29c137e7a4430253faf49ce6a5f25b7eb7245e2dc01aa870f0061cd7857a6f58e765fccd06ca7f35cd796aa016bc0198583f86ab714a044e68c4827f5ecde03f9c9843f3fd5c8448bd039b5ac70a6bec0048155a11e55f60edd315a560c5410210be96baab0056f0ef9404333d068af9a814b5e8be1ebcbb1cc746080fa7b3a09e200426188b14488cfcb564a8327eea01c0c1a1681552fc23cf516f600e596ff6bf44489f07db4167c02028eb6295c769fcab30df726aec31af2cef6a26deb01a918e6dcbe6bc16fbd21092a28418598e958b99d7db0157674ac564e03ec10bd6a59d5a87435259b5d74ecafa3c0209a6c20edb7e874f6db5fb83019dfa7820584aebbf93740849b5e63985b707e891ffcebf0c45f827933808d2a7374cee25694ce9a714f433017540c996c0b169a284a5b1b2d31c954ababb6f75d7dd060408e74bb09cb9be1288a9b52127fabdc2de942f -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = 6c49d5bc93d861ac46788e3c93d6e815966b90248f46ec89370c9db0553db1bd8cb81a2e77825fbbf8c39281cc11826063f131a2ef9b89ddbcfe4a1abf0447367117d289dee475c6f85fe32232072db94a6b392d66ed719063c6b8846a4aa2a0c46de416ef870993f1546767ec3f52e6f3e08f0e1cc30b6ad66bcd357d962ac3 -S = c35cc19c52d8727b0e9945942208234a2c4ba3f4d4accaf9b54fe161b5b92537838d74a94c0aed70e58e99cdafbab8d6b968f57d3af6b7a49d8592a4b381635f7ceeb25c4efa0cf8d6cd6c2e8b751143f11ec50956db690802fa0ee40640badc70ded68345255b54a97dae73b340e10af6f546dfd395d3434b775c6dfe29058d6c3b9531e968091f8e80f9f4a82439890f7435622b3fda11eda964dbc5c94f2eb7b66ac1e17b6e4bbb5a77870e8f03af62920e64ec059e6fd037574f31636800f53e506570f5352c99f04985337819cf47e8cc54ac38667e3406597f66025d05e2269a77b347f02129b510f38f898a7a79a71dc6126d3db62dc3dfe5faf7e917cff2fd6aaccec49eaa0e8a35b4bee78ca043ab2f860155ac2ecf3cb7564d8fcfc913653f6392fc03a675884062217f23543d1030704a733d077969d9181ec555c0f3808ec7d6bb7873787c296782a8c3d374039ed636037e2aea56cd230baccb692fe46cb84efcebeec031801ec10ea4fece8940ca6e4228bf5aa40206efddb8 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443041300d0609608648016503040202050004300ba6737418933139584032033536d357a432e5e4b816eea001f2b4d47dc04550e24f47ea3060631bca744f42b3cf9675 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = 08845a6647884ae71378c1ea0ebb9cac11159eb121cc08089e0a6ad0be83b8fb3a57a052473a1bb9c8d243b5c260642b10a3556b58fa096c3dc86159d61c444d5f92f25c2f7495d2ea251abff8c03eb336fcecc6eb53c6dbfd630226659477ece0fbf78ae77ee0b9e239ee10992153cbebe70acac22068dd46a2f43e5131785f -S = 06771fb5a09539491074d33f227cda5a26e630075870b00e84c0fbf47c98e60a986d5441ec0ed557c7b02db2394951b61d3ac76a94fc87b21ae77c082bfc0271c321a77ea020900fbcb7ce8ed40016279b7462df2da6e32ce0975c3a5d05cb03dd0e97b533f3bbaa352d579a2bf2d47fb72568f2a0e06a514bd1b3475db260f0fd040626fd8681914a28d49e6566855f02ee2eaa5e1e3e277e00e677c60c87083fa88785d48f7970fbf5e835e0b2bdecc61df27ea9fc7cf3f510cb234d25405c4f9078139bc85b92bd0e8905be80380188d61d699a7c7db0e087932c2cadcc6991a34dc2a6f9c2e9b659dd1527c51d6c41fdf23b5a14f5d8f0c3ed2f28c08223ce4450ca5e896a2ffd0f490cf2495956eb0257246afeece291b8ba7c373caff9eb52ab90462069d20e3b09f1e874dadeb2cbb599d2be0eea434f70f2d26ada7812f58b7edf20ca299ec53762943c628ee31891c26f69eab3242cf0d90ef1607ed56c19ff5af4d4be35334cc013b47aa087935a855dc1ff62ac5be945978d8913 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003051300d0609608648016503040203050004404cfedf114d5b9205c1c8fa9a8d73b55d82c17feaeadcf7da87eb11bc021a4b55a0c0e4e232dbafcccc1423db05e8a917b5d86dd9854d2f9081c5cf7744d882e2efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = b2f46df8613ade16f5efaf19cd04d7ab3a99c804e0cdf66160d493b1344a9d91dac61b7a34b3a4392f5b20a0a345d37c7ac197c715c1681eebea267573eb9709450eac967c0c05ca5e26b6fa3f714c15a2720bd6a2ea7a3d90f3223fde4c92bd3bf2a6b300f009b2cb77f99069314a5efad3ae9a4ff233a697170d793b159695 -S = a411a40f0b95e8a447e09914a31ab52842583a1a90479435bea0bd20104c6423ec3ca53a42e8803d172996237e35e59952d32ad3484fcec66fb8ace07034928ed162d287125963099eec4b1f59dc835a1ca02a658771a64e20a5d4e2c83770a11438b1956bca7c586595f8cdd28f90a033b22a27f10dfd6a3de68ae283b0af9b9fb3fae6963b9177ab6bd03b7ccef9e482c3c6cfb50434212c341afadcbb8c62ec4b63758c2ff5c4ea4e6625f8ebe1b51dadfc902c572d7786ff0acc39b82a3b3dd14ecaece9db85dde3d4f13cf7cfcfecbc5de471316585541a19270c3ac94aed43087b5c03e8da4f5ce3ab7cb10567d57fc2564e2df03143cad78a797bbdbe86e9d5d64f9cc9f9e46a288bafcca13edfabd4c1914884d6984447873d033a8164346b34405c8c0c84e1ee88d480d3bfda3aa075007d7647ee8581bfdf91912df7572bb8ebc9ae22f8dfb308e983788fdf835e415e883a401cf23a426da1b21de4d904b5d52bafa91b969f36811e829d8bafe39ed4d78e2f30c2e60038d96a95 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443051300d0609608648016503040203050004409f24b226f1c31a5ced2822ae473ff80616c976eeaf6ca63f2ffdcf92238baaf570822977f1c37aa3b53a03a0ae95c82b8de631b9bbbd0a6bb6623d9b8ef18d0e -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = 68f05fb0d353897bd65d75d3b54f34199bb8e5803b8f78c5b87fb71ac282866303b169a4b95b48baa4546f4a228fd9f899efaed9155b0a2a321100423d3cdfc596c8b31b58750f203c2a0a1dbb8d88f873d0bba7cccde9eadb566f3a87c606fceadc45fbfaca671568884f35c86ec981f30213d4a90f9c6e7bf70beae8498371 -S = e7c726b4bc65c98e0468e9e20bd38fde581f0975031c56bc8a1b149724bc313442436f6b0742aa96fef392f24f4c6e78c6afcb17a9a70a686c3091a0a746f6e427023877c5080ec23d50c2c8ed063b5d435ba3cadfb0786cc0fbec7d4b834e45ba3d4ba19101beb4cd0851cd66dac7dbe6028a5a27873b81580ef817c0cec52dcc99e5d0a48400109525813c9c087b403fff944c08febb645d36d0635c817d543d319cb0625fdc8e098cbd64b67c1981da87a4550d6bbc49d074fadff82f56332679baf1861b9f09ceeb8d18351dc7565af1e4729dbfb265056baf28ddd980dbdf512e9d86faa6acaeea1744f6437e30a9ea6faafffd6a813e255215bc1ef3e3a6d2879c763dacba1af4e657a7aa19e11143da902ee567fcf6ed9bad15f952e7087d1befe7bcef6a9f14fb7d7cbe9e06ff583ea888b27a0781c1e1c46dbabd14d5688f25cab383b05c79dd4f500bd2be7c647cab0b12c123a0257cda1f0dab31d42f70b53adc07765e583a146ecde0f37fde7c0f93e72cdc56e734577be3cd1a -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = 98ccc6f8347973189f124ecceb360f429f1aa6f850ce712175c2b24a7688403d06db7d26b3e187f4bbadb302220837f7017126eb2162a2cbc8d54dfed3070048057cc0ef9f43ed1d317bbd86af16e94ac7dda61d72b4d7a5ca2081231b067f563cb6779d20270c5ba884559fbbe88e0599670ed76c4d797821aa3703750e252f -S = 039f309c9e084736e33c0be61eda376c5ab9759a0ef9e47f9fe17ae52cc6bf878cc2bc6bc3dbd9986f9f1b971a5eea3377a919922aeca340d63fc414376aea9670aba138a831f75b4bc63ff3b1964a6d732988e6d801f4bffde8b36fe629e57ff3f6d6ca425a8b7d23f6f66d647aad60e60819cf00afea8003bc56ae59de98a4f0e87ce92f4a12e3641a7b4c9dc53027659f0257c3ec7e013e8396b5a006ea8b1fea2eb25132618f75f5903640bcafba9f511338fc234e1f000cfccee896194d0182347e979afa5b03402690f959329ec567bad325172c913b4575c1c46722828a99e9a304f016eb615664a43ad1bdb26e99e429c2cda4926c9005af24de69861850b6a0908347b2e72474df05c775b7cfb2360df99dfafbed216844931117462497b51e40b6b634863eb5043f001b6d3b15e61f00de1d9f012fb774933f502089a213ad2eb89cd150b46895405f087c5c93d7a9fb55bce4a2d93505d81f2966ecc6e0386c1957451d014892087d978422c612d226c9dbdad48a3aafe50bec47 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = 112b7aa9fec5c7ac703a49c298c4e29586083296f79b099e6ec422d586840ed486d36e06362d6554f14d4d01fc39a9d2167e5b7350bd18161f66185db0c4127a7b3a67951bcc9e6d5de010439746e4f43b773e65ab1ab4234fcd024be621fea819e6ce1c56aa5841db7cfa4f11f67b411c7a4233b0bbc60f267f4668cfa4baa6 -S = aa3ee99d39ad0332ca48deeb68b5966962018906f1e2e97d0d711df66e600fc875faf8da141212ea9bc49b2934f19bcb26f819b3633381b23f74f0c1d486c8fed6f6c17cacaac222e55c8c534ca2cb3921ca6f0cc19d045fa5456b4ffbc496d0d3079f19d93bba5600048b783a905abc3f30fe4b33b057a203b5f9d01254bdeb02896cc11b713fdca55e3ecc67e243fddf19130e2f3c79bd984558feef0fe877e071b0a13323e700de83244e2bcc09a602eaa06bb39d832d58e30450dcd96b30052778c07d4b209d5929bb6cc80800c95963a24bea449189301b50b5f26a899739dd0a4af6eba05e7e625c96cabda3beb2e4b0d11ccf72252b2d524d76a104a6dcef635517d78f248c78837422ac900557e1671958116500c673e2fc9a08e40d4eff8d44146f43fcc5f4086d276ba026e9953425a11b7be0036ddba0648f12424c3359cd8db8a0490b1bab3b35d3550840b4937ad1986aadedab74fcab27fec7561ae2bbcbb16d28d173efdf049fa8a1daae66db51f4c03fc91d1cda85d2cddc -SaltVal = 00 -Result = P - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 078ad6bde08572c73c5e94bdf0f1efd12da3a8fe7c035027236acd3e4ea86edd1bddd92ca601d012b7aa4e4e543caccdb49f54e35ecac7ee8b03b522a1b09957fe3ebc4d42dd96dcd4f9f2e215dba47749c9ec7369ec21571b21af638ac6f05d45980c4af0c1e6db2f70dcd738a803cb9cee7dffc3e7a735ec6c2541b270cc6b0225ef71939220f9ef35cf5c5b0dc291e237bd456333d803d12883e0694b2e891a3248ca36b838a8de27e154624fea5149857214b15ac4b4d67e0ab944ff5000552c66f833239f3d4c27a76cb14dd181d3f52a12cb4f3f9518dcb68c9db923e677d6f733febc93152c311880205a5b73ef323c07b87cd55549156b0452656f0f11a2c430924f426a22117c04dea477588fe092bbad1a4bf2a0a7b6befcffa3f91f4d308ff24515dae15897e9ab00bf755f9a366057b66f095573a9f881bc48e3711de800b3c0155c976957c40eab8834c7b7911d426fd7484e895fc8d8bb5ef7b562da7a846fd6bd013cef55ff3b11de43fe6da0c90b59dba4bb060ce4caf3cd -Msg = 7f1b83830b4da729242205b0e519b5243d32442d45f5a933d1b57bc54616613cabcdc99b02a7ddbad8cdb2a41b46c33d2cbd9f283585dee7bdda5944796a9bf06514926b14ef8a23448e5de0b682e35f3d21b03d1486ff1874d9e9f066d1dbd3d77646b9ea2c98ad92ed6c2d5fd6fdd498e5e1368b01f40c213a9291b553092b -S = c8e55b1b1ace23e606465dc81f6a349ad61d2b8a1afed31215ee6a0c8214c5366a2ce18cb649c4bcccde5ef2bf4af51f093049d1ecfa5f5b639f7ec62d5a4cbc505d0f11bae2c16d8d6a61a4f1f9613be25d66fcba03a7c405204cc816414a296787e5a1462d12fab51a829bf13dec500da689520ddddc305152021337a86b676545f8202c5f936d9cadeda41a111b65d9174488419dd19da5d3960b6f59281bb2e90b4c12891a1d5800d0b0a932bbc95639b130dc7d03402322f7cc7e06020d5124023b049c61cc6e88b345d0a395c80f1f04b7760f0c526537f4d4c515696253361a0eb03c3c5bf567cee736f63572c85db1c7e5d016ff19c0e1d38caf0f7569dc00e3c4301be9baed19d45aaa90ab7204c2c70191926ebac319caa27f55e5e68b57ba4a70dc153d750e318099c85359f1ebe70686f4bbaf9b9f6de3459cd8c4a7bcf8e559eb7c68790a67b0951554d9fed9b5c396f44860ec61cf0446cfa8061b19c72a34b62be8f34736fbf14fe556ad57aea605c60adbdee4d3fafc5af8 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -n = f33d3234f13272c3b2b6821ce4805663ff2e8b0d2a47de363d97fc9cc879cc6b40f9e53aea695dc538a0d2b558498829aac327eacbcd889e172b34f90745c5d528b7e82605f1a58fd228ec7fd4b6f476f393864f48dc47097c8a780a2ecc02f748138dbd7df99c52d822a2e5154c6047fb0eeb4f49da38edcae3c32d3fde435f291f96cad1e09e1030ad7efb4944b69e074d0d7964becb3cb86238d8d293bef3030d141d14868bc21fa133e9de1115f749991cf86ef506e663ac162b2c8567ff131a6b467a6f564d6c588860becbd88970354198ecdd4f1f4baee8f8bdaf7255835385f5673625f113550b123628a0be3994d91c3a19a82e5d73448dabf684ee6794fba7a2b1afbee0287e5a11180c29ce0896795d52ac7f408fe28e8e9116fe0b61a1083f95c5227d62d5537b5040b79e21b3a8e83c225bf3efebb2f808541e97d28a2468359fc60f588e74faad611262064628a25d8d61f9d03d8b21cca515595aaf2343a759b74a6a8afeffca139a389aa281995cd18e16a9cf7b7ff0dddb - -p = f3fcc6aae575312778d9e896acfd7c1aa4c5524f20453e8bab255363164afa7124b2425587a077fa0bfaf61b12ef3f0540dc4c9e777122a60610a53d1d75b0a5859c654a8ddfc2ff4860758bf5a6f264bf8bc2baa7551eb7be23bc06978be992fc81d890e07a3abf95d20eee3f6bbbc089985cac96395b473b2741c66bd2ccbef228432f66b906c15b19694dd786c29f06cbc17b2e6400dde4e3db85819382b3d05a4c3009f092d40d05ed5b2e0428a214e15a7aca09b47120b9ea6cb4084fcd - -q = ff36fcdc519fe10c69aa0dde2cf3bc72cf2ce9a54ac063d809b523f4e5d7ddaa5413d500dc21f409ce661bf33018b748fba3966d874bf96f4313eafea9decfba71d540ae0508161a3658c4762d94ebb3a4e228c45661315db30c20fbd9e20e24c044e4f0b49e6ec80949b16e0ab07f3d32b248b39f48332cc3686df05d29c170a7276acdd129259aaf018ae3afb49b6e0ddb9e404a492863daee7be71dfb11279047794e45f399a9665796d32d5e65956a13a6fbe992b36bf4c842f5f519ac47 - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = 3330bc3d3eda995522e8849c7e8bb5f3f6e895b3d7238156febdca74f62100f26079707698c6eb1d9530c971119a2e95ea7a8cc3c9e869f901f563eeba3d714b4ec06b18f3edcd749b00b88a188e39c0845ece31e07b265efb872920955238e2c5acb60c9877c7c2fb0057cfdb8f5fdc8a3c63e6650540efb41e24f3d188de1d -S = 5949a5007545d28832b13c6c0a453447eff95e2dcff9e403db83bba0379abed6d503394befaedefe578be085622fa73ab8f63af52eb91dded8a0456df41651cabccfd34250b813b57dcc4535edbe0901196724c0842b951ebf3ab469faaa51fb22e5574696dbb57614892d21a889224f6bb0da4b81b8fce60499b8802b36f1576780e298d87b71dd5496128b0c8fbd3f1994385c8029b720cde1317db984e02c0ee77cafca705d4be54fbca18c4f5ddf85eaeab784002c8d1fdf5e3794d94c5c6c781e9c05eee22e4c1556d9f8f6215b23d5c687ddb79af29a280a4cd6be95542709f423d918d9147c2c501d3f6121e942fbeedbe70dafaf76819842d651df018959e586e8ac4325a5e616c3e6474e1640d259c55474366761156aabd0d144a6437e7584bf33089ead0610f9ce10dbe39fa93ecc7665082d64aac474432689758cdb092757a53ee5b9b4eb3f6ec3589074248ee547c6fd203fe5bbf217974f1e2e398dd4d1909e85146d7e1dcf74ed9478ebd414268bef406228ef21c80ed1e4 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = cb67ebf8f8adde0c2b0640db1f4668ef866c27606577504abb7b777e63f3f8783b593c9286f437778ff235d990b6d767d17358f914fa150e31d04d79fe842557713fef44099dabcf69bbce2b479243278483b05f9c32fab441980bfb4354d3f2b3428c78484f43fd018c94370c81b516e7c3b6fbc5c9062533fb3a6bfb0c0a31 -S = 5e8e0eda2fd7477143e33826c1f37f1091e766874f8d9717ada2754610aee94c5bdbcf939e710a2d5bdce1329aaab8eee0a33ea8d93ac243e80a61f09fe31dad8eb291525dfda5110148a9041551c4673db5edb4d3e457e2ac8834bfe600ad9e210a9dbd238f8811552a5a6de7ac23e7ead2746cce7358e7b0fe27af32e204bf292e7be24536a1df8e10712bce78d0d94331de7095e9f56760d7e9e3534b0a8bb30357e2948e2e649c489e916abb399541067f778a21505e0ce4e43e3a64c30fcb8a22c575b2f63868b151e7c0865a52884008477d78aedec9b950bca5ffa93dee9c7b8234a054b61d2898a4fdafb1cd2008635ff56744d0419cee15477f544caf2b264dff93c2ef060fbc7e062ea29d80bec0e74287d9e2c0adba92b5592c4339776bef5cda132c83f296810833cc99119aaa31849ddcf62bf16c45f7654f04ac4eac75102e9c5b79738e7d405caa63dd917f3f199d132169192397198c67551ea78339ae376502e7e4ab23e5626c766fba9916ecd20d15fd63c75e4a927ec8 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = fc57235b4d597f5a5380a07aaf7ac6074b17d75ee4b504ffc6fcaae4d7cb7611d771cd6de6216bd047a04a5d6341c5121113fd9d14597c71e53a181ab4ba1acda9e9a0446f5a40c9f3d7ee9069532049912030f6386301fa01c4e573656abecaf9266489efee476ce08e56bac99a1fd553a7371057badcc2a101d999f4c1aa30 -S = 5b53b1a1fbbb8a28bc715cd607a699caa795fcff045e660e102b6c51e0daf25a9cc0d0639c1bbcbb9805904cf16ea3bc26c18f58a3702f39a3c1cbc5e6dac954d65d102e0c44345704844af1b8e3f15b7dad532192e35e27a335bb67dd3367c828b7eac524e1fa3a1db556c0c3180487ce197cef59ef05025d0e0c7dfb87fd9da457d15688434f5165f16205a8400849118de58b6380b807a6600c698b2553979c7e0b83ca200433c5b5a6155eb6b37ccd8d584f695a93e2b1a3f933e3a0997c18ec63c6e90c54f87bc48b8057be5eea9131d8acd848843fb3aea56882c414258478548a7806de7db039d97c5c440d8a99923cfd7c3718046fb16bfe53dfd157be94edc1ce944fd5770c38247d78927947c06d113759f4134c841323b3679b0e1b4537335d4a16aa2ddb01fb1735b8f8d0b0107ae714fbf727ac74572d355da37b997b9a424735f535232ddacd026814799d86b91b7701753fe1952651e991a1b8357f43ea06c043ca1cd57fdec28ddbe011554bc04dbbf3cecd03710d454bfd -SaltVal = 00 -Result = P - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = 6449afe8eb08b35e4411a1bdf1eab7d7cf0d5813f83b1063e714d376dde5852e84c1c054d2d3d18b31f20382dd76216e8d4a36b8554397f2cbb023106933cad532cf4c8b984143f79e94648c3af002dffdb3d35bf5c2f736d32236a349c28a4ab69bddf505fb138cd21e4b43cfff6212676db966a1613916468f9498463bcd75 -S = aa36dfbe785a437cd2c92b11941827bb4884157fdcae8331de98ab8d3294ce8425e719b3b0e54eb27d7a46e9729ce18044880a18261d28d6c10641818d7dd47c421d748c984597cfcfca821f8c3294da53d16c1af99135f750294709b92755a3f5051e033ce3f6df055a77c628ca952511a33b2a1e6ebdae047d9c7589c8689e9ab16747dd4788d023315e6c98f2f060f3bcb655d487afccef512d929da03e0e4d7ecc2b7715ca61cbad3f8fd8f4383391014f14fb414cf49347ac60c01b713b6dad9e09e60b927b261aa5877a1d5b0e76906d40bc77cfb41405b93a3c93fc2ac12aa08e44b577980e2ffdbce606aee14533c8161c85ce8e4493a8c1aa03f708c6a4f84d44f9d147082c1d6d0c8498e109d4e26406ddaeaafb9409cb2cf249a6308d3d8d7bedbb8133d542513d9c4424a3609e81066dece42a7a115279af0155e3596058a4e22f6876cd931f1e4e5ae5800ca96eca88a3c04b789ca1c843fa9730b4c050e269f9f101a48c5c1df7e5770f5a823e1e29dcb47367153a17bff1ec -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003021300906052b0e03021a05000414c2f234adf6d0986f254e79e3e89264f7681cdb65efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = 6d16916bed6c4e35c76fcf5ba043724e7404bb147d12534057ac512261c1b93b660242f37d3c5d8f2de5725dd5f56d314bf77915c45f0b3df41e23397674cf6e6d05f0c76c3040a8939c9424fb135f6f55947896cda31d6d35e437c95fe8dff0ca47224e81ef016a41bbbc18da4851efd7043ffd61878fba6127153be5c6f4a8 -S = b08db35d788332d2bdeb8e89c371858710b0664e464f9b726c92ffa837387e7ff14a885cc776b1ec4763da1c7120c5da133c3dc01de44c93fae6a9e13c3542f5ac6ea44f3ac9892a5b775a535b4723777a43240af123ef78bb1c1d6788098fd148a764290a559ff2637af485d280bed6e1b289e518aee6cbe842b3feedd158c409d13a5f117c8db853bab5b564e43a06a83f4d2748cd718bdb8fe41f5fcdf9f0104dd8125fddb401e8b5ddcad388007c3c86c0e4502c94e67b0d194002f5464d22ca2ec65af465abbd44bf90e3b578a9884b86728fe22705a9ab24549d4c168eb7b3f1c6f6b07a55c3a8347b392e0eb50ae985a7e3eef4cbfe060692b45c6671597c59947d056b9452b2030529705a6793547d75d67298182087193f608163f3599464ab3ffe82539e202679b84df75ad7effd5985b9e08a88d3977dc978b748a9bece9e08b42b88ec6a766989aa03c1ff73445706035cb50fbf01f89c9855784912dc7b911cadacb0fac987e7f5bab76d9658ff84755c70225a4e42bdc84feb -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = 724265b54dd8716ecca57175e3182d40c4ef7a1f0d9e0fc240f095fc75f0fdc64b0a1687246e5f9392b51af10cc7a161e6fcfd9d8081b5e0bdfee4a5b6758eb1b06e34534c51a6ebfe1319a9c0147997084801daf7960835d37d1eceb7fd573589b5e7a22d49ef7ef806972568c95deb121cad5ddba3b1c96bb76a00df50005a -S = b2f503ef1d4b84ee0abdcf78640f1f82de00b2f5fefd803e1322a3e09e617750884b4d6d7e8aa741c93e9b36dae70647c3fae398161729f2f8962f9985157ff7fd7de42d8ae7579602fec0f91d0350a8bb38fb54234d806f3251eb6ee2a3806e3fa846a7add80f0d2dd2fe9977265f5ada5012f739bd3f06925d7b8ce869851bbd5897b819c71effe7a611b1105e68a3edc5b70cede299548e9116841ff1ee624ce0d8d477a18c723ac05c756084f4e7cbfe851db1e044ea175c8603f90a4ea87421e79565b8ad247c9885a41af0a2d1032f2807b731f574d54b6c82af900b0a1815b4e30513c7033e67a1c78329dff1a4542bf28aa5ea78de037bcbd7a9e0740693f71586d2dde6df39a979dc55335854d656a8a4f123b4414504b1a3f3f0f5e7d12ab700d24b9f34df58eccf2371d9e8429f5f206122b3663f99ba02929e8f46aaf061845f793ba8bc7e4de8621bf2d1df9a1ae2fc130a478437c10d2bbd51207dc07af35c88c5807c92b739d3b5a689250ecf86bf1bcc8e3b5238d2884073 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443021300906052b0e03021a050004143ea74de96d5511a9072c9cb0dab7868fc0c87e3d -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = a6185cf668fe6bcd1a872da768424d95f6d52792a0342c580617887948aa03aa0e862562cce09ea44400e5184cf51e61d18841ab1c6e798354c2caec44b2f7af5f78a3f2018cb60cf817029843ab27c81932b3fd2e258e9431ff960299f08623a1d51ccf91687baf40b4ce4ed7cd2e73d7bdc6af5ec13432a6b633e2cece77af -S = a31dc7740083a5c5b17c2b4549d4ff97405b2de7a5d878ba927fe7cba62de764685a23f65cdfbe9d0ae2060434443f8b18d8032e7d7b952428dab81cd158ea3946d17c28d1bb160e6e8da0be12489206cc1c57670da9277e53ffd10a3a4883796d9389e2a361e335efe34e91d6d12e78f606a7e79fa3afc7640396d72cf34cf39150e7784110ba4c703d34747ce050c0d679ef7b1e72cc9e049e4ec583b9aae258d08560e74ba41d4917d8f41c1d4a3b8f04bb76c99b36f738619e6c3b977f716f1229da7d54287c0209403ceb35e98e77cc37499b7c2127254ddec1826d8ed6fb83ffa13e4727ad2329d6c85df002025b0639399a050bc2ee13ef43d4b5cf25a36cc0c9fa27c2e2523093dc48a2b1f66aab351965866459f6c4bb59827cdef8058311a81713c011f8f77f819c906be90fc9e09b6c5cd8ded0da32a30e756ac1fc26282af539dba2398ab21a254067fa338479714fa3b37fd7d7e6032e6b9e5cd31f23972b1aedc53778ceb8a39d3b2b3337e694be843e35dcfc310b09f560f0 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = f5df0f6986dd3e9cf4c243af92a6a69fba85406eb7944318e2d47ac80ce7d24c1c231ac6f9e507a5ab277bd4bd550631e55dae41e706eb22b682f6c1dc46434d1d194ceb576b91abade9ddbae44ecada0d7c871065cbd99c79a1602e8e431c573fea303e681ae594432ff1cad139fa817c095642fa8c156f74584179e8856454 -S = aa1f614775143e046d4ab4d317f2a69a319e82f91dd4e9e3cde226c5ff87bca2093afefa76890fd8a2cefe38c96aa94dfe9efe7e3975425f77bc6b4b13f2c84e8ee80aa7ebd95683a95ae0255f0923faecce58b02c6dc9ac9336801fd0a768d6df0a0b705d8e1402fb8f769ed32f8cb890be42b86a1035d73f01ff6757bd02a7e99449a5849f0f2d0003ef53773a0b13cc07e53a81a7914892238ef798faad7660f9caea94abc282870714d1e9bf7d29840f0beea5cf4addb6bda8b441db30dd43e207249577db9af55c674cc58ba2cefaf1a4fb03ee766f45dc46aacd12c7cc5508371db63f2b971e6842819a33b3535a1592787bdb0544317f88cfd63e43dcc987472cfbafdaa5923b3737165f979ebfb647d86f6d2a8dd5137484225164b19f063fca9cc72f516b2402983f7e5a643f8cb299870166b04177daeb90ea978e957d5f7a918063253d7144f589019c7691c6198f830b86d9c8a97af6d530d0c1126b377d5f450ee9eebe33a9b135774624f575caa08871c549f2d074552ca2b6 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = e3fc380f53d94344f864766b7f1ca420e59f430ff31d120a080bff5a181c4753f56ddf2ccdff130df46b6d68e4d1d88d83120579a43f0eefcf5159cb451ac0923f7bee4d77d80c98e9c99ef6db12a7671bd6143d8807572bd321539f87187851478e2f1c574a780e5fe6d1bb6bc75bd635533802a75d37e59ce4b37ee7feb8b9 -S = 6556cf98dad966f1c91e0fc492d74f52a7896d1901409047bc630f4b4e97044cb9f142e6560467aab4d65a302d856f72c15332873e0a8b646b3c70bfa8d522c50906c240289741e5e9d11f77a640b7d96707c959d130355fb2a2fd65af4bef7f05ef9496f630f79139d90556a970e1110d12ef10a1b7e74e6dcf7a39ae299ef8649c06d745104ca65b82b52eaa0f00f936525065221a690a65afd7699d93c70405403cc13a72d944dcc0efcd431604aa638515033cfb499207de58a798a22c047d18dc825abead4848c7f521eb1ddb2a10af5fd7bbdf9eca83fea139f6a015b614d7126652a302786850f400c05c2945de31cdbf0ae83c3e39c80a1860d233f17e5925a211b1a35e1e7bd72cc1785f9674f858b43759542809a3d9e241d29a62519424c8215815e0e85bd1374ef99ec64f08b3e84e3a6c04918462098329c97d8522aae23e3d5511d6489a1155774916946e7e0e10979905c5cb603561fb6004dcfc30ad2b6817272be904e928c4951eded095e75a5f7726f255b01a85211bf4 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = 167c1cf3b93548a9248cba2d5024da528f9a23bbcdb883a915ec051157f8adf268eaa3e54a4f95f6aea456b2b70dcb81014a0736e2e6b5e5efb1b6f4c2710c75fbd5f7b385aa5d0b1b516ffe0a718a8438e95ba26509473eb1010a335e999ea1d8235e86f2ae6b93737d4f38d1b8e0023c606726de88025e62c347f3b3d92a1b -S = 674ee4315853c10823b2d0da2e4b13b6125b9ab7ec5458fa09139ae74dd16b83f88a75bbff1b7d70a3d099d12c6a84661dc4097ddf5b569a5f3d1ff4de4b595dfc0a6726d1e6d1962af78a94ed73fd2104fcedafb61097f8753b5e8420e17e284179e7fbd16d3ca50ed0a66c5c2ea1e412f3f758ec18f6fc07e69164f71a8a1d779365a5042f5ab514005937da2b92b5120b62590134888134176f5cafbbb4a98f08c4e2d581e0ad9deb2caa666f36d4ee13e3be6a31861e4609479dcd4796b9064e7164aa7569230baba4fdcda388bff7d2c52645e9d4331c76cd2726eaa7039078fc0f74a47882bc0a47ffbb43e284d6dc4532e94f4bafa5e17d8dd2f108cb2f3b206e06eacd8a901a6e1f7c82ea45959c3de898560678aaa052ea9d9217e97b2a30de1cf6649fccac679f15317423078edf88af05080b679a581be29a76d8cc20ea7d33ec576ae8aef7d58c1b3126f6efa0941434b6dea5c0ffe8f404f1d37cacc3c5e853ad269a18bbc19720cd214eccc813d95ec62a0f083d2d0e66224e -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff44302d300d06096086480165030402040500041c20f660487ee230a6692b24f4eab6705e71f3b31197c1b445b5986def -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = 2524a5d692240e9c82d0d620a0b7a08c3f71ee679bd78a676174268672363f57e469479b4ae6021036883189fce06e43b82a5777927fee2c404c404fcd024505990f0840a20e0791013add3db8291e92aab7837beb4047533a12d0f7cc21921f4cfd31ee1f02e5c7ecce23635cf97a201e00bb9c2f815c8358ae1ea5f8fcee4c -S = b7ef6a53edc10ca9d6a16678c2cc38ee3859dfec0ed0012c788c5981fe2a1d04103acb6179c176d9f9003eb86db354fd504107c7921608e131cb3d4642ea87c0be3e91e7e85943e7ba650db959eeee710b0cec5817990de252244e95aafae943b9828f11da0e490d11b5990ca2d3254095f3ffc0defc38e5d9d87e3088a84d002844b8fb7231cc7d69539bcefa4eb345168529a12cbf866a76bc1f46c112b25099f91290222b839ba7167e8bb99a001d139e18a231c6fd5c7ddde5a0799b2885f8d32b77b620fa555d43bcfa1cdb897e53d8786f7fa2a734cf881994fd8b71148a3b96791c18d28fb6e39e9acea7e61a03b3367a1eed28c15ffed710389c6b047ac5cecc30cf4a9b0ac2648204c72ba48a7957e7190e4d34bd8a55e3e488e61cc64f1130d81f5a182d480fe032aa7f7302ab386eac8666c2213b103872564c11ac0e63f1b9a2946f3e185a0815e4ee2aab57a592344afb8568d70979e62077d5256fed2aa02d800ebadd4d9b26d7ec7ef0b3edf89d2fadbeed40f35b54897f49 -SaltVal = 00 -Result = P - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = 93af2807782787ccbdda1f2d60e56c455c5ef40f152fcfd7f62466ee59427ba2a75b6a6dc0dfae6d9df5a61434ca99219b29f9cf714de44c7af3f06c89b3289fa38f522161cd7470960296033270c8396691679009f49d173b48272648b75b4ccf7569892398e1bdf12a7561237c017505bec8b9a6cd0020824c92825df61b91 -S = c0aff8cf59e543109654e1bd05a2fac0a13782cf26cff6978a07e72b6aa64ab84dba40836ec1504a83a51374e32f09dee79845cda7aa9fb6c75a9bde61616addd9bef949f55d5a638615e3947c64fe8d8a85bb54ef6e71090b7c84812da8d4af8929c1964f27820435a587318c148f9221fdb4b63ce7f43c22a0e840bdfc56ec1205fbc5735158a1a6624869e4ca791d95b2fa01b1e1434709014549f4c0998a0574c6711d1a4295b653317db362f151b371a851535601de3d66d03c24fcce8116c1242e523a074754231f3c70e9e2985a5228021fd6389823a48b5aa2a70febcd61aec23fe98f6a9f305d588289c6e3f2522b6c28a94bdb27bc81b44a39a0b826572ea40a9772b9e3aff50106bd77b2a5ccaa1b901eee1d8ea6e037f7815110fefaf2cba69c55f7035d2771b095ce38d13553798c400e2f7d407fd0b3dcdb38d8592c4edfc5e5cece6aff1be8de3769a3269fc2a99d1ecc98c0ffae39313c1827b81d361074f9d1919829e23e20d0f2e361417b35da1eee8849899ed2f199fe -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00302d300d06096086480165030402040500041c9cf324cc0a040165d93508d7218c029560c75dc71785fa64343930ecefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = 38f06d35930bdafb5aa674262c796b395036f3a54103e9e26a2ebabd2e1c81f42b836f00c0d97032cc0d0b01b9748aa3ba065cda50cab711138f82a7afdd718b2d2b7209745248e30f4275a430f45e31f5a0aaa1eb2feb4ed1f3802c9e96ba5ac5503df7b75da937a9af7ab698e02d0c8b6aa5a1191accc32ac27df5022fa28a -S = 0ea93bb8e9b4639bc999e044c328e9991b5986dec71937465695d5ede0a28d5f152cd19cee3794ce1391a2cef186a92a789e46f70d7ab5e38d0d02ada5a9bcb558ab77fc06ab08db51d159cd9648a49cdd7239748ca02eea81e3e08758cc4054e279e1a98d77a2cb9ff77649c84e843f02d61b98ab73788da32b8fbd9e7d0338089ff2697341e4fee7cc72b73093e098b361a76eb0d56072b9bd04aeb05eae4c918027dc6f3c12607c504031d54e456af36be5c711b544bcba137fe415e96c25d5931a4524bff801bcd5f771370d42157ab1304c201ab6654dfa4f5f933aef840b74feedf08a3c8d74ca4de6fe562950bb7e5c3d901a3eebe1bfb2c6b6ec24b44535bd0f89b6ba7ff65378a65781ccc5243a9578f74f90f894447c49d240d6e118e92ebfcd8079326174b55291ecf57bf39813df3651f690eb1c5d8056b8bd50cbac145e909138c37a6844a5b624da4be9d13a988a5c43e2b49d11f035a92a098a59071b26231b024c1f6fad1920c2059cb53838215c6be939b2db31ba595ad3 -SaltVal = 00 -Result = P - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = 49da6ae32f9149781533adb07e035a916ad270052b7ee57f74b931e1b30b4b9ea01ad51b162a935c23e022dc5b4be7bc71254520085513d7c6b94d3aaa230956a0a1ad4d530260f94395bed31734d01334813b198e70b70cbe06c3c1566098de71f65b3f8e2196989edbe95c5bc6fddedc71bab766d6ba678627fd3f5ccade7e -S = 1273aec2765d853e0dbc6819df05d3c008cf12a14078d0398ad1c833340e8aa656e463f170324879d99e14a10f67e29b5b09b9dbe71e93b298c61db9c47426064dc5a95d250cb06fdd9d3258a6112180a390df3a82aefabbe5c3083e0978725da87104c50d9e831d24ad9545f3c11eade633638589e04685f671e68a6ece18c856521d91d4d74fda95879ee39a45ac139416472c3a5ba6fa17d744745da2a7a5ca1b2d38e813d2058f7fa54a2787e464a9764b11f7421f6fcabbf982f4046b4d4ef7f0e86caf038265c0f1711b2ce4ddcc5a70b8f77337fa219c1068f15f8533d99e9773313159f04f746d629129f03e517280d3c41f304e531cb8ab3e6c5a097700e9f890026274cf9deb9e80836636b3dfb2133d24cbd7c5174e89ac5e28dc2523b13b4e1031913e172eca410c3ac3cac74734b45f8448a531aca430f0d00d3bfbaede84d9c4220ea88017edea356d19e30678ea5f82ea7537192f10489ff50e40eed9f4f78075a37613df24d5da59fd075f1a45cc9d7a61a2ef8274c0e7ff -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = a455b7d1b3b32ef7daa94505fe97b16726745409dfadbfc9df30f52ce7c3714fee9b6b217b2a58d05338b0815435f344a1ceee47ffbe3b4a7fe707525ea117a229520de7243fe8b3eda1cb2c5dfcff06afac3aaee4c022c8650c0ddceb7a0b4c9ca1268a7799e887f10d1e6fe091dc939936c1a7555c7c2ddac88f3157f75337 -S = b92a17bc07f74204ac547672fd12d01df6888ed332d1453aa423e504c11c4828e500edb7ccf8071f1f98c4b68a7fdbe665a3b82fec5acbde24a0be40bace89bcb59d4f9b83323e6f3cd0656cf9334974b02d437155d6d37a02de832a8356a88f83cce253b4bce850d9c5e00e89a6bfe1ef7215d64b68a259b8f25fab901f5e6f9f0a8b508c554f2b1162ba358fa5270c6ded1e36af3f47c3558523eb1c3c7d6373e4679324481300e8af1737ee62b840001659678987017d2212c4387dd16105dd81f77b40357f607a7d5bd6ce07f7ee5d7ac4cd6d0df5136751d438000b26e4d36585ccb743102fadb674251a870396a3c0c91f6df33af415c196f7de0746d2060b28b456bad9b0c81d22a58f2e9ce06371b5d40a8eb1d0fb98a1610fb734e9fdd48fc553b08dc13dab29328cc3ba552557e2bc4c245c247cc7549a03bd2b616c01e98b04ea835d0f02c6d13939f62264d28aeadce370df07e722057254aa312f0abcfd306431d880330fed7d76337f58eca8a24bf3860a8c758a6df39d95e9 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = d262295e4f40d1ddaecf5fcd56af7b80625a4cd83c64a3ad6d02766fb3ca910d54b98815b37af01c21e5ce60f5c750acdfe1bb7c7933a5621f7a64a801f7c637767203b7947feff8fd007491fbeb40c7d04dbbb0478f3c988ff87ca349744bb4e094818e19d53839eb2538a890a3b398dca733bbce02d0166587a6a7b4ca864c -S = b27d86aba157581c706913aefc77e7ac3c9d4946c646a6f7ff78d4c1c19d0488637c010dff274cedf37014fe1c89d29018daab58b5aada55fbc35cc973290d3f4a7e7c61f78fb3216793d087adbcda38d963fea102b4240a09cdd433086248173f201171ae10014b0c785b5c374c0fc2a38e021f98d78954aefe53244d01cff67b7991ba28dbb1127f21ebba54440d31f5ab3bfa6be1b7d6696445e47f071232be25b08da70ac8ec00603910f9706d6f3692de55d1e646cc7c34a4887cd692e69db28e00a5de8c8d2a618e351f7714c59ebc419231e36d6debba2d3a054ecfb9bf6268e6507aa96823acd635f6d31b6d716ae10425c9661a0a8b7b8797d2d90d27336faa572a13b33dffb81918b42c70c28f0ae88ffc923120cc50ee8f5d9025f71936b606bf44b8d1f26dce76b1b13f2b6c3c5903407e846fce2dc7e3d7fbfd00693e4c25dd96ede4e29473d8edb7532b729010df0aa73d81386c470af3326fb3bdbae500965c0bcc7697e92f8cffc14ea29e5021b56d4f78a668c72a57bf86 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = c9e861253ff04d978781a7a45099445db4fbacba1c821e905eb6d4bd299d87a5a3d436e350dd243836bb20c73fbc0885de9790ebf5b640eef7d5bc304acc4878efa98b606402934dc98a1aa443e1083b9eb1390e36f67f34179deb11635148ccf492e9034307a5be88151fa223b04b683b712d8da5e9e44a0736e8c63dd3908b -S = af1a58738c5900de8d3be297fcd89458a2c11b90532dbf31acb6a4bb1ef2141e866637bd59e7af286f396bffa1fb46e13c2ddf0591df51a8ec29691c03d734ba37727421806cca1650cf172cbca3c60876992af88037e6e43902eca5c2c91ba7cf8a408adcb5545bb4151f05a31db4bfb17978aaba5b5bc626c07880f52c47f2f53d60b5197f4374695ded18f18dea635940740a3c5aee8caa9f01ce9fb02ee9bb66743fab75e63e2233089302044085c5e0ddb723aa142e0ba9f30abeb47782655d980dd7869caf0ca65b25958395dbff5fbac082141bc6cec4f032c60e973e0a6b1421f5126b5ecaf92f4873077dcca2d90b492ecfecb1fd76512ad2726f9c036206bc34deab19dd39182b8616eda9f97745f2e09432ae55ddd6ec683bd366e45668dffad941e7458e01afda6e3a232fb715799975cd9d81130d73f834300f2657112d57d661ea7705e912854676e50c43ace1093ba5bf579627e97e2539d6b0fe53741541487f89c2fac52fc97dd4dfe0b58c9637cbbd84011a80adeb3789 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443031300d060960864801650304020105000420bd0a68c45ca3504eff3fd99a411e4930d50450c1dfaf869af04bbec14d10a9c0 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = b44a3b7de7c8b57126fa95ae13853b28a221ce78d84d2330d242e06b0825e1a8d380dad82df33eb5b82760560304d90008242940f987a1363c888034b40f5c884209c3958b152329fc80e70a0c74e3d2c16cf2fd76ebdd41db6e7f1e3d9f27b508cb3edd8a962a74f9ee71f3b83d2245d6e371dad8e3a1f7b8dc27502d3c0cd8 -S = 7f0b8969669053c26cb0051e0c182fa688375ed6afdd39f7982d88bdf8d422e9c9ce4ab5d1f63a18db785031d17a3286d7cc1349d1ebfd764522cab0962fcb1e071394d00b4595231e8fb7db6d10e659ce8158ebe78e7ea60818d0276a2645cf2dea02d12e9447652259dd12a93936cf2cc0259d03fac70ccf47c99dd8e0b5cc9f90916a961e9b16f9e80b51dfdb38a6efefdb5e2dbd7359a292b89d8aed8868b7e9fc444a262a04a331894a57ef0eb2be8ecf79c6481fa8bee709bbfe6cdcebf04325e98ea156e82a4cb87afd1d69eca37f4dca02c319c3f83f65cb12aad441f8cb92e48ae789626b3662158148a61d8bad4b265df2fdb03730b947f5e542d9ef319e271fa27e598d39c9e6b645b610f96836ddc5523263a98f901f9b47e3046fe324702732a62206fcaf7373df7d987d236574b8b66bff55518ee403ed9e9763e366c26bf3ae47c8f1be461bcc6dedf549b3ea7d5649b5d7bbcbcbbbbeeda04218b861044f3115b684cd82a71be509345ffef5d5326071c4c63d119e86ff38 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003031300d060960864801650304020105000420e3b41f283a3ef951ad52a3dd58c46db1518442328f512485699894018fa1ab54efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = 0d0547eee5ac01f37f29f03aadcfa560adbd5b02b5182d23cf9787cde745dbfb228295b7724b508068bc4aee49d3159963779036a1b916035e59f566778c22d0a4fc2be808116ce6066f863c57c00d7c59b38176aa4480a0f63f39bc0dff24b4397cf1c9ce85beec02498c6cff1cf4d23778160af842d3c3404f3c17d227496f -S = 8b3380702deaf0e22ef08ca6c3c9e68616de1359a1cfd5f03968148a837f11f15474046c6434aa2a69005855ca945556c04ec3b57daccb2605683474eeae4fffeb19c221ee5c61b54b0914dc0ae7253d72e6d73b669f52651ff2d25e513e565d3648e6d5eeee63891ace75b924a2143dda487d8076174784165b105663719273ea6b42209ec456bf1f433b117e02e6a5bb35e285618cabebf49a8fbdf046b05bbd37020dece2afd1f6c9bd2fc804ba09bdb0d8aa7af0de45b7ff616d051106f6727415a460a62983817e373474666dcc8260a3ebfd59341f01990e6d8b7d15092c3d7dedc2d4190d75374d138bb414610834d48c9bc23c43d1ea96c7e9294a2d803c26a427e4a2b5f86f19bc7d10da9aaee219291c94d7a3052211f6c5b739168e544747b8090705a63671df1ba7a82d8cc5e76b5475acae66455fe377cf52156549d7431191573f60ffdd24d6640610f4515e3801a526d49fefc2d1b59456e3337485cab9955afada0ad5e33deba6944d98b24c24731acc54b78ea1cd2808fa -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = 9802b7acc01de6de29215e2878ea1ddec20fefe95963e56ce5c203a7b60a391b586795ee68d4b692a7de84a24dab1e0ca03c1475c4efd7d9d5486d7233f069dc1dfe1b768276040b130f8cb29d3af8f2965f962af66a3a304886ee390028e6f90f50b20bb50cb792963de021119d91d8cd01ddd094dcf8ba6505efc2c4ba96ba -S = 99e39af2014f011fbb413ec25a428af8ee4bf6f2adb3fd20964d551ad8355c46cdfe35c955cff611d299f533852288ad20b901d80e048ca80eb3cacd83e638e15953413e3018076e91b1064b2c0d615c8bd6b9098f7e3b6da919470636135b926c97124e943e987355c6d71d683136c8fa9698f15c0ed3abf9ab7f03f5e565f1f1b1b056d7d1ecbbd1d7afc5a45bce19984c8ff9a92437d832f89f0cfc5700d18482c4d63376fdbb851ba2a1f272df06718faaba2e9e1c8ee1bd3a3aca58a02aad3437f89fbfbea5f12b8ebc336b8dc942058c80e099c60ed6ca6ce128faec8343aede16c44ea97e1ac1073e24f5499772b8abdad9c8c33922bcdac1068715c74f4822b4e9109a8020270997db56299052f14132a1d7b19820e380ea74a68236de72be5d33f4e89c5fed4ca643f6ed7a3f505aad27a22b6ff694597c883896fffba2ef4fe81cf44cfe342ed6fa127cf31c58a16a5a35919cf2cc3adb47c6c84f660bd9e2dcc4b8b29beaef329affd4b5cff2c59cebaf3648624485c4cf94e9ec -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003041300d060960864801650304020205000430825058944465183ce7f88365fe96cbadd70cebade9f1469771f0a1bb5ef6e86c4e3e35d2a34393aad10183ead0436783efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = b438d4fd3a46058f4eecae06d9bf1d43c54eb5ebb504446bf350903aa902335e55f9a93277fba8668ce4af474003e241e0c115a20e8327a0b8d2919e4bba3eab236f9e4c4737f67b5383faefb55f9d9e1c0d28812eed89977aa1ee2cad6d935b08e4d8d211c197d58913b4869f9df663637c15107d0a14571f03d06d38e6da76 -S = efe705f492c2f05595143b7d2fede01de8d4ed8aa6730d5db7540d9353bdce15cad57eef7e66e98a0fc3d34e223be094c5f60dedb8c89f5c3e4f6b10f5d41415e098741bcd4324558655b215217582daebfd44d2154748a707d2219f68a1e9d97a75900329dfc0d7a28b1929775bd37fb66524945b6b86635dba4f2e7a95da17301a1522effe0728edf148e7007810ad509d8d541e6520b83247052e9e79a84746f11f469eb4db1446f5dce3519f09d8b4f154b0f3c403d23a37e89aa68683027b76fcbdf373496216aeda698b2fb8785e364bf2bd2449277c0d8420ceb2c157f8663a35c02f1c4a4aa86c7753ed755e60c022a4bb3106da295f3a2a72f2c861c619b8726f1749b9bae639589b72e9e34eb9176608f2a38daee1329de2f28291216b8c77a7409eb5c1d7e351e906f1f25a26c6df4abf3038658f7cdcfa3e1fd611efb4cc6c5167c4f76e2100d02612e12d2e696c80ce977e7a150e477ae0b67af577a62a6b57e6bfb9ce19f56979008076c73f018e5479de5c69bf1ebf5aca53 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = fc06f66ce9cb46deaf65f79666dcfa90b09d1e2fecd7e2caac268767696f6ac6760b91a233278433836a5ef780d923b26df854b4eb32c15a707b9fd7f634da34f04fad9682b36fc0f1e2b0d859d9846e9e381fbaa4a2a225c367350c756056c0521b70d13f38b08ce21314c259a4c5cb2ba3a6cb7eef2d348b30728c50bb8571 -S = 6106401f71a67b9b68fedb23595f45492fc7eec4557a00a5638aae54d3854dbd87d2f66eb94cea8c02f466a85983a37fd202ccad8892eee14e3301fc132c530b36b31383739ed7a51433e90cb7ccf1c17a0a512d249e70a3d51b7dda16680946872856e5901c726d3bf2af49fc264c3c6a373d9135e802a8ca37ba891c9e13c21dea83ddd6c55c25867872e18c0a726d5fe6dd3d6ddddfa0cff7246a63dd38cbd738945afbb3be72c55cc2ef38f56d596619970312d93a9322098601193d1dd537e1041b46e8ab5d67b40a069b4153d365742a32ff81defb4fd00782695b81b124959d33c29e88a1d911c4da17dc32d41c1b5f1836ae1654d56feb9a55a488a2a97a92ddfd9c754713309f661739cb2baef671bf41a3e74452690e0131bd3a3675316d296d696b0f07a50516897043a5b2f090bbb618d822245f5fa5aa7125551aa988ffb289e8804bd5149cc8ff372496a5071ae7f8583a8755effea0c6599116ae5b8a3f94ef2f4e6d440c9304d6a091ebf14fcd8700ad5367a21e6e8105ed -SaltVal = 00 -Result = P - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = c2fd970b5b17cd1a58dc8423f1354f7feb5fc86a609c7b59c229ff8e1d6f66e99c7dd8014fb67a732bc7947a53ddf4c096148d743832649df595adae436a305ad820f2a96c1c124cc0aff12edf45954ba3df50c57cc39c346d714a3e57dadc697acd2f2c39b25d4c1d7ae1661dd6fcc71da75884b4b6ecc832a61f68e22730bd -S = 861383c21c18f931fc4fb352d846e725e39cc117c4324952344cd007b6a00ccf08fc79048545fab5c30fb356460d5af25a63f83871dea84d464ce4179cbe5e6fd09a384c45ad046101a9460238eb3f445e8911970cb9c43d096f70b78f3434cca05cbf8ee861f6bb6cee9e123a24cbf6ebc5021d3a9a55c7ff08c6bb274a7736f34fa7c04029c246f2c70751e51a4607484ec87e816a3a5c92c06a10f512709fc4365a7c80941109b1cba4dd7ee79d4c3f851a32763807425e5b7583d49e97f337f270e6387f99dd21d62c9db52406d3376a5e549782625813634a8fd237e7ac477355f4be7e05e2a9c3cde9ede554026ffe1ac3e8f545a4d49ad39c2aee4b52c45440983f25c276ed58ea5fac719c5332655113dd768d93311cb6dbff54357f40c23b4bb9c20c7bf0525150e71e17e486eaec90d2263c9758447bc02739a14cb7c3e60cf376b9326a861951d6d38ee291e59219757a9de264cfdbd4b4601b8413161b927daff25504e0361f6669af8cea75f35969c910c3c5e1890597931164 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = cf28960fc5ef7fd91e051ca12516ba961ce953d48492fb3598e97a6a1b3a3b4b533e656c564a47f184c7f9a355e240435584b31e6c851ce1631d21afa49b24714159676d38ef741bf6a7bc3319317e0b7a98ea206b7587f23d63d21606b22886a060e53bf544cefe7a8dac7bfa6b3a97950c410308ca02112fa3d4c7c8e90e33 -S = defe54ece1df4a9e2f9b2ec712b2047be979113674458c3e1409777a8c568bf43b4455fd4197ab42fc514e3595cec0d46f3302cf556889820e1c9cfd38c642ea09adefa815727b6c06b2a194e095f2696e35f3611c19129a86bf60b11799b6587bef89082a631cbea67fc4d77c7dc998afb8caae59e7a63a5792cbaddfad6e3bf8a0d0fee650b7a9cd502211dac3743642075a2a563ee20c05393992c776869a6eb4a206de21e72ec27be193537a32dfa65831bd13c66f6aeb2bcb6239ef31b2d7e8deb309be4f639c7ef9d3e6147e15a8a9dbace13315a3267bc4ad07ce02575a8b279b37646b871b33ddce57a8170c422474c2aa5bfd5323288753628562f0afc715576c027f7f125793dbbfce3fbaf79fc032bcd9214983fddf1d3a083819399c107e2913de535dfbfb267cd0e0602d6836a902c6589bd1f35dc07146c166d26592d8d52fca9a82340c0da7303602531f8144aa1f704e66380e07fe3c54e13b1361a427531a399616b4ce74ee9633347dd29112e180c5ed263c0153f3500a -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443041300d0609608648016503040202050004307d7ca11cef0aa9200c55b78df8c91c41266ce955d1fb2622cd36ec797f3ddf70eff54c77a2904cfcb282cce545a31094 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = 835eab9bf266d49ac4c672c5765511461a3261dd04ab8bddc75ec577609e253ab019b2db30b7c132e0c57f868052ca0a03d945a74121abfcec6263a4c5a955b70f7dfd9344c3bddc08df78c15b1c5c81124eff2e88b6aeb29125020faf64b3eb89d4b14b9852719f245d85ff6f7b70b430d8b8fa42313d049ef0c8418799e7de -S = 7f96dcefcdd212f01c585dc3bdb38f3168eed84c77eba3d9c5e052cf84fb059974ea282c5d5a4773e13f4d23206c3ef731dbada06ccb827a75c4002a267554f2d2290e2cc23791f8db52aaffc7e2af981f9ea55d8eeb9abcaf379cc47dfa54d28b59686e737e2e4c3a4c9039ddfe637dff0f1ae77ad9fbab078ab9a81259785880890fbb32c70301877b6f53591862f45463bc7c25da257b8fc798f7d3d115d6a7b2228543b81e768516d8f29f645165c1378623c3e32dc6ca08c452665038db2ef5ee432857e60eec20c6ba75981833cb78c8cbd18bc3243d4959ed8ea4e5cc3102e1180530fde85e837188e029717a6c9444265d5bf297b44bcce7367e3579f09928e97257f48f935a869b72c53be1d3eab08dd10cbff54bb099d2e9a2d3ea9acaadd2c2e7c0ab89f58d265941eae9b1bd31d544c4baa8132859869284154b7f9b99fc98cecf104473437cd6960a768f044a655034403896cafa00fd89b9968097d2cfc90215fb1b6e068c0cd6224aa5f73013e1cddedfa80d3dbdc0bde0b7 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443051300d06096086480165030402030500044092c353394e0845afea273cc4747df99a1d7a0474ab8902f073a0c432a27adbc8398de33e7d5b73c3cb4df25e6067981f237b11f009d9c1e547af65322d32905d -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = 62440e53c9081680b721630cf3071ed102fe0ccef99906c98f7ca93876654e62ec6e3cc28d8c1dac6b5caf33601fbc49a3024c289aa419f1efd24393e69545efee6e283a76e0f7a2012f72347d6806fdd0a1fd6fb582f307c604892dd9795d5c90cd39822c0b8aaaa22214d8f1eae534b262876bf13c7a533b9be1cef81b7cf0 -S = 646d7a66aea8b4a22f75881e6647ba0f207bd5cd15e019468138fd126e1c7f660a97aa55634646cd8e5e584b6bc29a4cd213cf222657ff6526b7e0ecfaf56c0a90ec4f17a297b0f8523bdf39cc612757867272409c65e8b2eb463cb134560d021f60a81ff4eb08aa97cbd6c07cc3b32422442724029be186995c2694ee4def6009a7a1a8b3c9eea48d634ab3b84c0c9566ede4eddcc5e59338ba5aa304502c637f9ecd0b707e841d0b7befddef4fe0875809fe386122882ab02e9d06af3b9953d8416cee296decddc3b2e36329434f567d57330c418624c5a70cf7611552fc2fb420af0ab0ea2c6ca4b19a0854e6db10662a7fdaea3c015e53524617cc29afb9cfa9065e1065d95d288f395402667caf80d7b4a3a91f5b681ff10518e5c01ddf0f20c359ebcce526091164d5718cb49b9a42bbb57361865384e8e2e162abd7629b1fd242892d5164c012dc07650c70cee79a2ccd13f424b574eb1f6cef662cde18302038bad6e100a4e7b949b9f1a87de5a2d6352ab830be1138d9b83c4f8992 -SaltVal = 00 -Result = P - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = 7c38bdb32ddcea204a99b5f953ff3d6e0adbefcdd40804f661884a0f8fd328798c6fdc023bc1085cda236dcee137f6292d7af8fe5d1cb80e7d0f2e02e25e085c54c0f2ae736d15095330ddb96abd002fac46bc3ff449608ca6ac0d40920bbe001c51861f9a851911fee78e23b53c636acf66c2f95f370257258771316a84514b -S = 0d07f7c0cbe4a84df3fc088750c9c503ecdba6c37a72ffb15a2da05b5c99740c894427cbcd6cb2c8ee70f35175e70f226c466761356e07009ca88752ae2cff5d7b2e7f2da77a36b68de59db7f5182abe88cb95b52d766d721b5fec504f6aa7b9ceaa9dca1241a5819d4d48ede38c045d625442b27b8384dab964616885cbfca944a747f024032da7b3a3fce0b02254e08c8b9e48646407e69aa317df5706888fc13f091602e1affc23f17cd50ef4275e321a102c2b066975ee8a0dd3111cb0e88037ba98ba477ec67737024ae92edcd7d944bfe2863336a59026052bbf2280d542db1cc70f06a9509805db6651f795b0b4d74f94fbb06d2d4149321f9334f5fdba395cd852e46ff2ffecd063a96ce5d2d5b15cc075c243b30be7a260fcd6891ee3063fe3898037c79309fa043fe210974a1ed96c14bd0f0db1055f710367e55d702ef3a9bdb9215368407312dd415f420bf0a90f67c53c9474219f36adee08220b0798d14c455e57ee8ee47f2b8c7eaf8d5f8474a9d2f51d49a785ed4626407c -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffff003051300d060960864801650304020305000440a780cdcf06d5af7e658c9a0afab551db2fe1c5d86b54dfab86d5c10acffe37c4c8ef7b65dc13a26c2330ad19d34f1065d99ce4376e6b9886cf30792e9430de25efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = df8787cd9718e6bde708b9998cad4e91c7d58afc60b719efeb2ac80f4a152ea3732792ee74c809bbb44fdf397b753809b409f796f2e6dfa5b223f82de08935689c4a532a3def047296934d3e794f2da47af57f1ff501212753cc5604880369e3e058942afc771f09173ccc518f23738aa000ea4072f0279d568fa93d4c6b143d -S = 8407b86a4d3715092fcb38c7d55a528182cd6cd94186a86cc654bec9be3d472ba908d5288c1393619f1a4ea1322ae01d47f321a414d0cb1e00fa37c71364319b2e3f6935f00f0b5518806e8c21504b2784f14c739d186df08091139a911d7c8612b4ec15f17ea9f069898f4f820c9b8aeb5ea34aad293637c532c47b9a258d633614afb0cacc5ca475fd4d3e24fd25809df22f14c20289a7808806cacce46eba40d33f3392e72ce6316ce02866955ffe0558510b26c303c37c773f387d93739b77e053d896f078d0487cc4085712e2e5b42a6031e3d01808e94b8219304a6756233dbab0a2f133d088e67a2cd4392f4d688bf4f4ac4ee9a3a099f7389c5d8ac5f09f55cd831cee52306727581792455ff2fba50592a7b2b686fe4e7444866a2ff69cdd68895f84a1f9864b7f36c6ae89853adc517fe8b9a8fdfdc78ba03f91dc582dea4fd387858ff90dbcf9cf3878632b5b8448e19a797485ad4bb9d2c28b1e7ac717ffd4639617d4d4ebd44a556561fbef00e66b99c5ada41bfccab314aa06 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = a24b2fc765c9953c545043a7ee2edf6c1887925c6f5301d9dba67f3a67348071501451ea5bc407b76c6eb6eb5569e343ec033b0c607e8540cd58d5f30dd002edd2a55b99f121961e015609cb25a81db8268bffaac58e98384f99c02c7172ae2c4e86b39acfe729b83a91a61007f17513efa84600458c240789efa8af3b256c75 -S = 960d6a156414272675d2c09a340d9e053e96e8ba3737ebb8a11d4829ec9287e6997594549cfe6e7f60018074a90d1e89272672f4a464d969ddf7b634a34c36d15b16c542911ddc2805bde86b5716b8c8e9e2dd81133ae4d70469803dda409e8e8f6c0ae0785652528c02f49732c4d2dd6a33bdf93c17ce851e8d3d7ded4636d63f34f4fb2e43531bc61d2dce3f60cf2e521cd5cd7a5f19c35fb0bad328975676fd7958bdc7a957d0c1ea3a30f9141a39b67e101c9e9832cfa63b4b09568d5d13f50ad24af42d4fa9b6a0c3fd95be4a4d7efbe2a89fb7d675054fd5630c120e48af7b7caee23fe5ba2dfeeadb31aca63fcc729e4cb352315cd06f8e62e9b727b9a8b8ee179c69afd09b4d5cf5a8ddb281607374a526d462d40ed43e9197d871485fe84f8b07ae7ff7bb411d128b9a63cde123945201873f5f257ebee48b0bd68c3486352530819f0b01330217e4acf76e43f676e33bc803cd11cca82d7d0cc0e7c14b58c65300a877b443bef4e75d3ae079e13b4719d2993dcd3f90d234956b99 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 04c4f6f1fab0aceabd3acb55e65cde8e827e671e60339af201352d1c2c1677758dd2b42e54e8f7cca6c1e6038e47b7603086561db3aeb25d73e7bfc8a5ca27042df99119d7f5ade9b8d3a03ebde5783e915334d460cd1a7dad1bd0285b454150248ceeb366dcbcca68a14e7cf660dec0280f59f27ef0334ff4eb5e2e104fa6f7d3a13f312740a3ba0afe61dcc5338b1c3256d81b7a722c2453edd8f5314e30ebaab9fb5ff157f8b37e1c4245d72d82f0c53532c39dc891b4342682f1c9a8434b3cdc5da460b174c948fa20fa960e53735f4c9bb7ee77ae0db7a9d0082bf3b2b5d80ccff914256809abc88c697d3ce0346455be8cde06d5920f74fe841d94bed59dce7f2b96e5d708432a56ac6409563c93a3a8ffe3c1cf9daebb9bb77405b551b13a40b253a819a3aa0164cda1979bb859c2f63da926cbaf3701e30efbe721ffaaa3317e4233d51628427679cb0c46556ff2cd4d6f3fb1a647695edd7601378daf8b27b7f0b3836586b9fb1d30666c06f494d0f62ca96b7bf0f6bce76395a009 -Msg = d8b0d39a21a7b7d11541c35ba83329b6320896e86f165a13cab1c94adb9ee1a32eca2d8d463ce864e14966437e07b01a1d046f0046370bca4c3613dcd3aae03f900075f45062aa883ce68ae95b05f978584e9a5f865bef252105c280d7d4c46a86b9757648004365ad80f6f447154bf96c50dfae376c4f4dd0849edded04d74b -S = 2b5652f5be8741b03959eb713e46299a62ed69bc11c1e774c3683af9494e7bb8e51bc4e4d8de1e65fabcf1b4995ff065612fb5cd1812ac7a2c1a0aca8d76c66a3dbea40f426d55a6d60572ae28d3444f059ac714b79e9cb1b9bf443315b85e872a4e20fc69ea1b89c01398b1dd528de6410b48c141b1f7e70ac888393b81b20a8fd6add6ce8a423f4f8e57c6860cdac522349b9215e0c1b25c78a7d94852cdadd5e3f0a4baf2975b60a17cb0e3b9c79060b4ea0eaa153e1500cc05c283ac300e3da7b91aecbb10a50e86a1ed74120a0770d0608893fe6eadee193a20d920291c71df799e620aae96b263f4567962fcfaab4caaa4f06d9d0052a5e2ed8c2f62328a973e2f39568507f6445c7e883e81858df862804c419e3ee5c6bab1832521e841da32bac64a4d89400a2f7d447796f441d3784df53187305fab96ea4faef0cb1229cabdb8cf07c9177b8ebd977c4ed6f260a9b9e97d5d4918cb0370e71ca008db73913f2d519b99b376575a808761dd144d74fd8a7b68f38d5021f8b0533e41 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -n = cf92efc93d89c560e4cff3e81fb72672bf010ae82335c342ed80c0eace8fd0333470dfe2d327f9ebe0ede4f39b0260144d1ec783dffda1f883c0a41cd21e9244d1ab2e4869d765c7e1506e5c1be03db067be54e887daaa13e0d5122e872373891a0480c56d8ced157d316a8ec314bb9f15fa49c0ffc0d78f913ec2dcf354bcfdae2bc031febc69c4fe9c51c05dcec9c1d3004dc8a9c62234d91e4dbd5f9455d94814bd6feef8697efdd9c93af4a9b1ca2e9023109905242eb82977bb4866a81220f8232558af67296b34a19b818e5c07ba53b6e4b270ccf67cc7149c79bf875fff248f4f6f86fa4e9a10dfc162b4c4accbd5f76e4afc89c5339a35f960c7e5d156058bde8c9a49aceb5fea67a09325348a8d573e304e9d133f77913c785e5725d615432d6a258dd4038011a7e19369de19878e945e9d4191148550bdbe5bc22aab57703dc880c3bc08c2df1327ebbf5bb9c2e75082e998dc48685511958c4e7b895dd6be533ffe84d5aee6511480e6547b89144136b8aa41c6942c00f5ed42b7 - -p = ea7777733c9695e5bfc71a4de384aa8d9556b620f13d50a4b3523d95efab4c5c037fe788c98ae85b11b3ae884eed6f3b8f5bcf5ab1b7b20ad3f44f760b2287cc57937487d73c44f4395d48ef746548eeb9101a42a6d27299be78fcc6160da8c550fa46f9cd7252b91f0d110bbdb3ddaffbbcbc60395538565a266b0f78325a4fd5fe846615f5bab1ab0b306392a1d5853da8e03cd00aab4b9045c5d898594373cfe55654169f1c7eb22dc87c7497db4a729b27ab95cccbc4f44bb8a51c0bbba7 - -q = e2a332843df5531bcd8a06e30e3cd414e9a201b2e27b610f944f6d915a5396b5508eda547a3a9425426d988428f87f71b58f40dcb02b012095ad2ccd43c4c4aaf510fafa7388fbff8a190dbdb98fda002db90ba0f0c819045df960e5d7747654ba73baff92a630b08bd78c1629ca8cc839678b87081a54c3d27b34617d2a53bc87fd43ea3e5eda402fee3d18e06f3ed1c2e0e81861e95766de7aceca9fb003e945f8bd43de9f1edc154241f926e5c761109fa4e9cb359ac778f0c6f748fae271 - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = b04cbe36549d4a58dd6ecf23afa174b2c45b9f664d14b8939cea3178403bc3757272fa78b021f3b9a75165a75616de2171664fea032acb5758968c4b1ab63765ba4a607811d4513c48ef0743f5e27e2e86752f20e304d6734fd178aa8f9ea5a74f7cfb1fc1deeb4a87f1c0dfd330dc3fcd3345f035c7614e4944fe7de91b95a2 -S = a4d1579f4732ce97ffaf6852183ec36900945fd9283be8bc50a1dcf81e8c4f277d5aacec934a5fb6951f97efb5636986e06ba302e964d118cedb83fb6a308772dff6d77080ad390ea8e8f401f5e2ab4feffa25559e699e49ce08004b15c49a7915f28099aeebfcbb3d22426a51caa71097fc5fbccf0cef1610c17cfe76587cea2f6a04cb7893394a736fe2d9b4b72093c5109b086b6f2301b7dc7bbab0cde72828407175946cc275d17da0fc63da6159492d70a341613971926be6623b262df63f1b9c9e9917622f365ecae401123baf3e33c2dc04555804e2b6b3dc14ca263121a510ee44c9a4602c005956f1d41e0b6c68ad78200fef0ccaf8ed668239e196c55e11fa57ce96bf8457baa139db776a43b98951b500850170bb57ec17cf796bfa73799d48b24da7fc85f828a6c1287459735b34148ccf84de1379bd2c13b8cff140ce6f8140b8cb8326374def23122b1fe8f015d6b62be5d99a04e62c88e3f611414ccca66193fa31a51cbe9c88d85c9b3bf6802ae24f4f4263a7b92251a82c -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = feb972fee487cdd8d18f8a681042624f51dfa8639f96dcf693ee7e5cc76420a78e54bfb5e21d536d9e81a545ee4a610703336cd60b05776c6001d5a5ff7e89413dd3a4e5b577ce648567223dbac83f6508ce9b46bfdc1b07faede10e193266c372fcc89744dd6546ec0aa8585c0423eec878debba263ef51c9794b9efec8dcb6 -S = 879feb8b92579291f651e8b476d5414e46ebfba0c85b4907a7479d5327c6f582356ac2fd6dd59414b9df5a465a24cefdc39f19c6e814545745710c9098d15385c7823996cb6509c20e359dba1fa6bfd5e22b41aae1a8de26aff1c26427033f6b3d7f4f8c28a3e398c52c8e5221785f4926b9230eefa264b1684d598310a6e09919409e34a693f3c508aae0d861867fa680f0712a1b7019c850b00216ad194e80357a06a995c9da2bbd9f2189f939b228e5487ac83318def7dbe3752c656653517e475764b375f54a26f848e697aece0acba9cc3b722d37fbcfecb40b5a2b7adde54f02f9fa0cf3b2769ed2d4f81879822e01a289cb9b632e15a9ea45e09e962ee27964992f3a406ac9c72d3d0f97563e8296df97d7ca6383e6643d0b499896768846023f901ee0397b229ccdb706701ad048a7d7f17c52b46fd9288c4a6f5d47c0fd6fb55ff74299ef8b3e1b4c2d72af4c24876b6f68bf7ec74359ffff8461f9a9893c9157e0f022e0453dbb87515d71d64178044048c6e161e6730e23e79973 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443021300906052b0e03021a05000414da0d47de632ee4adb50d8031bed0027c846d752b -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = 08511714a11c3770946e03091a2826e5efaec9a10f9870c0bdab1e42ca07c07814a1c8184df4198dfef42390cb444ffcf8a89dde2cbd8bcc75e83a798d8ccc865c80109abdc061b48562cbc0c2cc706940252a2f520972b9ce81816c5a32b43ce6d435c27ae6d88f32a043c1872a52d4cf0bbaba07e4ec2dd15e3c44b9614244 -S = 136b4e04197fdc938eff67044168e7dc31ff57b7885d9b41df0d3efd5251a5f91e641b73cfc7732ed326519773c6cc77648f2db4ccd056d52f7314e3f3009eed7f2120155a3566a307cf268adb6c004d435957370dfe06570d626c75db422915e34aa53707ab99998c6d8c0978c0dff28585f628a5077873465b6372bc24a9374fc6edbfbb8cf8833e51cd0cd9df4d3edf0a59a531811599666a2617cea298476300de1fe3e12e45a861f28e66982ef0dd41674276779a92ff9307eeae1159e2526641cd18eab80b43a83deacb075e60864804d9da39eb1cedab591906d4b428af9ae9451c06e6a3b90fb3999808a93c883ac59f80b4d1e3a32a824d1affbfe6332c7527745bf8272ca22bdd508822a655e0e4346343233e1068bdbb866eb512bc47abdd8ac777a2b93e12809e8576b898f97a341621a1fed89db77449b590344e8147d0e81beaad44f74abfef11181c6ec161e96045ee3d0f7dc96c53c6baf7dbc385dbce0d6a054970987b392db1f237778dfb667ae9a4f7133c3d49e78e30 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = 5f474c3407a08ec87ce50ba52183d2b605d61768ace41d03134c593aee79d401341bd19eddd8b003eb3e125ba7fd3ee32d53c3fb2ac75f7de51a204d7c7bc93170fa77e3643f8465227cac95dfa06e01c0ceb5fc9d0db8f204411ff8815a67a71ccb872b243dd4972b85227b52d42cb9c72e36948b1ef00a79a79e64847d760b -S = 65e8cec81b96a92cabcd2acf178afd01ea7ac429634804dab05faca839e1dead2387a4a4c702863bd0522c3a6847960f604bceaa5b56cc78f1ccc535e9c387c70f929bdfb564da2c4f8653b74065affa5c754ad6ffb1be0e02918b1e066f14e5abf499b75d176106ac67b6d2ea954eee902afc8816e5c9b143a6820c4ee4c8ab76fc20442bde40a0dcca8f64de6955df646e3790074ae0d11501242d6499022eb9597eb39ae68f52152f71e5b1500ccdf46dc8909dbae8ac5869d21ef30029b0bb3881df988161b7dd3f80d9f0a9631ec6e95a33e02f2e3e736c086ba17d7f803ce670ea9186be3da26e552d656aa915b5f0aa0fd80e32f318670ee05d0a52a8ddf56bdfdcf1f413b66f4d3173b8f6dfbf8e2434c467f6c340b93e597c1cb2f114e103d7c03973c6d10fb357b5ec91e47f03cb6a794f8b4c3eaa6b2be6ea9a3fd34417373aadddcd9dccdb95fc71a639ea99e0641d5aeb63d59477b8b8629a4012e35a3e167ef445b085403018f7a2c731b88dbb843c3cfca5c367d29dae8346 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003021300906052b0e03021a050004140221cce979dddc3f07b69ad9575641e343384e9defefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = 23adfc8012add4adaac91852a169e42d92552d70b56ca413ed98dd6e0901b1074381e1a90d59fbb60e2282bd6706494f3a2f200f6d80b209ab83ae45aca3259bb79c34c8652fe2c2a71a4b490a47ffbf3a44a539c5f3e4d622838350f29eced085e43c07a099507a7e9abd1d1496cd249a7a0316462d00235b7ea3b7625b744f -S = c789f344e0f4e0c291bee6336b3d7d2314b0fa847970df318ea8ebba2de399914ccdd085ca5c48913ebe9851a29e40545db646d958b9370e0c59b249119b67efb26cd864e226b289c62edda506560ae976f764d575515483bd13093b28ee85d4ea62fde932d0a77dbd81c971e7f4386fb79c7f4fde362df166255e05bac5289d8f74562be2daf26513472f472b68828b402c4570a5cb8fb027518a29c3c78a35a9fae810aa6aa2bf0333850d6f71eef951c4c7f315f00be29682121e471cb8fd05b556e995d96e51d4d56f0369abacf234d19e43e737467c14e82e05732d521276b81d8a75eae5a096692ded6f5b56fdd22b719a3541ff98dca661778c25f6188c756543bca8b8ef5a29bd801826fa613b349cc24e69ff4017805e181fcfbd8e947a3d38400fea81a18cb8c151a304e6e39c0e86b57ee0d0b1acd7c052ed94818cad2a6e75de2bc7c46fa9ffd9d37b9ce05ca53cdce91ae58bddafd5fc626ae71073b1efa0015cc9df589ae73cda5563f60774fd559e565250af8b9f2834d2d2 -SaltVal = 00 -Result = P - -SHAAlg = SHA1 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = 94f581408cfaecd499c20c50ce61b30fb294b95bf1a84c79529788e7e97547e18e0a3b298ec13a08a0c1d8901a593b2564a12b3cad5e6961de27427fccc6635cb2e1ef63dedacfa6aaf34a23aeb6d54634942cb0eccca137e28eb42eac60e5e6e8c2c674e60d54b5a1a18790f43f287b0ab4e34117b89d024515087bf20c7487 -S = 2e43df8eca870c60a75965eccf79952b6251f216e8ab745226963ba9200b8ba9a99f9093a5b3df5f64e496b73b8ce077b76f4badae288c3e979796f88049ff2ff7cc0401b0f31c48487d01b4ce4854c4f5afb9cdf7b10ca196b665efefe4be742b2db236a379660170c3f684ab76b69de13a3053c403e8e14394379a0e1a6b6ea6ec501e95c17d6c7c728e08315777d29cbafa972d483d7e7ff5d9b97a8c7606300a03e57b92cf727cbcb6f14ae3c22ff2d417481ffc180a378e4fb1a72efeca8231b5fcba6b1561659d8ad96dde28a2f4360ddfce2c598428012abb2ea530b3dcfebab4e3b550cea5894deff740ace9ef4bfd42337cb2d186d2cd05a27e35d37e04093ffc0751f80ca4ac2c3b197c9cc60756029ee0febdbff2c9cd69cd0423a37fe4560a1f8805ce591455dbe56bef0cf8616901f682bfcc1b58049fc8e3ba40f28611822413b1a04d5ead7bf3cf0ecd94ef6bfd4716f1b1c4d82f70ba8e71de91f84b804512dc037bc17a3de87a74e8c37ee921e2c1a03e7cc9768e3059dc -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = 2456ef08c07fc1ec469aa9c73b677af225a9f5f6f8d0e150d1d65e71e6677609bd44f5859de97ad6436ecf75d5ab76a41c9f84f6ed13b311e87ab2b3661cbff3ac7378ca65d5eed14f54fc4c34e3d7681cbae5c1c1fbd3274395e2a21d6881b358ab21ddfe8b4564d215d8553e56c4c68dc1c05f5ad1691a48ef9546f495e4d2 -S = 0631ccf756acdd39dcf45947556f56418b598b25512f9851ecc826e8e15ef8312b12896c5046736df8c36c1e80d43abf9dadfdecdaf48b6a79a09200008695e2c7469c837edce5bcc6c86506908be7942dc6e498f9806a921180cd0b997211afa495d1de016a1b98ba5aad0ef0b0b1f1ac7c8dd5feaa44ae69f8edd6fbe7a4b196ff96077090d2bcc05a675bccec3ab7d3b6b63adbd97626494e57d03ccec82a4ebeb2641b07228de82ce892e24df312f2df624235b00495b444232c205a5001c0db68c06ef7112c8427ae0d563b53b16f9fb1bef64e59cac4694884204f3cf3022ee2471c158e70ffd552ccd582f92eaacbcda5a43d4e4d4b2e72b2193e34b03b9ffbd47da3c0482593440910dfc334d74fc1d0dc11e74210fd31fcdccb7ca2d01931ea6c75faf1f7a32c8115b0661ee1e3457090b97cd35ae36d34b06da17c047e785a5da9d23c048dea4c766849792ae07ec95ffea56686fffd71fba54d44fe8e3d2dbe742a97acdbd7d54fe3a78d08bee547664a0f1dd1544b509b5d12fb -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = 29fd9ed0a8ca9609d8e67edcffcbf733f15581633c2449b1a2414115cc04763e3c359fd58471f106b5cf3b3d1bc42e2d2744fc17ad2a264950da8ee53a25d4e3106ddf592409bafaedeaa2ddb57f5d8192d7cd0d9706c4dc4bc91a385a6dfd668bec89e4f25a98ee677fdc4637c62b35195619cd637ecc727d560c9996a39ace -S = 71265c24f74301a5c2cb797274c15af942ff4b98aad737596c4195fb698a69396cfb5e967359faa0f091931fd0ead53859ae16c1fb18b071b20dc0e8936b58a6dc8eadc773ab583525b1b9c01112c75acec69221d5a214eb2295a26ecd476ec37d8f2ff62f7dbb7452f306d3c4851b67a57fe3e6d7ff98489e47ec0768e3d701f13719f0d8f11281ca4fd6bc1dabed86c9d51fe187ba5a1d3187465e2181e4fc76cbc0ac42f287e9e4013dab1926e19d02bc5d7b84605111f5d2fd63229cc27d8a0e3378646d90a44726aa6f0a528e86a9b9ae709aec1a924400b67da5fc4d2cf307b810e66bca0120b659659882699994764d3eb992ea3521f40e8fde04af2f84e73e33ae5172f969b05e11f55872db50c1d0287bd331850025e3a62c25c26deec2605a4012c0c7ae8454e3c27ba299858930f3b384188c41b5302c83f9032e45bc9995f3ec5b3e5de246eb0bb791afa31523277c26a590fa67bbec78b7934d876f8a8ade9e12190411829625a845f0cfa48bfbcc0af544a8952d52eaedeafd -SaltVal = 00 -Result = P - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = 092a5bc0943f3cf6a6295b47ebfa4c872f57f1a10c8a4040c6d246cf73fd6ca45f39fa78ae28d91b43329d65e11fc37090e5360443be1853b77ec0e79e24ffd8fdafa842d3334ff6fb2b50705311140a1e2c8f6fa7aa0d5128ee2f5fe92b3071ac326d06498825f196bc7d4f89f7c7bca1d503c78173a6a3dfca9b1f9c3b88d7 -S = 31e1288d0923e5de3feb553eff8781fcc91fd118f13e2c931e2ec8d3a102344e9f2069bcd3e9b863911013ce2e6e58948123435fdbaefa122e8393cd84abc653559b2958d643ed93431639123aac801ec52578b8e8250d21d32a7edcba7d639f890c3675f664db36fa859ee340d9c90d560b6e1b07a82811a0ac875e0061ac86ac352d33c1760c3ecaa86977efa971f415e3c4d878e5c4d6cedf865b048d78359c1b063713bc20f89a77962998f253920855f80cdfa21f54cbdafac23e259f6de785f8b298aa9e0363a4f098ac1136b036f40c8ccb87de2751ebe4bd4791be851537352b5e813fd1f82d3042853c44fdf645d47dccf149288ebd41b4a583a8887fb01ed1dc7cea237a53649f62a94e3e1724cd409eda8194d39c047b58c43b3210050ebfa39551a4d1128ae519ba23b20456f0d5ed259342f71e1a40d3b84a27afa1d26a1e4d3e365975e9e92c52802dbde13a239748b1644b528cd824c503e6dd4cb1d146cbf1d5a96e20c388bac4bea7b484c337c7b733ab6715bd92dcbc12 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff44302d300d06096086480165030402040500041c87593553a6906097c51fe2ef6f4de291844e6c083f4abcf7f2d581fb -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = 729c6a3b890e20387db4ebdeaef7e1036a7e59af6da5952ba72ba55a402a874cda4d9311163d17cb595c3e07d0b6364eb13591f6c414ec3e2395cf9b3ef7d54c21a20d34faa69fe9d563b309ab898ecd9b44fee077b0f97182938187784bca94cf059f4e3d3002ba7a321389475933a8af1468138d6303ea4e8c81c6f810b04d -S = 31a04b5bb1588d4410472beaf2d6ff86d514c30456ef16df2e0b92dd9f26b7782aa0d363d1e3035546d7c91c6cfd05a21190f597103f3900ca12b51922eabbba0f9df47010efcd5394263987c7b79bf8df94ae0318aba4a14caaf791f4a0807bead368a129e201d466e9e70868471e2cad83324e1f70650a2e1d11d9aa539c98e29f1991226357e3585eaac9c856027aa3ac418fa72f00ab71738dd6baa3e8e8af0f30fb58c02f50c50bbd64b6dc1d693fd5d548ce2e0e0dad0ac2936cd3bd1c16ea2ffcd1d2fdc683aa5a0461158aa5e621ceebe36a705d4a2813e5a1b8adeb44718d1af3124849bbb3859db3f8114374c6680cc80222b214ee737744eaf1b7bd400345782fb4df6fdd9e4116714028886e250847e7455ec466465bddd55bc4f67e5ca6048e95653592c9d0bd689dc1ec88aa642f253568d3cc00d3bd719b90e8227c3a1a924f58a8ba5fa68e0b932bf3be5441e601a8466111c8ea6eca21039d8605244aa07952e6918291a2a58ed90f111ea075954cedb1967d4d80bd208f -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = 1399504353d5ebc7064355b017edfefe97729cdd100720cb16bce8fd200136ff9668e19c2bac4afd6df392159a500a3cb68ceb19da2648c6cf98402fdcdc78bbdb2fc92f921535cf419d20c678e6bcc72be2c6f5085a700008329e9145ef54e90b766fc531169484aac9678b57b7fde91ffc933742ab80c2ea1368ed0441b3d0 -S = 19e0165b14491e2f84f6eb55f7d0e3bfa5ce45d20067a7809def939408a90b0cb60b3733081960a0917981a89c8907ba50622411958982b37554b40235c28bd478a06d0cfc3aa628c6685fb739a4f72cbd3fa6b6fca3b2e927a7a79fe2d6513ad8e04317ded8873e446eacc8e600380d450cfaddf32523ed7bd339f3f61638bdbbf80ea2cbaffc51b2e14aef079a491eaf55c7da79189327070e0c66daa906646095b2c0062850d9269a456bb13e632e5954208fa9d9a576bf14c958741f7e30372709c20a209d0fdfb0e18608a65f049565b25a77afb4a3d79a49e9fced249f6045d95c83f0ea4b8595288eb022620a1a6e6768239fc95867c575338514bb8d16f4595b6463a0bc576f1edb72c2cc4344b1000f43447207f2ca9049c86c6ec92f1f74b6811b65534808ef659af5e3f283a39b9921ab906a51a9043bc34dd023c54f2a682f0867bf543ac02b55a13920f8c5295b0aae650af71083f7562c84bad2bb0685b0d6101978ab5d789b88c3785d82a01f154795084b6e363235b10fec -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA224 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = c783252ef5e96363cb48e544342f0b82a98334cfa425d5a158cfc8339f3fe6cd3498d746220529c77c9fa0d14f91cd82d579e214eb12c5a6c511633fe14c471039216bf9bd164e4f00bd46dd32db18284ec8c6f89419a8133a7dbe4c5fe545bc40e88850ae65f984c06a806dc55413fd7c3887838882a6711edc81620152085b -S = 516e3483482b42a740c475678c4954ddeddca4f5d3cbb9474aa7fe7ade371f4ec09d497ad8f4bcc33f60dfefdbe3bb66268f5bf25eff3a6f4d58b2295c82dd977933e237fbb140f9c095bb31b091e0d8ce862a588a827a3ed7a0a6b407c534c37fe6e89b047042de8119db826edb202cbbd6188820371d7aaea860f08e23cf927fafcea8f398c3e189cdacbe458f3804131b6cb8f32bdea4c8e88dbab79b5493928a794aa125a102c2af675e8a1654489651214793bd7b8e86bb237f5fd19ba5c902986687e18390604a5fbe531cef3d1cda48c7dfefe053bb3142ba153256b1aacabee463dc63e7d74179e83101aed8e9c140f51ea45c94c9114f22d9ba63aef338b87c975f3453fccb06ded002477a073f40a4e3a42df7bb588a5aa830fbefa8c7f2bf363bfe43e236d25f8c0d0adab69e3b3b1ccc756a5e8edf180cc5ef3d18eaea6ae4d09e407a1783ee6a4a5505a90df31d310dd150e6aedb20bb97b2551e6e96223aac0b3484a6179498d1b4c2412090ad5a4d3dbc0fec1d11d8d0a813 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00302d300d06096086480165030402040500041caca1cfaac92548bc1743c2fbf38354db0247dc19de0004601b8c68cbefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = 5c0231e10a12e268e08dbd3b86845a1907e6bf853552e12e482a68afc7e9b378acb61c0cc3397d6e53adf3d50036e1a7f07538a52d5af6634a3aedfc4a22c603bd6a45bd2c8dcf8db73829affda082293c19b4ffb9e5c7a76349b6bcb3e676f7d647355a0eb7e0ae5655e730456a448834f9bafaa3985ae0d97f4c58cbdfcc3a -S = 1d7b0e1ea89523699cb8ca51a9086043c1d3c4e2d0d0dc5e1a6f3688d318f7db0d2a5272f71915ee2439db175714b2c38e8c0b27264c8ee01bd1b292b66197e023f6b49dea082b469cd30289aa5b2079e6342789b1cbace05ce265e5fb1716947989e5ccbdf4779a37bd4b748ffc91c2944259ae2de9582334b6df1c839160e4e704cc8a771d371507a68c61f3a06c46a41e3aef02162e9f20c85ef51b3f15562d2b9a512ef0e81ad60f9934be2a2cf7e5f54813244d360148334c40fc8a2e65335bacac5b9a607d70d4296f56803de8c0840653ae2837a7e826dd4569896555395bc0d4262d9fc025f400859421bfa8cd5841a3375e22efc9c1538e78795e28b6eea359da14ca3c44ee30d16e7359b7d83d47b6744099c345ec60bf2fde687d0f81db3718d3a79e4ae86a0c3bb47ef0618342f103d6e6f7ba89d4a4a520b1a61b2d8d3c5f178a46166631b58921b7e0aeed15c175e85f76575b746359ea831f87c261695896125032d7ad4ad26014abfd7742d5396dc1516f46dd273cee88bc -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = 70125f4abfb1179f8c2b4f4cc30386a6fbce13786050b848f0e27adbeb16b0fb849e5b77dd6ab56c32110dc35572d1fb5a9bed2893ea533cbf71db867e9f4e78081dbdad1ff7182b42fcfce52467cb845cbf02665efbc7e7aaeac2e043d22e6e635830f56d9f676423b4c4ba192a9cc96901fb39a9cd3cd11a13d6f222f77964 -S = a06c4d12aba140f9db9ae4dad7a507c241cfc073fe16cccb8e99c0793a0a605097a0538bb4849089473050ae1873fd369c2295dc98b5561f975a66d32caa6ebbf887428b163a9a0515a0f614f636e8e8a87993c11fb334195de25c3cc9103a9e01f5bf2b6b6bba1786b0ef02e17c9256aa8fc714fe5bd7c905e240c2dd120662ff4ed31c229df92e0c819ca384735235e5f817c9a844b733c4c125498ad5493d1651ef8833886d98b409b41709fd0d0c20b0c91c666cdd4443dc0aec4e3d9a844d28b40b36be972a99ceebe68b955fa699229bb393bb65f32f139cbc42b20be0481aca045f965ed2caca3d4f7802bac775fd0032967570d826361620b32a2f230600aabddaf976b1998c9a5ec545fec80522f16876c4fc77e0867867bfab4b167fbee839b83b7f5d647a902e3118a167b0a7c7fbbc31f23c8b9606429c66c46a3cd7498e14a94fb315360a1668025ee35bb49fa614250fefd9236b8d3be9bdb271f865b460910149449e7d22df7dee27db29aa123bc31915cded3def0249d2a3 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = 29d9cfca7319f6e6ae00ba6de43e9f20e140ec7b45f76095d7dc21491c31f5932989b43cb58afeba72f229529ed87d7fd435a49729a25cac74636fb0eda5e5ddfa047854455048051291d0ced04819e7edf82d7defe5cf9dc11c69544ab346154452015a4cf33e8e35e5972ba217da20d4937175c0492131650ef87c5ce48001 -S = ac2b892951ec306c6fc6c0550d633819a2d4f073001665cbaa7eceb96972e7b0358fd49f1fddfefbe16cfdb78fa15e4174b5d3e398268da9eb23e6b7cd8bcb679079106f583390462850e44b23aaf0a59dc9780d0f3b15bb93368da8fdefb979b2220241af3e60e5c1e2bcf23e2e8657438cabc2ba22e4081889d94f2abcafca0dee1e81ef1c29d3164d86fb50d28ebcf89e362f9eda07cd85206b9351c6092d37f0cbd1765aa81c4e0e18bb01d204a3073e1b60fe67c6233862f1739f223cf79160154c138f01d4428e76980e0dd9c21e1a701d05a6e67acf7f257275b383e506bcdcd54a80fafe266e87eb36b3c076589d1696916ccc88e4af50d8f3766e6dde0e530cf747d814a591e5da6bc977eb25b43df723e28e3ff226253d07043abf1b8f5a013b2651de9dfa34b7ffd94baf8fb1459b9fe305bd58064138a0ede6af36298f3444086f1a7d0c723ecfcd6404fd267bb20ad48f6655a9a0886868a83a214957b40af02064692661c1b191aa828339495b3de0c789856f80e5b2d569fd -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443031300d06096086480165030402010500042038dfa46ebe6244537c96b22aaa7542f8cf5a10069d87d81b37f93a2ff7323cb2 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = adb245d4c5c72ee661b657c6efc444f8b1bce6b8c0e1bf905028472935a48d62a742219f42b6326350b5f4224b6544509e128fbeac22f026134b9805320373a8e938098a9f42a2dd8a16ad672abc628f1703a7b8fd7330cde583eb1db60c9b6afbfec23ce652c57b953f4b3d95b1e6dda5f7f54dbcbbc9ad4d38061cc9a74cce -S = 7f25b51b4d94f2220ff257205e640272376993e698cce9fc5a9b429ecf8a3d6d4150341df129b74030afd5d092858153cdd01a38a586c05871632525ad7b9d433dd9f8b1436d3d62efe46501665e075e918c39f775ad6e1e3e4883a529024193891d9463b0d1424a42890d5c05058d8925fb4c446510f12afd6457b50cb611eb0ca641b8f2f2c0afa4f03e98d154447497a4640405676e003f8a2cae21458d56c59785e34f54000b6105e85e25e4c380db43c71b990d3653ac344e2bc72bff987d6c5249205f2770998725e88125309a7c49dc28f9e6fc8a1340f9dab47fc6507d3d99fa876c330ee8183827db1cfa6c05179bd49d5e4bd6b467d559731417c9b19d0d265bd7cce858178e15cda9eda4b1ace1f6a492251c4e591945d2749d7ce65e8c03d57277e6bcb0f097c13504f006405e879616d95b5b75005118830beaab13538943044da67867877da87f29183fc05ca754df6c5bff810b6e5dc64b9e50ad29da9fc74a2fd20ccac5a300928ced1c3eb719e44e3b21071746fc559b1f -SaltVal = 00 -Result = P - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = bbaa076712216e08ed954528d8309ee685afcd901d6865c4d48b63d5c0a8a870eb71ad80a7c2724e21deb7ed39fc6fd5910272cee49072109a4030a8992cef1d5db129544b7382b142a1fa7f747b66927411212a8f4dff1b6033822b9f6851bc3af1e5aba73e8677786776a630b56c645564436ec6a7f42e4fedc2277b63b494 -S = 477b191f2d027ad6621e38d56aad700749444fd895238f9dae3633176505d798d670ab5e85df8fc42906949ba36090a14577e9b179e6704be20f1d3ec2ff00b9f038a71956ee353f358f608d1728164fdd3b90213152049f2b3588237a8c1530f5333f0b89f07443fadaf09e80122ecf2af6c2dbadd5e189f35f9c2cd680118a2793190d0d63f83e13edbabfbd01031b6875d9c7fcd38bff3587021ef04f1ea0777ac67e76aa1b0773109b869075ae2c4c1f0121782ad767a7d0e78f3170c3e3243309ad36378a698f39fc6591463dbe9c84292bc4a44b4874320f9c5cc3cdca879f2a015362dcacc5c74cccc2bfe05f0773f3a836e1ec511c72d9fc7317deb4b2af5976bdfd1fabbe15b3f99b498647d92f818f658f8398c031cf2f364ffc106e75ece8f1cb87af2592fc4661f80c45e76fec99545c54dda470a019ba9a26068f05517defdba0d423029580ffce95b3ae1e5c8a882806f40ffc3b78640d6b311c2de8b0d51bf82a1ccf304975bc413d5f7e2222d91e5d650ba601594283aa49 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA256 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = 7e5a48ece8abf0637665d2cc4df0476da66a82006aefc2100018cca662c1992577104c739db3675984683d2d43c3abaea52c032fc42749f8dad8a2e953c6096027df445d66bc16e41527b7a338da81d5308aec664724bc588a577965d75220e636cf18f36c5067cccea8267754be32abee8e25ed1b7085f9b79d3b6314ef467e -S = 8b08c4fadf5a33065be2fe7b2487190aaa863d150c819bedd2de321ec34b9f397e5ceba241c998d1138080867a2931660f6d720099698a473b10fab8c6c1ac99bba21ec964db0e9de0424d12565bf20978a6041b8c72019f910c286781c7979a98047abe06850d282644f6b7f375c6bd6af8509727b0d64d851902baade451f6af0c21967e4d545a535ada7f59f23d90992ab1268dab4797907527b9929cef18ea468e4803ddd69f44627577e9cec0ed8219a659db94d46f560cc1c32fc36537f9fbd568e26d22d070c82805cd17cdf80ef8ff1129f5254984ea7e13f3b1d40f7d9c304f49b504b634807f77dfe73cab854d3b98878dac4d33d13289d1fbe9e1b2f3c75f6ef5e4deb2bbd8e56ee6353f2a5d9c28d4640b01777b3bf743e4acd53e2e413dee01bba20d1811c62c3ffb27fa6a6a522dca12cba25c0b5c2f02d3f6b4593789741aa8d2e111b81e34fbed7ea544405dc0edf263283fd28249665001488c67f9ca067569f82c52587ec438b54516d1d84acff50719049e64edd562ad -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003031300d060960864801650304020105000420c46cd19378dbc903c60d48ba8ef26b1ff32f64f6612a2fc01dd770c878eceb8befefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = 2bc088c8b2a4af1e90a9023b3216fdbf89aab7710e8b0bd6037ff503fb5e3eaf9cc85c8ca41394d82a87612e27ce19a334a6ce0e95d972a7776f3fd47622563f6212a72c43ba100a9a23c947ea57ff697719bf5b4ed3160485d0771ec4ab5c460508304f97816ddc69e4022e859bf73adb6b53ff40623e16b60a638beee398eb -S = c42b0d458924349b4510e4805a6f199b29defe24c7220c54d1ddc44117bc05c5b25858939708333c8fcae96efc75e1df6c6b429b2f0e3f9ac21a59e15c1a976fa91294c11e255139725d5b9ceffce0bffc93166057d191be06435d68a64e0d790731f00fdd868dd2881546f467b52d3fd240cea6b6e3883db18facbb67ff858918de576f275d6a0fef13fa135665928a043390607b964a8d395117f886c661d9a9f8d3a2d863292bb2d82c987487180dc2fe859fc20fc5ba849399fbc2a5bbc414fb244003b1887d945580d2bae524d24de03fc14e5595e7471f14cb212cff64d561de03d5a85304a51883a10c259ab729e750f8a424f769eb8ce2f12c2ce2b3835b0ac9b219a22b5725149d65681c525eaa55ddea7f674ebc833f74464302597cf603d95fba141b8ddbaf3a540df6ef9bda7146f4d104a9287a4a55bcc5f7cb4dafde9c437d2172cebab2278ce97441cd1e091e3d18429fae503e1cc23319ca6abcdef6f8562a11fe7fa1b283f4c81a3025668bfe995dac330bd0a3ac869985 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003041300d06096086480165030402020500043034a99a927444c010c6a1e59848fda5efa3d6f47f1dc62aa4a8c085308632d72f89e37e9f74f5947755a2dec1ddcdcdf2efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = 52e616af9542cd632f93bc2f3d510bef3dd341572014ffdaa0b6eecbd447f6c302c4b142b45b1f990e759b075ef40d22f5b96278366a3977ec72df8ae1497e85acf59143cad19b8df08d193ea076b5a5fbf7bc2bd660d2360fe7e54d21ed5f7cf782a0fafe2aab097ee11f1e2a5e6a42f69539b8287f32e0b21de65bbfbb0170 -S = cb647fd846c24b61bf5bd7893de079147a8fb4d447bdf26aa871d7ef83de578a383d932b152bc28ba4baa5ccb15e499e338b2a5e3606533c62915a26ebd8351212c226265bf097af9e30f113566921dda511c72fe0fb114eba47bfcdd052032abed1f69e144ee7c347f62f730b96aa42b75e23773d2a65f0d5f63e01c395ffe6c9a87c2364c05983e4c676af4b57a2190a2bb7f5f1b96574663a13540f51da353be8876879a1ac90b10a5acd42a69b6ab45ca194fed641acdb89fcc2d93325028f01a3149795a2d95887e29e161902da1708410d37cab1987d4f3265b9ade7c1bff7b385ec9ea1221fe00a285a77b5ad37f1e8519326d7baab48fcd70aa52dc2e6f8e7270e2c9c99f21b30d217a62969bfb584ddcac60959f71d0ae16cce6a41126c9c597970a79da11e7302ec710df8890afd0b133306b8f8a2e1c67a6f0103cef6b13fe4c1b19415759291267b3fb0dfd552d83ac856f85859589c69d911c9e498160906833664437456739116626d03f6f2028d869218b418b6b9360d536e -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = 11a710487cbb1b9392d6f6c305b105f68df8d5d6384e0cc10292a028a5604835b2db30b1e1aaf124a541c03e0462e575a6e370f02cb127a4c315c2bdf8365b3fcee020ed0d834b6ade7f549e959e645bcee20e40bb823adebc2f611a309b00d28c3c46c4aa4e10ab631718aa5f6e69ee2c7e17908ec82cb81667e508f6981f38 -S = 378ea4183be0744a9b81e57577e197b4b20f3e9cb7fc455def83eecac3f470e758557b741796439947eb6b97b46b3e67c12f30452c04ccc3801496db5e3df3b5f6442b7086eaaf36ee1a43746926e78cb43317259970b71dcc9127fb41668845f0bc7a938addcbefc7ff19025f4c35da5efdb74884a98872119983bd0c1db06489b7530caefcc81822e74fa635ed4aa441a48b8b7d6d64f1a489d50fea892b2296c6b1c24829e7f7a23c186dee29d88bed157386e4090caee36fe5984aa09cc222db2f5985dff56fa97da47202fe49efac993ecedba74132e144e3ca1a5702127dda6ad91e133aa6e53d3d5cb8c81b1397b8c8ea2b55714f6559f198d8ffa7aecbb12b2d4bd99eb697a3d26ca55694f2f1e99e543d6be90e4a21214ce3082d0848f3c141c98becd7f986d5684e67a8cc5b783d90aaa7e0e2f30616f59f38ee150ca41101c4f20ade865add34fed3727b745db406e91dbdeffc40875dfdf2ff0dc62a8d392b4272630d3b17ccdfe39313e7f8f265b2770942f500396d2e2d97f9 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443041300d060960864801650304020205000430eb5d1d6ac4370fbf37da65a4a43e31015aaba587ed2b1720edc90282ab022f9581f3fd35e174a5be58edd5f9a9aaddf3 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = 979982a68d0d60a1200990ebf8a49a7b7db3d1e83f9ad9d9946267bc830c48bbe025a5ebb99b85c7f1cf93de2beb22c8e9766e5ef526242b01f5251d8a768780026add2d2d8fb9ffccb86f8779221b01d206e586d96b83839b3e006910a4bca6438fb5d5b2900431f8ecab50a9f18d0e7e8abec7b212fdc9ab667f08dd3eef14 -S = ac48451dfee18a468ebfebb7300d03efd9231ee21d9a3e3bdb5db9f5ce8d3e1ccb9af7284d5a98a00c39cf62d9c4a46c0374808b0dc01bc57ac8a61682a7784279d090d5d57c5b4f36cb468fc9200e3c28818f5e8cb14bbec20dc460f2721cddb09233f64b0fcf7fa00c165395a681ebe52fc8673d7b18003c4387ca6c9487f02912cc15e525531e1d40aa79881e2c6b2038c5938476d4649f20957cb0405c6f1dfb14c1986235b7f8f18ebe3c47600ab80f841c100ebba3e042d865d0fb8de4708da33493fadc509683bfdd16c00c5cec1fdd7d3017f4a0718a615dc7122202a54ea7429966e6f818a4096db8f0ef3e530780f09eab5d96bff59869fb8c85ed059a3ad8dc3d5613f3300a8ed17754228ab4e38dc24dd8127ac8d4cb7a68af8aefc87e94344c46868c1562942e188c9618be86bfa09d12a16aa0b52a7ab493fec12eb8f4898bd000ace4c2520d6713772b524dfaa86655fc5dd140d1d7ed49db225c93845b41ecd10b8dfea26adf2761733cf0d330feb9cd024bc4b906fa14ff -SaltVal = 00 -Result = P - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = 7fa4945a374691fad437ab261e2c9068c7221fb14ea96f4a2483130d0e6d9cd5ca3d6033f52d7a632c77127e7222dff0d11be92d448794a0d558dae4031ed83766208c2c96acdda048abdbeeba78496752f359fc82d1b63eee36c789d185337b9c77a0abe16ac19870fc8fe0c0d9d6b390d1f486cd2edd0cb74463624049b58a -S = 9e8ed5b7a3863ca22b2c2fdcd28ad09e69346c8d14262c7800e85ddf71b845bf31d2101fcb91fbce1f227ee1c72210f29d995404ea2e4b31b41a71173884570c2fa0753facadaae01038e6b897940e386b601e972d84095cd7e51345348d45a653c1ce707210b017c1b32ff4904eadcd34097af48a430a0147499a9d9ee8a765258b94fa56b0185bb0789cd222941eeaa8356964d2b1b12c81c0ad0440725ee6360c9e2f2885047c5b6f2069590c0f85352f5936e183d78e5a152f6337e1643bb37de221291191fa4226973f9fde3c688fd214c49ba3ca6df5a09bbf4523ead8682835944b1f7175ae038f84955dab509e0d68b5d9da75eba60e11e4e9ebb4d0f2dee448694f952eb3ad39e740516f129d12874e29ceb895dc87dfbb2ce4f208d1e646c347f9682dce4b71ac53ebca2a499ce64112279ac439f5942c8d04f2bf5e699000efde4909e6b6b62cfb52ee384e31beb22b1799731c543c4a95303f8fd32a14d7c0fcc4b449c9782af392800d2f7bc37369293f49c1cb94b2921dd407 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA384 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = 831c38ca5421eab1edb3600fce5acce059ff4c5b38b56d69fcdaee5c045fc6dea164672777084574277f92b42b654c8401517a5d8baeb30cb6c6df635a20422f610cb66a2c7c37b13215a5f8ea86c67cec198bf95387941d6511f53d76cc3b48093daaf93925c950579e2142d56741b0627d059657eb188552e2b853200cb911 -S = 5c95df8ef637f77033e66934588956aabf334f0f5ca5efa1bb0e5b1c58fd313cdacb4d9f3163305e048d2f33a9d101fd6c0670f96d67b466d11f03d3aba60bdc04869e3a17aae7c80080e146c114413bb6f6016653baf26d3516fc05fef13149dd552bf5149cddaa46b783e625d5a3a0b859563e9f467d9a2723e5efd041a92a9837d4b652219d4a9799b35cb3df6c80b8467338b0e7c325e0dc1ee22387af8877e66c6f6a9b0d12a83db08dd4a843dc0e7d0aef5f0ca9cff1db415f2dfdeeb3a0525b2cd32c07dbf39eb9a3a132b9f764b66ec0ac6cbe0e770e1afb063cd1cbcfd8e8b39e10c290ab4a8500b0729a1240c772ef5adb065965ba3a4536e2ee0058cb11ea58834a5ff267fb11e90160c7a433bc1af9a044e208265e4c62b5940fde0e168a8863bb398305acc367cdb1c3b70f39ef051ce9614a125c3241bdaf42d8416d4efbc003f698878829dc2cdb1dc1f7c0ffb1af30b8d807b459403336a2eae1a6a497e95a0667a2f547b5d40bd97f9d76259c3ce91f1209a00e8da48fec -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = 939cc087cba5d8eae6cd3884251f4d60808bdc82f2e6f013183217befa20cd5929d339c80ae7171e71b2f60671c9a36273c6e53186496ab6f63d02d7205d0bc384f62cd71cee47c3ed05a8e8db5b8305c1339d13c1f6496dd97b9634b785c7f2cf8d037daac24e1f814fb8f30adcd49292576cef4cf47380e9723b9f68a1e92f -S = c80363c21f7f20d91361e148b0a76c33ab2109b8c8e34609f567b49ec9675f1c04452715371913685f9a2f88effc90f3ac16665a2dbc81ccbdb4cdf677b66752fe07577c9a2986e48bc03e12126bb5212d7e821adb66c4eb96c267eb898db16f0fdc52f8f98797281d8411aaa4949d41815133a79a7f6f8cb3893fa1e28a37ee6c550e17772d5be34cf4b2cb16f119fbf9d5f41c411e1d2561d33aecfd9fcc425e287a650b127d11ddb2fe49a82ad3e7cfa84a4da75615ae23d0cbc45d58b7cd4123105ce3444a52412bbf09c08036f10d03d79ee735741858017181262fb5e2f817e0c53d3def1fe84c53807933bfdbb2ac2eec4fd96d638255364033e38ae5f9cdab1241938c1f6dcb14067bd236cb69809d95349d9c1723b39b71192cfe0c8a204c142a2a72d67f124ad6b8804d3b5ea149c7a1e884025fe56bc7ebf925d34ca62c285d3b290eb38fb24e59ad7c47914b98d55cf8d1685f1d08d1e919f314994a348499a68d3c669872a113bc119fdede411f4318dfffc8082e442784b68b -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = 118a21ca36aa54b42804f7fb07874ba74e14bf3906dfc4343a19dddcaaccf53ec306f670cf39971a6ae2763535696613ce480aa0ff70a3e735e826d834b892480a058039417dfb5c59f693d47651ad3d55a51ded849af779d312a17b060f2d93ccd1e6acf53e2981df87775f3109c72ccc7121a8ff2468f3fade785086987128 -S = 5d1fbfceec266986ee94603ef2f57ff87959bcb7f1677fc871f97b5e73bbafb6885957eb04616a3a9bd010fa46c8a5c40831944a7f506d165ef3cfa4d3a7bf0768360e8dc0444c2b7a2e05106cdbd6e3ab029c11ebd701fcee53bc46acd269582ecd7635178b850ebf2522d16bb4e6671ee7dd1d417cf0d23baa26237e03fc0650462c1d113dd450e4465ff18d3a9871fe5fbcaf554d14c0bad78752b4c048356ffed2f80ec319ba816c60d06e270c656c8687be145df46baafb686a9b74df7347c8712dfe671b33aad8b3b7eeaf6322a8e770891c8e03526e1c6ea4fb9dd03413d646b3ac78a3f6b28ff87612616dcf87efbe12ebcb6933bfeb714961e8e153f96ffdbf7777f6109be52a936a13986e4e8229535f51a679f7d7aad4acf1824bf0616517785b864f5f19d275406ec53089a04a4f1b820d167b5ad3ba36910a9730722dfc58fad54f1e0d7f761f5d4ed3bff3037f79361fcefe723647c65811f4ac66dd6dc4e3f5b4bb1cd0f3d2aaf000251b69b9464a35bb7f7540b1249dd39d -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003051300d06096086480165030402030500044022b0603ccde4538899af30bbe52e2e4d6e62ca5f5e69a0e7cfe914a193af2e5788f6bf85199a7098078438b5d2a3b694b926526033922915953e113bc4b56d3eefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = 465c2bbd78a5f3bcb387d0db7910e9b2d0b827948d949a67d2cc19b2d64f29f8e4c52145a7c68b06a449cc1d085f0835a421405336e6bdaeeabab2c1200c1d9e70a7ee85ebe46bb5a41dd382706441a8e975d4dfb9ea0db015ae788687b48f08f1e9dba6cf675c72bceb2b3238895eb3a89e2c609e0752125b90b42a92af48de -S = 902cd4cb495e446e0b4d4cc1944fd9cddb126dcb60543dc32c4ed0eb4e72182b1a13459746e4ae37805e23808cec5974083911f1c3f155e09a3223b03aa145128c9a2ead1c7010dbf43231b6ba5fce2ca77734e543139118475f5f3eb9db6c0dd00b01b7a48a1b4c65cabf9260d22776bd4168a7f7b8b81099ffb60d6ee00356cc16cfee9026fd318ef4f0e71288daf10e06b6789fe0c590ccb7c448b7426dca0329453633d98fd3917562a2df5c2a1ffb07f82354b8e3b1a508908314245767542b856938e019ff4ee00c46ced5b8b836b57b9d0999742b2e23dcb15e66c49401495dfa7267360eb0493722abe6c89cb92d47aeac5218a4a949b4d7c4ea23c7448995294424995ef6b873959fa8f670e764a59cae39e998459f9eb03f3f640a6c4a6c39a9532c48db61b5d6031e7098bbd836f5ef887c20f00e6f8d3e82a7cf3f3fd027cc315b85e93205b78e29b9307d25f6c38498bbfeb08a0aca6975f241df0bb9e27e99dca0b555ed294a23071664a7fc9039838a892bd4cf9696763637 -SaltVal = 00 -Result = P - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = cc848fc93ced6a3252fe844053b56f8b8df90ac8ebdbb035c81baf3801eefc424efe25fad2b38698f0b1c08e61a2676e8335fb08f4661ad26001f38e9761fe26e37eebdb9827d89eec8bc6be09fe4ec461fa909c42646df5aa11f6e95c8923e1330bc9b3b7d1c60eee947e1875538c55ce51b1cbfc5d10644d559e9378edd43a -S = a2771501c8d96b8f29f456930f1551f648abc58e214854d44c1bc32de90c2a8d269ebb1c30456e710fe411483b4c931d40a7c300e731ab0897f976e5c5aced427bb462acb998ddc23031c84efe0d187930254e0e0e1f20c9155ba23f7d2a02f1b390db18c71d37f175d13f44e421279ed5d803ef7946ceb364dfb42114b2943b446ae2eab8932f19a87eb449adcae98223f333a47eb028dcdbb9a8fea2018b3e9bae3420d99d288daf1c13f9eb9932814d530d1f8cd0f496ab21aa984f5f2df5fc5f56a6e7431542864f2ee78108eb4ffdf98d50b8bbfff626da4f166881d8126442331ab8d4d30492473a6af9c1fbb08fbbfb6bdc828d2c2419a302800d21e91aaeb39a453858f6f2a3675afe000de678e5095b9b885d1b02c153dfc48b33470fe8521afa1d36a18e2ebb81d58e1cfed3c0125bc8c5635cb88ac78e03aa6d661dfac9bd2844aaf98b6ac7c753543865c70a34c9f49b33fa63bc7b4f0b4a38279fc413482f2757b287c31f83c786d5a55438c00d1f3bff8479ed3992cce425a0 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443051300d0609608648016503040203050004403c1940aad46377052b5ca5f32e427fc60524134f6b125784071ecd029233a6b878b85b7f3c9a7ccd4838fb9352a468d02f64a6e19ffcf2e2158aef7f09033d5d -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = b493cdbc8bf23247fcb00bc4ad61ee808ccdcfaecde823ff2f04467382451a6e6655f20e555aaebce425270145accd9b11bb8ed144e6fa038ac2a585b955cdae9eca3d2bfc697199d2c7fb54dd3a26895e90d8931d01bd84ae61a101f39b1e54e25a78bc8809c5074efe51637cf24072fbb5759c5f1fb3a9254a028f38fe5588 -S = 301c7cfbd1d8fe0d725cc8854a9ba1c7b16a3e4c0e357373a57cf22386bc562615cea5e5359d90eac51e558a15580622585f4144905b4dcdecca2e42f68010aaf8be6a17cf2fd4a5ec77871c2229912dd6318f365214939e785d2e9d23c75eaf8cb3c9ec8a21d15cf7186aa3e92e1c1209f054c335fbd61ac9c48244ecb4d607e3bed905a930f9605855e9b220129ecff5239eab8260fe7cca7d07af495a134dcd63dbd71c72205d11613ba89925f7bbe36c2909e9dfd40596f2b6956e749c3710587d4f1c304acbadf83c29caacd3a1b3f0dd332560fb8802be3af45e6e09aaae57d8b8c75441f310ddd927a3279243817943719451b94cd6d3cd62c8e1c15070c2fda9baa2534018279d36ccc15fac086cae7d430c44276517d1e32082a6de8d0cd7d88900f9cf4a5e7012074834b9783734dd1524e191a63e0c6eeaa5632f6ff2c92f3d05589791d8e717f4833cb5640d2444074e881419cd521fb7f5f847fc1852c8e17ee7c7eb3d808c9870b1f81ea69a54b361b65c535e0dff70278c61 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA512 -e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 22987d4c34ec4b902622a8a6aff3dbbdca802c7c05de4b35d2402027226d4d5dde12cffb23315451fad250d344806558b7852140a554f05415f570af785a6db622f1dd0c11a3e64bfae2bd0f59fab4f2bbf50e26c14f1c58a578d85d1685e896d9ab6acb9242278394dd91c275d8c9efd8ff0c4ad54ace97ed8a75cf7de374d4f25ca008551f66f62a6f62f564f7cc4af8800cf6c6f65b08ceda624a3a98b8f98c0374e7fd2966ea7fa44c347e1c484c5d1805d81980db5d1eb193f48c111c02b8a4e987a505ea5bfa50956717f77a3b89e47fd8251eaf35b3863c3e32a01b6271d8f793074aea4d0ba7eec8d1cd23aa967c7bde7c2ef919a1a9744902fac439ac3ada0f604e2c1edbfc4349bdc50060f0a0b2e46ec8ad9385d63342c1cf5eaca1c68ade01acd711b96f3e165458d53ba6108bc784dcf36926a5f2e2217fd8afb78f46a7935cb27707a192ee7379c72b74342fd48d7e43b1a446a01264eb2bda68954b310faaf5dc57b524a4942b35f17eb7b69ca39e609e398e9cbb6d7bc61b -Msg = a97ba5b9773d187153d602d121ec843f36ccc618105046af44067093b78e6e11114441fa6f2011a759dac139f351c725772d3bf1e2c32d38ee3a3cf441ec64fde40f18ccf6959185a25065354e5a5b5715b47e9e782d70ee508601ab07d30037082452b6746540151783154a9ad1e9ddfaa9b8a73956b7da5331e741730beac9 -S = 2f2c9aea6942c5a24b4e5e04875eb5c6f44e83d89ccf1f13455890e2d61f2b7ab464355c5cd0e7e9aecf004a0b85d0cee852a9681f4792899731f984e2c06e47b8dfc4424e4cef5b9f15def45d528a3a275fb4fe7a194ee7b10a6f9694e8e1659d95a6f915fd79e3406e05136b244213ccf67c5e2055adbffa85896591d7abff96f6e68494dcfc48440bf66cae21d1752544933bd22154756ad15a3c664188cca88b5f23a6acdc151e62f7d0bfa9cd60429031736d7df76bf2c12f37c338a1174eb42cb740c5d38c1cf1b682aab8d49443016cbe397cc0c44374f29502d997bde22a45efd0e7c801ffdcf1b3e42e93b955ecc0eac9f5b71c349504e8b2973d894f0d33edfcd07f9fb6b3cbee593448bef9590391d13b661e2dd18f70b43b59f2e79d65905f9ffd8ce0117e06e610f34fcc8dfc72d6f0440e2e6f882747c5416bb8c3ef6ec702164b51309d3df33a3846237a2f0ea8dd39ffbe0a8d549cdddd063d7d5a65fa27acb62f46ea9f467dc0defd426cecda8afcccadd1fa3e483d5fd2 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -[mod = 4096] - -n = b10935650754c1a27e54f9ee525c77045d1a056baedc8c1ba05a3d66322c8e2e41689ca02b8e6ec55d3331cd714e161b35c774311540c6410cc3b130e65cec325377ccf18a5d77054afaa737e65b68662327627f5d1092df98c08b60a3ba67599b1406986f441528d2f1f5d6fe5ec6b8aa797dbdb3162876b08298237af81c7004863576af572ddd66c487cf32a82d0f9fe260f8f2681613208aec55723622f50d3cb3bd33b1226d5b5b9ea2c97a2c59054e31536849ec2f0f2597c077e621ddea0a22ddfb1df925c9f1941cd431afce0398d28e736cfeab3dd7f062a65a2a4c1ddca1f32afa03b4ddfd8b7ca40cc0ce2ed42229d753f03cc6d8bcdca76ab7c2703c5ddad08aa9bf9a27740a8b23168c6b55917bd3d5c1c057c34d1efb1411da51ab745519bd92b9432fea8fadcb9a70e5dc3adcd3081d3333507b7b998886e988296628dd7265e64eab557712556cc492377f15a078dcb620a6e7f051a1fb8754efdca3de253dd0aad4205b032659e4a4fb307f074fbde340702b5911acb34737d7834600cf2ac77f62f83ccc9ba78ff911021b9f8ad1bf421430ae0d64916944b504542c0f6263c48e5e233ef1869df1efc2ccf6f4a95e4db2de7b4cb1a992bef6573511bab4bf2cd58e72a0c235f56dfc182df4dfffb69433a5677415f35d84f5125f5200eb57868cce6b74c5833417990e318372c9239a36dca1a0b28809 - -p = bd4e8bb7fd7ef1e39d71de06b0001bdadcc81b0edf2226e0d056b7eea70b2249000279cc1c04b1ac2919014fc3fb8b62baca3e261601fb0a58a9f67f03cd60085b2d43906d36ad014f321012a9bde9617478a0c10201afd53f2207de3648afd1d737afadf7fd2c0b9824d4f66b2c7dfe93390888ac088c680c27b1b2486659ccfa8986c8c23f78f18b5815a410328e629e7440221bffd8ec4722bba3420da5234f898f8cd7e6d7dcb1349bc4a0b665b41d930e3957cfdc88797aee5b2b27dafb5ba0949e3dd892f490212dfd249f4b1d99fd3b72695ee0652997127f0b9b417fa8365ba9fd103b978309d9baa9d401902cc107cb8d2af7ce04660900e3707ab3 -q = ef67f69838735c055145d21fccb42298642177fe3fadc39070a95e4fc04ff058aeaf9070b4eb2de1cca72d8533bc55206d2ce9f2895b148da67c89e5b6496ba682f76bcaef69306a7fa4fbd41a838bdf0fab3e7b56c27a8c18dc4bf970364dff7427cdcc6f532b49712282370a718b7d5287bfc02c4abc35ccb2eab3777f5e0d8a27ff9ebe13e725aa0a0cd48aee1fa33ea6b4ea965ba42fcce7af3c528a6675cedf4969640f2ca73345dfd322620df9dcf16520195df8232061e2bc89c12de24838f255e7b1c17713ba435d5a351e263350198b3fb881b8ce0acb5aa58b7afaff184489d167c9af21e40e2ba9fa69b44a3854329385c97df0de24dc283a4053 - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = 200ee1828829d9fd27576e253ea700245c38c5ae78fc76e33dbc4877a55d1e10c961fdeff8b1c0d306990d1ae614872a7b4a450fac578465b74e9879c77d29abc8f39b177a40ce74c47c083b4c8b2f0c449e3c4f87fdec17e405b84bb96c0807c4cda44037606ba70a0847d0959460945e3e90b4307818be6de99135a4b225ec -S = 33d2c45a355afbb8eb5f64fbdc4bd3719afbcba36d5d4bbc697887ecb7e7ecaf99bb31798977e3385544fd4c44efe1b05f2a34119bafcd6377c24f57c030498f6d96148677079ffa05a253e9499d6b13d3c02d5347dd3263045919f1a7169f4297cb4ead2340e6706269a8607b1575044e75adcb94cc7db8ed80a776ff1e56d1ac13ed7d82439750d51904337c63bea9a059a056f30bbb8c1c721a0d666cb843b1a8223b197a9f48e3941a9f6d8cf022dc4edca612d057b2548986698f2a53266f49e7995640eebe929fceda0d33eb24437113edaea93e8d7892ab14b25e851b88808b470a90bdcff021e798ffbed003b3b9c8d53e4a1cf77aa7b5016a2ca41d4da22ebe498c73bb3d0239cf41ef7f404fd609d390c8c1a0d2f0a6817cd3ef966196d64c89524032b6ddfdc6f9d6876d6b9e1c55010969238af5f2ab616bbc9234445d07f2462aa907b31a08677fcb9236206187e00888b53e925c334f4993d3f18ad6db81ced54b666fc6513da7a4e8a8f1c0eaeb6819cce7cbd27de9f9c9718d900297247e41a704b7613221fa114cf145a1cdabf4217eee25678a24420c4a75f8d444069c976ef95d61e5abed512c01cff4b864038ec8e4aa877ac501664d48be5aba39a35df9b3b1ef01a25ebede122b1797494442420e0f0d0d4b7c49d85f9ffdb102a7a1e0ce6e4a99d9690a80958ed548e5beadec583c192316fc7311 -SaltVal = 00 -Result = P - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = e0dd55521da6bd181813a02ed22eb20e2f5d9070573846be5d9814c91ff072ba6de1514b6d08a4373d1b1feedb343e8e426c8a0fd6ac18bd02c052ec20adf9e799456b294df822d035ed7e4e4652c46299f06647ca02852b9e47b4e2e856ffdcad322c54861e40cb46b245b5dd2f4b727c10ad7ffae195ee7754c2133f928981 -S = 2c89c5c5b481ae5b632c628ac42501f9df48347c2ffdc7d06526d2884bd5dfa01591a0a197bc87c0c3e2b9fbd6934a29fe5039fcf5b5fc89c1731fda7e274e706826740dc352d95c470ec799bf4123e7d673060de89d217acc23ae544ef70e4bcff3af691123216582b4fb6bc277a1c364acd0bc7a689de95e2a90d762ef4ce7284ae0a9d42f0ff37a2f6a40da956cb08ef0520df1e5c9462ebb5694d93ab5ea7ab7cb3f1812eb06ffda74f651d15439797ee0597fd00c5c08ff08ceff35a44875afd485126a9044c0635c4ec60992dbeb9cb9be19541b019a270c85e2c7a31a687f96f13b75a11e1cccc0257a7a9baf665553ffd34802aa23f0db466ec35d8d5a0d6a560c75b0ed1f434ce06e23ea582e53851c59824e476686d027810f7b46f31e88969b8274bb3116277ec1a3982f26d6918d4919b2fbbd161af81786842b57c9dd7f388323dc377aa64dac6782abbac9ab3558cfa8c989b8df8ac5be897c848cfe00407ffc9de8f3dc94a263182523c31efac84120c3262158d9190908479fcf24343192b86991a15a2fbea0ed8ba12d7644af798be3205538ce4e45a437e116a1faaf527614e57a4fe2299c383fa2383a57b7e950eee956dfaad4dec984a239fa4e09586113659126658581b62de9eedda4a921589b02d2f24c57f2827b4044b8709bd688a8a114fc9c875973ef145ca1211698bde58ad273c67b6a5c44 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = 22b5d51cc4048a5a3188dff7caabe8c2f2d8b59fcd3032da477f4cbb596e555b88faaab5ae249300fcea6a3d4077000c64973cc3376d05c171686200f173e0ea486c356e7bd8225205d59ecb1c4f304b35779d9aca71c3285b4dc5a2b33968c36cf5bd6db58701f8532fc1cae69d41276e621f4b0da534b60f17bbc82729b58d -S = 297bb0df8a838904aab3f7a517cc87b6f5f4e53e314a2f6d0270fc34ec94da9341cf86aa8f7de3220485f0598a5907ac559e89bbbb1e6ce4fa2f1a17cb5c8696bbce34480ca4f7b2bfa2d446e028359fdeb265af0e3e1bf3232712cd06ae681d7c5e8107fd9b088931ec27893a0f2ec6b1b9a1e53e0da9a3e19a2bc840366acb9452099fe221f28a6a8913f2d866d3d0d4127ec3a96c71099e5ec63be473390c4aeb9cfec8a651e812807bf8b3dcf75fad8372382f86556924ab57dcfd59a02b9f3b2da272c1c738fa6f1fc3a78cdeaa91120cce66b9b3287037c1858645e418fa74a5ad75196e0d10d38052cd4ab8e5aba58805b4bd58daae20a801491d042180019cd41b70559fd9dbd1cb505c7f7feac497405697866753a8d3e2a92f854a988a50f3554ea0aab86e79d5516db5f729cfd4e2d1c7bc754d00d75de863dbc5c254748e805da04492ff230aaa89ecee80b5501128bc37646fee92c3714e26fda4a120f684dfc043bc26cba3347a3defceedf425e729ebc0f7199a348f29e500a0cf50bbc71375b0c7324f41db18f7e3091c9435f3238ca879e61684ec7c5e05ceb3835d4a3efa4d07ab918a4c0b10f01fc8207e15aeab15d21fdf032960fe5235447bd5c6eddda747e8d9e11c3d05612ca1491cc5d1314946e45e3aa1c6b1756dc906168684685133375a7d7cb69ab04eab56cbba728e70ae8d4deccf4139a7 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = 709fa24119653806778374d1d9574c92fef4959886c61958a97ae96a2918f5d48572d98b70c2fa37818fd2372cd088e5f154c41bd361c1f60c9ca4d9ff280cb56e12ea88eded932497b91332ff0ac4766a6620553beed494ae401562c99d379990477c41792d2a561fcae0ca3a4b29cecff0524ea4b479baf730e70c6fbda007 -S = 0b7c22e20bb685bcd1d871bd2466cbf02994e50238895ac17cb51bc630b646f3ccf7d1c572478d762648e958e8fe1cc1d6a3b5eb6ce85bef9a01945cfe9755cf2d55875ed9cc0b1980e54d9d11a64a4855fccfaa3c3f4973bea94717b18bc4960734bce689a6581061a85e6a6e316540d209e6044c5bee56fbde7319716094ebf240133b1c2dab38565846f0603efc68ba43c36f439f49f8ad9110833156a72435948c3581c2d5bc1dd40441a5d63200252cc9e8af7bad81f5513313ac3c3665a03cf2d89c98b736d3ae566a175a979885d4d1bc87913eb1c755de17d2c80bf91baa108027af75e55ef8c5f13d26b4ff88ba3fc4b9aabfb36f90927678a2838e374eb764a3773d769ecfe9fbee806b30d3b1828fa1aa8a082563ce38279f26c09b898ee863e5eaa868d9a52a35612cbc5e87e5202d5f1fe6608e0d20ffa9641588a8e60cd0f06b8455f72378ec5e75015b4e3933c3a8d8c72e204db29e3327f8d3c30f8b9150760673b572c0a1af15b0344ffc3e5d405a208fb96b2f8f03c63806351ae34108dd8f9018a6220c67d962c76fb09579bea1c43121d467e05684f267d7633caa14cec7c81fce053aa121922c190f042bbcb08e37dffc6b7f7e022fe9c937882c27fd8b4e8002a53efd9e7c32cdbee30b373bd40d547c07696b3e854e4fa66b4fd7b9ef41b8f6ca5e6e7acea19e6e624d61e24494bd93ae7226d686 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = 6b9b00a0420a1869f6fe4de18f707dfa850983b626efba9737dfbd56de7c71d8c0e6465d668fb9fbe54a1e4bbea59c6203797902bbbf971288a53f4c87e21e3678468d531f95169ae9953327d36658318812343cc965358f12ff4ae97ba7ec70dce25fea34c4352f4c0715de975aba505dfb3eca188899f71f1365958174e46e -S = 7b08a6191987f3def583b16c365017b9a9f4baa76826ef12593e448fd5d7cc49d441fe7ac0edee5dbd1685a7295a724bc0b1137e8860930f12bdda8527b60c3ab08546d887f77e74315d4a6be9d4531413914645d51c05008a7e145257af7e7a1e41d949f284be7a7f1ac71885275da46ad75b45d6f19785f0a7a4f18124eb8b2d3692ca9d7c3b2cd05fe1df60ebebeff90cdb7b18b20a704acf64407de123a553cbf21c2468a25595fe2e2f6c0516221efb0f5057d92d0e64e0d95c1e5500467fe7c1742561fd0ed03fdbe4795a9a7457c3eba1033e11af6ae64e59bb9c84412fe89551d52435bb0b717cfb8b029413ea796f6b69212649c97e5a7f2e2ac50eff7b1485a251154c6da8609765e3e3b5cc155f0316c0f8a3f6630177a881e3546ba1dfa404430a0910f71531b892c6964abe8cfddadf60a301427d9d43bd8bfffcc68ddbb1df8b718f07ef794d95f47650b0608c5e5beef2edd339021152c5cd33d6737ff3c5f5aff14ef447274a7cd727e4f9530e40470989e60e0849eb3eec1a124feac7b452dcb5ff002225bbacb420a60afeb10781e7784140aad0f76b01b00343835caff44983b0e681154478b951845cd26b852f279ea45f4f6887ba29976c48fc618a7eee9b7b110fc00f495f015264ac6e0e88ae0129748da755264ee4b1289882a1cbff971d6e87545cd670875c0ebf2464f1133ba5ef764d49cb98 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003021300906052b0e03021a0500041427b561ce228f7d5f0f8a9b1a35af930ab5a9cfa6efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = dbee53378324652b696ae9daee6d6ceb27bbd30533cb49efcc3e7cf51b64098ed102343d7352ddb5f54cb0408b249b61bc1485b8b85b3d27eb86b033d2ee60ad0e821191b7c6c52ef21ceb87c643d4fa2b1d661f64b514f38f800e367be3b411b9f651fcf68806df8863047746d0fefc9d5edf01e0e0b89be0b5fcc5bd4cef03 -S = 24d07b55df196ab4f27c5c1008b49b54d726af278fad7408c8006262756037498841b35db44ea4ef7514a1edb148da8ef08fef64ee14c3059e6983526acfa9e6e64af6e056e0e6a602c9656253829adf8bdd43950885e3a6a8f202d90a728e0377242fa09cd3de5108b8b06b44d968f10e3652cd8840daac895b08923b981ad4ae2bf4ecbd230afb18c1fbd645eb993b40ba4e0aecee894d76bb414e33c1ed752abc8c8d950b4a16868337b40dbcd9707b3c28b5d59dfbfbce57dbcb54238f86fc7ce2c6a5386388a73da4e65c5b2a48d620819760a6f64b34cea861fa0703bbcb80524c63ff64c673250e1cd922cc3fdce9849e9c57fdbf3312c2f5517abd501ee26bb06e7ee25e58b3051944e0e47e6074a9af1f6e6ab3879057eb82519521856dc94e70e4b8663d8e2af2064b75847cf02d814a77a64bd395cc1f3357ae466f4d9ffb5f0b808d770b854ea44295984a938337729d301f28bbc5e332e27dc023c96db9bef26664d4a3d10993fd6942372254ec5639ed69905eee6b6afb2bda04685d34e3d1e7e1b8fabf9fc1a0418623c014e27b9acf277097108cbccec1be5527e7baa2ab100d8ad16ad1046f84e728ad3daa98a681c7cbd520d1ef131dd5d588325b390ff12e7b565c04de481c03dbb16f24f96a9241437ad31aefeb336ff3a1669aecf15302b26528f90b0ccb1853881d89318edbf3929ec5bc45ad5cc8 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443021300906052b0e03021a050004149f14ee6f6cd3ed793d7fa5a7dceafe71ee86f6c6 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = 1d9f5b7a9786d2d493b4277ed95816559e6521ea07fa308deb217baadbbda9595fbe39308397225b92f2b6ef22a2cc7c50d91ee24d9bf0651a72f3038f646804a22288d4e682240e522f89d9449fa677c546711b0f0a86fb4df611a7a132ef996b33100dc92f20135ad466e24839ec6f8515e03e542f3a780c159f3f1811853e -S = 287a3784de71ed88e4621273a477d5570a0db6dd00d528ae7378858a01e7412a6ed335f30e0b4672d61a6f248ddfcf40ac8d827f847355fb0751e4ba40ecfcb9373a0439200778ce27391480c21938515d174db382e27d57148fd235b7663b9d4bd4b1f8bf1134900bccc5a0dd53bbac5336363d8976e01804b9cd089700fbe7ac7bf61f511e8fc3d0cd28f6e6207ef9d5757b762ee96facb746d7c514526b5c6afc71879e359130bbbde3110b9fd1d35c2c4be5a0246a53b164b3c6b5ebc96f10657d2faa629bbff44cdab4fb9aef359251f3b7e33d96bc96caa65a4ce7ca31ce65be880560469712de61585c59c3513bbe87dca0076670b142fb8e6e65b18f21ed0d931a1712a4c6d62cdb6411626d70593e97716b22d10d3bfb6420f8471e6c75509f6495bc1505a8bf8172512cc20dc76875d3adec3a29dd7fe79e258344e8cd8094520d1e4e07e20092e5a4dfdecc30625e9547b23c6a27abc6dc058a2e51f769f6a232fbd09577da3a137401cd1c6e4c7ae959a52fdcf1f7aa4856db6e58fff070e20becbb735dcc3c7a2208ad7cef837891d20281e2045d47a37ab9e7eef5234de2d0e9e5c33b48bf8d9475f96fa368a87cd3bb82b0ef167f5533ed365e73b8e64657dc9c616794d4508042bf5b727d60cfdbc4999e8429d02ef91156cc74942fc08e85a9e08630887dfa4d820bc90c96eaea99af4b6c90beca889fe2 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = a96a3d33f00d283002fe250940244a11048a4bbd3c6d3d5858939ff767de9ab07c2088075731b4a9413f605d38660d374c80f60e493fde3196790b565dc293d3ec40d6115cbb4c3d70f48140bf385df21634a98a180bcf5a27a6e1b9884cdd40c172303946d4785455c48e9c1fc2c4aa284e6b18f0fa9939d3c329072ea1025d -S = 553b659961b3c76e6ae1f2cc56928e90488c5a6c8c8f6be7885824cd69730b356a57a42f7da21ee061bbdf8354a6ffb3b4c96948a7547c77e6786afd77bd6507aa159919d0eb56384610a18a971c396f994cb6f2b426fcb0b96a12836ae99f6f1e91de39a90c6df4e88af34dd59ece75f1d841466eb72634ae73fb66b952e4a7f071f09777033faf0bfae8fe80d7b45c3e46b063c06adaa71ea66e8bace380d35fc8dc3d61cc4687655b89f2a74a41f29f8ea4b77a806a0239bff08c596392e5a78472af3cbba23bcf8145ab3cabc66d04bab15a8330cbd6f626673fd16c8a30a6c4eb110690e2d5bcddb327619887a12475e0d598866123b2604e3d14750e5593276e3830f11cbaa30f7ee61479ee05788f1f7616053b98599bb5246261de3e90df969d0f84dc41066305ca493e5c814cd199590e6ee20317ad9acea9ec22b57185d334c17855485edcc3d2d7e939800c12d02b4bf818c72bc03d9d06c228aebbe9dc7d018349fc9ed8ad34249e05a99cecf3dfff0e2061af2e6357518758b1ce23db5bb2d69fe5fbe64b3e08b193c30c647233a60372e64cb550f90a923321cec4ec692b3d2caadab37b6fb3826d591449ae2ca3a6a754df669f3a5beda1b191a8a2107c649d69234d83ceab0a1c0f65bbb9d7f518a0106c655b86b3a280dfc8c75548612b01bad47e7b1c232a0af34e7de7291eb9e747292e78b61fa0c174 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = cb9fd0e59bc6d0c1b1ca328db6bd9205ca50ab8526e81dc000f46eb5af7d4edf10fe1fac2877b4310bbd591cfc1414ead5ff2b5aaa57e621a99b96df4487d65293e811c9f3ae45dcf443065b721bc584018d52798fe1a0f144aac92dad56512e1a03af254494092b330440325ffb2c3b169f29ca1dadd2979ac80c87311147da -S = 7a0a3a76ee0fd8be7ab380c909d18702fb0ee2730c61bdb7fe5623fe62137145bd555dd1945ace3c46888afa725359bfa21028dbcec113d14948a95a3ef8fde2a454d56627de249a7548306ca4c042037ec8ded524926237d69bd4099383e0fe68cbfa1d13542955aeca3fb27e1c21dbec1f6b763c0e5df2efb9e3b0a5a5ee439c91832361f27237f7570e0fbe93ccaba416a2495daa38a7adc15c5f39ceaeeb9240ef19e6e58a07567fa3d8fe5cc375ba28d15395a8afe98b71162609a06ae34035f6e92e7e58c6e814aa9714880fc8403bef091396ea465bdede70706e514431ece1a30b6b0e640456a3c353a790b5e9fcd1a75177aaa092af6cb07221df11b9dfd9f9e7be02b2433841cb7e3db33a5e4010b0c411e7c823af510c80c5930279b7f655c52d7abe24050561c5ea2f290a8e59d17ed8f7873446ac329095814b47d2710648090aa52b4e969298968e313f7f7e49599bb01fe361e1d16ff10d25eab366ea47aed18c98fb87c1ff915bf040db4a46458e12173823e541a47f7fa92377db3070cca6ffb9b78e36fb90fd662f47605b8872b8556c886b84a774dce72f92f8f673f55f8bf24153c9f18753ebae13d999ddb8caa25fc75ec58f29adff866dd5ea68aaee641d9e34c3783187c3383f57a88ef1b72e90ff9f512a6061ba922954f63cbc0726b2935adee477a14e6b38e7115be26b314e456c65d56b3a07 -SaltVal = 00 -Result = P - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = 0bdae31979864502cc9e0cc38b9d97ccb0aa40a0076de142d72197e9c4eac5fbf4695c39718e5a37ceae91100ed6aa57c15e695170c133613baccdc3c154667d400dd893fd192b7be7bd5ad0779a5a4bda3b59ee52eb4482dac98b44091e28dc38edde8ee7ccbeb45df3f06c8f93b08e436997e175921c8efaa15ad463ef14fe -S = 34a41f46718ae045c386405e56268514a7baa1fe63c6a4e1c963b1a43010720caee088df14f3ae4681a5a63f89966ba2ec3243fdb80514a977004680770bc8e7069acc7aab3130532064a74f14e86356708f32829ca06e0749af4c6fd8210e2137bfacd11087630828afc4a15d01f8bc1c1a59eee3b6815e4168017dd572136af46860d0ec0d8b24d342d8502c09528fe02ca39c78daa7eb6c6ab0d9f063d92338f68aa7b165b05d044e7f9cb9ba1f059058c15b088a3087d6797658523b3f3950ff37c7fe135886b0b309b5e3d259993e1373e7c86626497c573264d928ec0c3d653cbee9403f12de12c7790c54e0bed9cbbe70aa78094972bd921cd0dfed81ea6e91df914e83e75dbc714eb89e7dcf3dd4d71450424898133a9bc67bd4e103422cbea4adac473efb16c6b10ebe089ee60034e0c599f66f836574f7207180cd6de83e3708128d867439a90748676fee209dec01acd90d5003fcf7dd1e919bbb3ace60cad0964081a8eaed261c5eddc7384297731cf9cf892730b938e8aeeedd60b06617fe7639c2f3493bf96cff12df30b19ae86c8edb0867f5476b6c381301ba9cd3ccd39b12ba11222068878550cda07e217185eea14f75bc44512490d1aefa18ed11729867e4e16eab49770747cdca5d4c39b451d50ac9432c42bf3122da7472fd58d95ce0937d33818449ece98b64ab39d1d0e0ed5e6ac11f5b119dec8f -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff44302d300d06096086480165030402040500041c0b8e0726c9d9bb66179c5fbffb9b336ce88a54e819789583af5fface -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = 0f46bac55d9e2d3bcf07f70ffccc050fc35fd35232a87629a69de0533413607048d368b88cf193ed0c59e68e97ab574e68498bc506aee4646801bbae5de9eaa52ba48e8376530bab649850dfff635cb3db090042f897e71fe965d58f36ee2cf500deb48de36d9b5d21ecbb69fc9d1c2763c8ba32d10b884273f2b45c89c82d46 -S = 5ac96146da56064477b2994f953f31906fb9f546553551c4c76b4811074194dd0a4622e3a53e6c9d13404dae87e4f13b7142bea20336ee033295f2ed94405d7ec0351d880c78d753ca18dcb6b39735c588e656aceae827c273068097b39d1567f921a4f2305f7543fe2efeb0ec47a0dba7849ba4e919c388cf05de325c2399cf84f1a167a0895a783e167732020826d5735e8b0b7cba4ee338ff586cde712eaf638e7163ba45ef94818f73e7b7160243ac366dce1730b9ac0937532607f9d5f24f9fdb1e227150d0df91a8ebd951e7aacb371c0ed053c204b22735ed7688d587cba4a23f7857d05fdf97cce9f363389832c35ad291757c0ff8ff1e5a5075aa97856cff7838d3ecda3450a7c9d27f0617ec80c94a2e2a09028fca6e613f902399ef4f783e768f8f62e097a2dc52dbe096bab99cc4d01ca7020d72d0566cd6b8b0df6c1a1123247097b8ecd978925a540e05c2acd9d65d3e64a6b05702824380c1a24bd67d66f2b623f962e89087f08c5695b3f9655fdf24856a9f6561f4191ac338d67e90bc0c747ef7cd5a115d47aaa9d048ebc84c098383260fee49bdb446d1a153e51b0041a5e34bf71ef2d9b579067138a492e6ac8a693da58d5ff37743de28411d56090ee31f9e08cfb8566c7067635a30ed65cc24d40e1084d6c4164740d0770a88a287897b34fc4490a7f565827d8139577c0052f4760ef17c5f5978a3 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00302d300d06096086480165030402040500041ce07ae5bb44ac73b9490d62cb7f02d236e95b023c7aba070143c6243cefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = ec287cdb5ee54e8441dcc0662f98420233406c61c6bd9255fd1f9701003d069bbe9c5e71df93ae2afaac624f094c5d0a1a97482d478e2975e77a3711068eed5e13c85df5d918c7e7b1c46a47f50b9ae9b709136ab3da8d7083029033120c8a3d53721f6e33bdc042cced7f57db1b2129745d7520f4eae5ce387f4b710c0106c0 -S = 30a67f084b071c9e0d5c5f3f797cd89441932da1e5cf9b7788855d03f6f2a52d6519ae67ea7616d76f2a73016dec5663f6e337c9c26ab3a4e0bb6d3f8ea18d0ebb1693ca5419b9cd19fe747f486f8bdc40164da9d7024d7fc675b7f87b702615ba523b59a747550a26bdb8a80a57dd14698a17b6ed4c4f04fbcb3ad98a2190f02f508b681a517663a3c0a4516f92f87cd9077b674e716099e36dc50ad24f98bb74a6afd0f85318a67abdab02fa2853d206acf49f941706cdb0e632244f2be99ca1aa9cf36f2383c1092371031a99b7342714fffffbbac48ebe8fc7a1f31c40834090d7dd9d905047ec08aa0c73d1b2a3cdf6c10d3930db3f8675a97ec1cb175142725bdce1d73dc97f656ac1441c967475e46b7a94ed38d067def9a54bfaeca15a49780f5caf2e42ad3b5df0787c1c06844b28b68dfb0d675e235a4114920e327e870e2346572c3b04aa29ec476933470a0e56fdf3ec0f5e1baa35265637cad3b24de388eb4b68403b4b6652ac1c258cc56bc4cd9d3d804632da9eb23445154fbf26d2eefa30ec2916a54b052ce58baddf426680477aabbee34fc6d98e57af4342b2942c77dd8695103487203a77d4f8e4ee066bf003f45cdcabe7b57b46b34084bf22eb5c905ac76df823a0e9343fbe4a868a6e0adb58bb5725b8da3c03933d95b4012498557bb78d096b810be5f403b9063243bbec780de51ce927d7294ff4 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = c9228bd9823d98cc91944bd362aba13e16f6cfc78d9fea74c383e8be607ec7f28ae80cd8fe5f6f935fc7d5c8cd907e02ba378055f910744218426fdbf01334277a66a7c8e58185dbe51453204d77945be0343ffa64c570f7f99f5e00a96f8dd640a345f35e2c426fca82ad2409e94b1130f4f5fcf647485b0da09d75b3193bc5 -S = 7ddff91ff1168c9bf0843a1da3c141e1856e312c0d83c4052b9c134d3b0fa82a53e4e1923b051be39fb6245d6acda63026161feed4e2d56d83677ebb347b1849d479b3da628b02a3a411f86c443e7807f6b5239950bf2b060da1c6905dc75ec2e4236b8cdd77419361abd4720267ce447c104f437afab32af9e1b4c0104989ebefbaa7ec0c18a065a0c38a79ccd9e40eac3554d78f3dafdce7acf06e19e7e2792cd7c70bf1f0eb15e32c7d6c41331ad8c8a1bd70d4bf74e64548175d913999aa673c995bbe8ae3e68c362e3427c116290a9680d6d7b4be07de3cdeac0a0723699be8ad032f794610510ec4f61eaf355e56e15d053007b1d228a91b1f576597c1c78636c2202ff55c070eb3242b48eada77b90777001067fe61907ebccce40bb6b6361add71717c3a429267147b341bfa8bf0400512c538948a9171f2d0aa278aef5b950b5b7722b372ed5c2ba1e18562f0fd7b7da7566f61f5adf1f8ed1023605f360872cd963286bb5685cfda4968f412922df0b9b7cd0ffd8dbd16a2382b6893b4d075bd0965f4f7e4e2c09b0bd00217fa6bcf9e0ac71309e071c4ca0077bcca9c60ee5226ef058ff8b7a076d68cf161b13dc90d51f65babe1f4727396f070af6b3dce92586e0d31028e6adcfcbc32c71551c7d688cf9c32fbb26d03c5fabd455fc716d9a9cb82a740a6a46627d80c75035b0bf02dac08ed6f45539f035885 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = 91e945fbaa97924f3e6d9ad222bb01e935b7b41df0c2207a3eeca2348eb93e9127269302bce70e9341f35f86fd42293bdfd5fe5415f88a16dbc40e1191e7110311a852fa3f2500b9e2df2d5db2798140b1bd2b1ebfe01d76690779330309468cf67768295adacf87c83bee9d69e96fc0537625c41603426491bdcae30ba847f4 -S = 34dd79f3254da1471173aff6aaf54ec5a8633b468af99d925ec258438f3bade74fd1f23c631f94e6db57b3fec9b05ffb18013cc090bcb1f871e011241b352549e9dc72349681c10bdeb1ef00f99d4a70c48488d812bb621d0e3b926876b91da56541176dcea55152d31915f9e633620886f6264c70c2875019afd51eea4ac8cafc17842e2e035233d4679cb22d329a671b061a2da194d00dfe6a3d6ea3c3b10369e0558b68456b241e7c368e2492bd0d5cbbdab42a8526acc04cf2ed43944708e99980b31bdac37e754850c0370da4ac8b71b5147ddc91dcb7509df44b3fad89c2cb4e147255b064ffa9ff758a55c045f27bdb4b12107e1820530431a28baa16da02925ffc8e84cbc7ecf70c2dab46e246ac51888a198d85dbbdf4be40e674e562533667240e043a6e8a7d1a026af2ecf6a1cd24934f6469e28b14bea0f46cd333b1043d837b5b21022c9f7dd7713f8576152431746b54c9cb9a7ed3bb5c7d027281cbdf9377187fd584b8761f5f6972ef357cf8c54c9009d9e650aeb4c9d718919706d48ac76c404875e95d60b5cfc06588e1bef0ae95c31d13a27edb86dfb643d9d2f08373d7af39783804123202f796b1a01da28932a103a817c368f9e8bc8764cb949e351e0cfeac9087eca02e097662020927940b84dce30f22eb053c02f6345f6de59c2428a0c462020650db4e93c515304bd6fdfbf882d29034fe218c -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003031300d060960864801650304020105000420a20a34a9c3d9d0e915b9f010007a3c625bf71d96211c68cee82075ad2dfd21e7efefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = c63bd2db43b2e094aeeb020514d2439f6d8d04d0c40b403398e0140481507ed617a965880fd7d975a7329deb459ae2df5ac656de8dd95d4716369eb86796c2c6125878f1e718bdd65c825aa73368aed95613ad1c06d7299034ea51362f7777a580ed16fe129d13219784432126652ef6291c1272762e2b77bca43266211a24da -S = 18fe9f7495370f1b1a8318e33ef759e72fd463d358de45d4aa412b1c149607681d12d7da6b7640ff21b53745387e6a5c9effca633c0c6d1e7c150ac6b622981167fad90fdef6b0bc71bf87cf7aaff12afeb60c823d95b32e29f84fe500248207d792d27965f915cd9527a666985223b4b2e7d72b1819cea49c825c304eec56632188b0907b54e2fd9d805a53e58acd08b291532d9500c64ff406d54c0f43e16c5a6f40499d20383e6537bda582b5081d0db95bead3b436c7d12d5c9ac695d4b660c79feafaee8b79f4fd9147cb5a14f5c8700c868d24bf0bd086397deee79284b3a79e9b68560ed6e863da75da37d324edf13243556f66982745b2ae931e3f2348fd8c3f206b183cd8768183c92ce6a0daccaface91f3ad6dda20d5c604b5c474918fb124c494f76d68ca7192ef25bca03648eae43008f9c3482bdb7b086ea92d41ba3a243bba037f7f08dfc6912218dca0fb97a11acd0ec3432d1fa4fd73f4d810843606374c780b8fef34ec13fa6e26ca05124d8029cf7ee6f9cc90ddc1196e29c4a6ec9feaca4c2050053a212838ab901bb9df01e31b6519a9d4f019ae5bebe1bcafc92f79ec70bb1e1f1db62cd964b8a15171edc72081daf239b0f9306921444032295b4c7428873e142fd20ed2f2e598fa346f2a76579045c727de99294e2245db6d62061d1a2cae226f0aade7da4bc32fc6e750483cc20fb2f017178be -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = d34ec8c4045b0433954c81096a09dc82a0c6c799157bac1d2a949407c7ea480ba0f3b56db735951622014ce70f5d104d05424d166d084883501e029e62fe5fcd406087a8f6ae8d08c4b94f6022aa9d51013b9d7854276d8bcfde0ba4ee7e72dc3aff061cc8ad323002dc501da9d7c9b51b197d68d2c0655d2e3e76c27452c960 -S = 4082a6bb4453970119c7f4cd61253f441fba30c004ddda4ef25f6b9f30edfd3d2db0f207e8b7c34f2d9ee23d692c850a29e70906a98fabdfebb5fac91722dbab0f19ea0b3952041cc448fa9e3eb8b54965e068a2a0df68b44f2839b9d10ed07f9d92039772bf6fe6a6d4db2531a03d7eebc15a125b87ec9899cf7b14911dcc4f0880b2196e165c1e45edc0de4abf859f30d87e3bfc3cbd69ed066aeef26869ec70012f0c1d1e13ba1bed0a6260d0c412c8e4aa6fd0f8b716ce33fc5bbf3562e98c307b1b8e617b26aa3f55e3dc063f7ffe4d03844b0da97411f3996fd94416648724148bffc5900f1f9b908f2c6ff5ad20c90d3f5ebd76e3aadab7b9e9e55ef50ecf4d923249a83cc59167e65bf6593aeeccd750ef0c3f1029dae3fe1ee23678ea70406a4e4f9f1165a48c16659d367e2f1748e104ed1f898db701336c680400818cebb47529fcd1f9da787a025c316a2baf2c1d32eba2eab393830eee7a2465d0e43c19362e64266883be22d85a0efa83f3f837d206bfc96993d16199712f6947b39cf0875b3744d96705ea19c8a173aeba23c6a049aa668a66f2c6559cba601c4a8737fe512509e90eb5751abe5c45f22e9fe31dc936b7e80544daa4e26cb9d088a623ad6a7e70902196a0973b8bae0866513360a05265ba92e96fd8e7a09e35a239a0d2499713ca0e7b5dabb06d162fac90a75e9b6483b3513787b66b9f85 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443031300d0609608648016503040201050004206befb2ccaf4b531cf9ffc53f938035025cfdb7eeae29da84ebec94e716c003f8 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = 8f937d50d24a1a6ed858d2e3de56e5c23b917d5a936c87b84effc06d48041391caf42207ba6d23030ed7edca864752b99ba3b089b308c3d19668bdcc2578995d4ac9ac502b347de3a37cd685f22f1bddb3cddb0e0f2ca53a311b1d45f9464edbf55a42b48d69d0167d8fb69c89d6e8376b57277211a2d4fa0560075d2d37dc12 -S = 2df1e58e7491739bb027c6315a70eebbcf37b8e5958df07578a589a47cbaf1edb23ff2e676f2f273a1cc0babd22e0bff874529cfd6479ae5c7250f06579eb212dd3f4058c476abae8e94c89afe05746c3aea93155cf03195ce5f4eced399d2b61aab7f4060b69844cbff6303d264c4755be78af001d125af461fececad8f46a9c4b07420ca63c4212f80a751fcca6a4737684543fcf07b39089baa9995394766f69239479e7c9778c644e022dd4ec7e07a769aa75db2571e58a5e0ba1e4377e9677092bc9dee9d9dbb448441da8f4385b4d4f8ccff4b3dc3c3c3ac8ba11a6ce8caafa930108ba3603c5b0ef65a02a7afebebf605aa88511513a69b3086fdfc25c588c4d61a06219d0d5643410d3ae4d78b2f695efe4e0b82161c53bb9d4b8a83692bb16de8da18b4a6c2abbd0f6b0e24229077fd6c3bca918bc9d9f4518598238df0c925f8587fff0852c44e8107ccbc1ce6a9be3b0941c3b28bb03c87eeb959d719dba9a64a338c7b9931cdf6bb169686de1f8de0e1fa74d03419d164f2c8bd2030562705d1470415e48144181dfd31cdd4219b5d22f9a4c659923cf5c4edbde18e8277dae11264c11423c5481402e80af223f0c4faea0c2c7aefacbf513962c2f16af353ffae1414b408f726eeb946d7c4c8577e72d8f1d49ae2301cf70abee46d286a6fac1b888c334538abb3b830fae595bbb19ea9dce46a343da031117c -SaltVal = 00 -Result = P - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = ef737d90f65532a2693ef41fe916a2b970c411409d3801c54caf50ff6a326eee086011bdad6e2aedf16c17b047ca1a931b1a0a601d174843dce7f52b969d62734e02c8c220953a30d2d0d7aaabad449788695abb2c881b5cd819eba41b3bfd47ece00b66f6d14ab233f39dd4bcc8080de03868197392625a68ce9a32a31525b1 -S = 6d2d3c16eed39f5b46ffc45a8476c0778bda78d2dfd246ebcfbc74f88c5ab742cab942de2da36e1ec2cf65a43b4ff04927021211b35d6b6b2136ef1d69671aa8b95f6b55be4751a54b8df1bd87518e4a736bff9ef849cf7bc212734b77a7fcfd3ba99327884685a146294ba0a45233b03e97a27af2f615952261cbfdb1b5bac0f5fadbb8decbc4b16ac96606242a9489f20fa74f726d3c45e0e0c515382288a8ac19ccd3eec7ac94d30019dcbfbf77f9dd592531eb1ef4eacf9c38ccc0414317a3d7eecbac02a130b8bfda18f4e0fa6a5bcab44d35e020afdfda351afa1f9feab93579861d2ac39e6c8499b8b5777a6be5ac77b3ecdb12fe8189b0bfc00a4a3e4e6041e2d52a5112e8af45e5d0a45f0b88ef66ca29076738ed07129be4493916bd885e128359e860ad8f0c0d8fb649710cc76a0d3ea701a2ba1d7e77ff9b037c51f93e9b9e162f71da900c07b42ce0f02fa633e8e987cd063b8659f25d190f3d35105f70edb65201dd67d9565cf4e718f4db2f57569c8c88f20ec11aae3ba3bc1bc78c29b2364acf2f964fd2165fe82d8721f1b16b668804468f0697643d1bd0efc5d45f8c27b7804b4931e210a1eb789c8422d7795a9b156fd9762a56fa27b7d5adb2357797ba50dea7ffd217025876ade111d504799ef8fec084e061ca0b884899701a9265969a9a027c5337cb0e1e86d3d5d1b8a0a80eda33c8936b436c83 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = 5e59add32c339dd10f33de88b32b8cfc1dd8fe7684693e27633bbc0dcce7431bff7e2b943b13d1b8d47a44a286504171093b62a6e57392cd8882c4609648e5e880410e65580bfff0e422c99ff1efcaa9e901decaa89ad4e98c6d1ff9cba6ce1d0a2bbf0f2b210fc266b3d4469b0e0fede6b0dcac75e3ecc3968435a01409e801 -S = 5d7f2def0ab2f104974b66e6a7ed79a4cbe4d9c6ab4bed75f442703fdaecf0e76eef5fa5c13163b4fa661137c877e4416a3fbb4a15a2dd534267ab860ae73bb97abb5e48bd5ac60108baf4aa28eaa5b3aed8f84adf06063e575b39c932a565ac9689a6ea93359f5e5c384bd41af7627df06169ad4728e9b17f5cc7855b5e2a88d4417142bce9b45ffd82e785c6cc8774e3c78fa637ac69c90a2198909fb1b611ba28ec978b1813bfcedc2a4ab6f8a2f457a146be5a6ef6ef90a91caa3553f96a743ef0f3c2a057ffee3ea2b4a3a2c7e9b26ee2e531f8b17216080096527df06b83bc11ecb977053e5d81f6c3e30e0fc5d4353bcb7bd97906ae7eb4bb1670fe28a8bd674c836e395953d3c3e64503818e3c563284c7d21545e7038d3dffa0182b5e6a7ca50e07d7dbd3614c4b2006a4f1a14b77c3dabf98459cd33ec5b325118f9e65b851a155b3f73267950c92078c70fc5dff3e9f07a9c5ef42fc210b5d2b24a9dec7db05c12e492decaf4b448c9545ee492dc0c2a4a5bff2ed32a8a0ca0a41b7f7455e622763319054e1212c0297bb604452f82393a3a96f54b1a141da0edeef052d2f0382375e501d67b1a83d0b02bdd9c99fd68063b908da1738e88b2da99979abbf73e60a4a295d24fda59db64486bfd7eb5b8dab06dd22202d58422bd450f1f698d7ba51f71ef556c5bad3d1461481677e501dde5b613fb2ccf85fb40f -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = 655d108236ed81085d937f81dd9056d691a1dd531f2507f32a81b5dec9c4ce30388792fcce182b912fd785fbc3df60cd67e9a41e626ef4d29a0c851b082b313e69e0c79b3612a6e8d7db8abd1430a555ccc5f293e92bc643933ba8a3a4b862215c30586757231995bb6834cdb6cb4df528fb6fb89ca4a4ce7dd8c37e87b38a61 -S = 3363dc1b2f8be1f660baf2b61348786a7305f4bc3e7f030318a743893e41feb40636f768a286c0e82f0638eece2d7f53f8b5c8c5052e6a942e9a99fef85e8d5f2d83e6768515ca14c8e8dce14717af8fd5a2ef209c9b8bd314e5297eb48aabdb7875d1c33efbe9d18ef9021ec41cb54926bd3542243db8c576d8bcfc61b5dc6bc8f37b91e3d631bfed66d97e9a39aa815a8c138932d4b6087b5413c888e97caa07b54541f22cda57a9d06b92047276bd21bc5ed946650ce7f9b07cc2e150bf14233e8571a8f09259dc1620e6f55609b2f2a257dfe250649de5e7dc42fd7503809d0ca8344cc92571a91ca99abe1d22bb6f56e84ab0ccbbca0d8267fadf08017fe98ec57088234e81546386ea48725e0edffff0738ccc99aeff1f3977be58761373749175e7adb270ca322f15f866a668b3473f5587ca80fb61200acb3c09bbc087419a5d4a3408131571d06f09607f8d0b07a285b79d041842e5cbb682e11db41b0c36784c4c4895d007f076d3e3ed2a13d9f0601cd4e95ed492dd57505f76f119eb3fe56c899c20aa745335fa2df73552e95ae596b1ceb67e3a533b2df1ea1ed661fe5b46e1e31b753211eb44fe683e26fa1faee65adede0c86c788a067cd1c885ccbfc0066fa94070a310cdcd19003b6b7fc836c79f19e7e402a549850719c3cc3fb4cea67de4332680c3b891e0aa42693bf113fb7210e6b0d470d30335a69 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = ab8fbba0e6a56a02b0b42f139cd656416b9bb654da952b09bf1a46fd544542cdd33e3a7c43bb9a1591c7d491e2c354fa28aab5d1f39935ae8b8e66263b6f27f1ef4fd34c02eeb89d517ecb5694ad991beedf8127c2bb21ecc9ea0ef9611bc821284beddaca43ace317627d2a599c0fece4c3821eee05d70ca1b7a5406f510da5 -S = 87615e72a27b387de06e4e8bc3f2e70d24d061abb00a8a006456ff0b8bee03924307420517eccb0eee44c1f8a7458e13c0694c1bf7855d5ab1202807339bc82cb5cb3974b83d4000751fdced787295387acb814c2ffb4f636704de4595bf281d544f72d676bf59768389d92bbb08ad9662481129af3ea0ff2a0faadad65c93ab0029ee0ddff3ecd02e0bae13c4597de92cbddd6fcd9ba4d83688db7c278ca55e5c15b061993a1a53984efffc0ed72f55f79f3d11581ade9b651a6ddb5ad4863e3b9798d2bdd7c346174b114778f49ebde94c53c406ecc6812fec601995236ee09a8df5d0663ec4cb49fc47599b2b884cde458d6cba31abac1d3900fba8d9a053f02ceec3dc9f372b285634a3b21d4c7182c891523fc75bb8e49494d5f5eb4dd001c40fc549f9f586e60fd2f9b3b3dff4c8d33978193599de8471d2db11a4586f2be00c2f03d818ccee82f183f784c88a5d04e14ec99ef808e3e68333fefdaa414be5d7e817de3472ab212c40de7f172b3e62d203d7da871573f4f1fcd0f01f49258413e726cd91a79f465dc0ab69962436dcf52162c09fdbc151853327fe69a51ea91a339138742d555b40be06df4ddd594cc51baeac5738c96d0218363461bae49da0418fc3330adfd9ec008e89e2342a9084800893b2eb86e40e27da0500a171e234098079b91e08780d5d4e3308e5158bf7b4de557662311c533c9daf553a -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = 450171e919ecc10bbf1d05f41eee02eab8eede088a31263433eb1652593d14b7494f7de1dd9fa465a39918283b6726d2010a9f80edaadcbab72afea43e007a782a44d633d006ad8f57e5f93219dd92254c61f187e2aa3a83ad4e7a7fc7142c9631070349bac9e371232a307880f94cc9e11b5b8532d94a78607e0f4bbe2232fb -S = 0471456bd38ff2a5adeb19b73c35de60f07d7907479f9e6d5735dca75ebd3ef499194917287ae0c3334a5b97f2be41598917a5d880b3d021c61a7acfe9083441661f56fb984ec6717986c558a10d108fac9e00bbd5adbd817a7684edd424e612c8a7f60ff1c8056067f0eee1c6ce3a4ceb6c27c735f0fdc93cfb521b529e1002659e6fe9cddcc79c218a84ee59b7355a43b47b5c4ece8535e0874cca866e3981dec3d1996d4dd05afab27bb5dae9d6ac9dc39e957329eb273254c4e7784a29db26696bd0ff872eede9fff869c35487643755d9cd5bae01c7858b123e4f9688b1d2607f349d52c828dd6d76ff41514565564d39038814841a0441c232411c8afcb15073739f5d5c537138b9bbda60bfd2cfea2847678ffbab73eb02fcaba9e4cabd7768bc0c3a6009dd78f02a8d791f5e1e30d7358b5a642cf0a1a838b954b76a15386109926595b2862de80ddfea98e6218efb925cf5d6434b93045cad5bfd1af36e63a98c14b8f5c6974f04e5e52243bf7cffdc8cb9c0a35fc3250943d07037b319cafef02a2fd21c39aaa3da9f171f1e9c9613ff97d3a6770e7639ecbfa7e47804d8833e8212064d091e02801869bcb2bbbfc2be5d21b2da790ddd7973b6f5b9d6c763cfa503c6243851461490dfab31cccc6621fd91fc1ae28b4b1d393cb1e41d397852acd98fa35b93b6b4dd92e2d5fac7665d8c0b3f7d03ad3048b6854b -SaltVal = 00 -Result = P - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = 105048a958c92670205618120e4f1f5f40af63b03d2dc8272ba8c13743c8696683e3d051a21d92f149d4af1e803b9651674483ae26c40b4226d2f689826f4c33b86db227a589f7c9b0dbeb784570705b8535d35e3b165c771268232e0684265c19b5993347557d7ebb32742a4337d4060248fac7656de14f5833f32fb94f1e6a -S = 82bd70e07ba8994dae47a4f8d639168e5e9aa2cf70cc3c011482d170efcaa8aae5d2c8e46d63a583c20d9b7ee21e39b86429aa4550c9f2df8a955a43e2ebd3ff99e1ff3625285de3d506a95e183c664374eaccf0ecfe6d1fdbdbd33f61696064815a21e43600fe7bd45830208970bd63eaff3d2d796740fe1917196bcdffa4107f6b143a7283dff052c1b732fbb545d2772fc725cb0f1f69689b57ea25a8e54c6d68bd10026b911134f034c9f9499f001c71e67a1668dcf11e3974c6ca2658a4dae79a103b1bc3e01195b8ca7da0a09923eabb8f7d035598383404fd7145946931cf2f577c3d2356aff6e2b37f4b084c00943de3c90b9f944f42af472a7eab05cb33d144ad0b36c2d3343f67af4c78bd1fa86b5dd66c9edbba788278dc063c2a6754c114ecbf5e12ce76ea97b9b83431f215f2670a5f23e27b1614330671d3f4b5701ac57bb8fc8a4eb33d2203d3a4faaa1513471d94446a6bf170a78389738567da8206f8e2a6d906a428253e7a2bd95b26ede968d6781b5247bdaa067988f671f9049da2fd3e81a9a0e419cf077d54d524fa561a395af3d443ef4e56f217fa5e981dd693999caa88da4a58bb7cf5bd0136ba939f507fca7ba93fb95c8e33837576230a28f2e66ae1c566f480b16f7f3c770128ffac3b2fa8dc33f1455f8178b1c4dde3d2df25c49d9d2458fcbc1c1c5c33dccda3987f50455f898609622063 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443041300d0609608648016503040202050004303bcaa2105477a151f58e5854c43aea16ba8a3f7aec859c767b4c972f6516065230af636d2de691db4bf4eca0591d5df8 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = c74267ab7b27fc613890220c1b77f9205b8a8b4a7c8aa4f8c5f1e41bf5d7122b3216b36c42addb71fd6244de02ac9d72aacf24443a49774c5d6da726d14e8f1360de644112578d4ca1dab4042d561d7131ac3614b6117070c6b34ec9249fbb2c3ae2a1af53eeb7fa0a409b0602402025d869e94356a9376bea0bff8d5693407e -S = 5daace94b6042b542d3ad0dbfd6987222d598febc1e612c89c008c8ae828767cb3248235febf65a100367753aa8c75445b08aca203a83d471b090c4b40eccf1a375e15e6db3cb49eab5db7bd30dd0ad2750ec9eeb09f1ca646f2cd7941cc53c1a5bd982032dad6c022f4958785fa37caed46c67fdb8fd0b8571494a255a0d8e093b79811b013e8bdd0636345c59fb31d1daef1ff7c8d777721cca8b5997cea173c2044ca0b0c552136ef57d5dbdc9383f034daaa20a61d6db7ba504d0ca67d9d3cc8df5c52603a870010d7024d7fc67ff2b719551ce5b1dcb3228c7c17b0772e3160ff940789935c563b72ad97302fbd276a7d17c8d6ac70866d945be4a19b3ed1256339c005a03c1bb0be9549d25a94daa4459ae2f6d3b2b4ebfddc545f76c3fd761016d3a4a79301c6d94d4f84ee9da965f1c9ef2239c6a7cdd28f4badb57580177b395fee7c684b70c43d92b5f5718e3353dda2ca34e10f0a1595474b3f0cfd90ffcd10c3ce987ed72da95aff0d967b582f9c7ba4067b77f728986bfa3fec94cca5104d361c185caaaa1daf8ae9a54553190d54e16c86604172cd53ff7b37060152d1fbc61e54817580aaa6a99ac1e577161c718c6810a735abf2cad04c51c901b26540e0546fe218be87b12929f2aacd48d9768c51d690820876b1a73bf3d8c86fbf3d37a0f2f8aa9f39dc8b86e3990001cb3ce8fe75d41ad863fa54acfb -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003041300d06096086480165030402020500043041bc09c6fe8e745e4fbb2fa6312743e27bb5e82870600e0f80b1147e6ea9f392710548d938b910d106960f7d1989f8d0efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = c0af5d4f3251d02d37abc8770b5884391a66e7a1700087bc714a0280ca8d910fa794df3a27561b440cd54be9b845e49f5571981c535b701817221a54f12984db4f76aa883158acc8dd4d23a1d422b5f4045ce7ff3fd73325ecad5bf2fd59fc5a211d66413aa1ab4111dcf6a748371ebe91f07b511ebdf96b59b36a61d4652112 -S = 326963d3bb01390b62b4dc1326248ba0c0bc44b240e7b01fd5b05bb138777b31cec22ac0b0d53279ddeb14d86ef2acec7b0c3ba1c8e587513279ecfd6b912717d316ec7bb6aecd56004f9a110e3dafaf3f3f9997549e8b65751d1c4574dcf16a0df08ab705289a9b53930f2bf90c0a6a8f461c69d659929cc2b8514f6c08e07c0c542ec8bb2ab42512f48d8c866f4db4a309af0114e6b9ba1c382f48580a9befad7dbc1d9611de97fede893243fadd94dd78e99f43199d76ea3707d6c8a2e1339b534238bf1bcdf5c2b7144b616872c7a08d4d6399228d508d01c81e7dc345527ef087ccd983f94fccc1f5f8db9a34eee662484881f38eca79426ad87f4ad7ec35dc46c835ae5b38b8bdad63515d710eea32b8024558dc1929e704225debd4e9a770706c78057678199e4d006d185556f27bdfcf5330bbe9cde8271316f460efa53840dfaa30cc1f230395c4f12d7e0a0ae57d71297dcce3834a27b4f29a2c8381eeec3ef4e71a2b54ff1ee09147385f5e41fedb3c3df398cb53e1d19c97fc0f5f85f2fdd0b42cf2065fb68b7a2850e065016e9c3b88e4a0d17370cc63f771de00536c57739625372ec08d8241672ce3aac63dc843d17a227a7f6c68b85eb39e4074bd7ed49682242b213ceedada0db1f2ad978620c43aa88325284588a5244f82083c4420572e30486bd40902b71319c9b246ae9bd7d994f9396ff2bbe844ef -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = 42c5ea617a25f019329ee172e4932485518dabd01983249189597473b4a6616cc5ba8ee693e0ad1d76e0f0c85ac8c0fb11ecb24cee2cb7358f7593b9fa8b904aec0573eb6d99af92a899d9d0fabe5cb349256eec9797422dd60d7fd5fe73f2cf5ead7fb72fd85e3f6fd284d2edfc5e77a03ec5f73c4c2f420728220fe9e9efc3 -S = 6836dff1bea541916b9ccce2695e921ff27a737ac54f4a5c3b2facee80a8dd3bbfe86c93a1af8da5c6b3a92c445dfac7e215fa9f3d67c9589dba858a223f326afeb8f5d0f92f28ac4e3671c22b5b4e0b4266f776aca928bb0309929f2c452b62d462675cef09388e5720cf0cb99351d44059790720db82ce014d7e795826833284bd4205c64e1330e30e09ff6220f62c013c117ace4f4286cd46e52694c4925aba12a5278e47de910dcdd820396febe5179bbc6ccecdac1883bd408530bde92e93c49db2c6fbb42e9705f29703763b21a8172489d2831889bb060505040940e60f7c5cb9f58327c3d3f7cf7e18ad60e877edb65222a699d4acdcb358fbc87e1e461468cfdc82a8cd7fb1f82e05378737f4aa741a63ddf6039b23e1aa19d94e7087915899685add8a8da8f64a93707be0b6354c8e9a8aefc7484bb45cd0beca493a4a0aef0b6aaae801866b905683c582bf39f9cc0768d880c6e4b331da86506b298c180cf95fa45e532483c55544371468088b4e378f37976c397e09f89081f0f0b6f4ba3be6929957f55f14a88f6beb456b70e6fbc6227e98c1e8a4a6f734c9080c13ed58bcfb3456cbbc217653835000f54956d839d4073571d8a42fa2294df1a747e88af53a16df1834203009cccd6d61304739872ab92be79a4462125ebc8bba909ca2b4d91b9e520d6c681c2f92070f156e31a6875122993e1d94fc3568 -SaltVal = 00 -Result = P - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = 3ad62d183432746cfbdac6d9c87148bf13df52e906f67c573156fc407f8d2f576983754e69164298b20172741e02dd27683c2c889bdaebc2caf5df5602b7995f7dc14b1a18cbdba5078a3607c8d7e771550de8c49eb3b752365bade94dc98c0ede585786299a661b643fb99cae388d26441c2da2f7ca0b8fde500f02480b2fea -S = 817ef0cbd8bbe2c93d49bbc09c5d5fdb0c36ad983f0e1f45b41026d3efabad67c69aeb07a0bcffd57c4c6ce95857ab1dd6e786f83d2bc7460366cf051019168bfc56edee99aca9b3862a77c8a9c22787b35004624a7baf963b6e1be2530b0ee43fe44bf21f52e23b2ea0dd7a9cbd77c960d9269bc9efe867f10bab0d27eee85fe95fa90ada2171e9c0acd17ccc6132983276d0c6f1260b8e20ab84ab4eaabb5db220ae7becb26f05e32df93d2a759a9d2d94fa6cfb2a54ef20ea8f486cf587eb2977fdf17e4b65bfd66497aab225254d53cba4b18c9b4c8e30e6f5010eae0d19d53b17c9ba8ba0afb5109dc45f7e39e604f57d1bdfe3a2354346f462036599815578c497a9829be3fd73b4d7fca27385cbe44faabefbc25fd599c3e817a606dc53544e6e10cf3182fdb806441d470f16168237685e2a384391c3b15663cfe9a00f938fb7f9362752e4377217c06c7419a2426bfbf76b503be486a2b90146e9c75718b208c8fc492f47d17e4e8f3ec9b1dd5a067cf1e4ced4617243217518653ee3f30ab3a2c3f95ad15e6939f88e169c643ed2056d594fba35c8e8fcda9f7a5fbf17ffc42ccefac0aeb95cada9b48fc4a9456626ec017b8dd995cab7720cdb7c093ffbd3b2c149cacd7a2328b6ec825376d19ff693a8c8beddb9cf2c67cc22bec90f1d4e0a310d7d7f81582b56fd2127fd7a9c1d3b8d1050ebbbf06be49da1f1 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443051300d0609608648016503040203050004404f6c763ce96f5274b8ea00e1e795e0afcc8a1d1fec8879a033437d0c153b2ef5ed766002b39b50a10f9cc919f57cd0679b82940ad47bc8b5961061fe1575eaac -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = 96c824575d1e537b1f8d27dda15040ab262f9416f0f61260032786362becbd41404fe9f8a9ad46b81f68fe16b3dd4b741396dbd209c078e744dfe8705bc012c90faf63bad1eb70938457dd7b83727d05e689ba04012c38a12edeb5aacd10342d88515a46dcbf1835d4c18ab318f81f872772fb54e12199b5488cb58b87c56996 -S = 336a1580b52f2b15e7fe7eefe6d4503fe0985bfcca17e5379d17d210be01e44394adce8d1c482db58ff71b6ba418b069fe15153ffac74b3f7190df14791f8532adf655721a5d113df77d164226b941cabc035853b795db3dbfe64a0a89fa8728071cec0bc1264cd9c7d43b429cbf868cd7e2ce9f5f71c6b1c9705ff2d99f99fffc6bd964e4aa85ae127e074a95e396551418acc46fd22d61711cc4dfd51428130b0036c54120723bccc8268d9f1739488e4874c7fd77a207a28b97f463fa0667adfddb34adeb6f11bbc1ea2e057120ccbae92c3504d14fa4d87768e435b1479237b61178e48232c6884c94f0f287cbd135ddb9629678d7097f8c966d1b74f288a8d307764cc34e3690be4e790c57627ff1e6ee2572afaef68dccaf441575dd5112341f91c0f20efc8a75047672c190403e8d5aeb1005e2040502d7cce97cc8977315aaef7fcc9c5b0029246839134dc72f72dc2e80e1d3d5e48881dd71f6b2accf21635252d82adedcf86f58dbfda3ea1c0624fcfbef191a89a43d5fbd62cf6142cb26c4cdf9cfc0d8c993b3e80d551ec56b29734ba77dcdb03cc20912ad85efc48d314c42b15120ecfcc03d85a43f2ae733fd2decde46e535aa84415bcc7de4203869ff945176b9e7047c5953bf241e3b537a93e62b412cd81591d658e7f55c4bce859bfc56683abea7e6e1f87f807ae05c52ab504f0341d301ad06429fd964 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = d44ccfb041a426cbcea27f0d5e2a77b21074beb5c175bfe5d39a833b2cbcd26b81519cb9d4df980e3bb72b4be4df8bdd56502492f9613baad984d132a730ca8d011e4e54f2b87060bdcf0d24d68cf74032a95354c0e0401238a4ba981310bdfcda1dad28a417f5e8db52ef413e1904052ce714a41fda1745776405157944f4df -S = 5272ca5de6f01c255f59460bf1789ad5fef5cd25345d701c045c3623933f6d44389c5cb6eb3746b0aa75ad49cd5900223ff998d5752ca0c164dffa90cd4a3857de3f4c66e9d3c19bdebc842babc4b0fa60bdf53b76efd35de73230e283a590f4f4a9b7658ab1e1e0e5631534710ae18c7b866e79be08cbf3c30bbe6c0daec86237c439a7f63e57640263a75ed980f5180dea5874e2af8348bb15b833055936abdd01f8e5d913499382496691b6c60b5b2aae76b8c51794dbf9d9e852e62c410e9981b5663c59a0e5ba5c1545643de0fc9397150518d7e6122334246e277570ae2bdc4e84e916096000a44ec2e68943589d62b24f45594f35a2b7197ec665d45c3d9d403e7510f536a0e214cc6e3391c0494c5d52508e777b851157ff091995f4e0d2131f9e40fa4e81091e46cc40c0459a4f2d5c198222f0c7b39a5e2fe86a6f964a966d1e66ea550627d4b21c90cf3beeb8c4901a2ca47ed8b3581f37852f582382922ddf0fe0e322ef9409ae860b251699220efbd41f09968d2787d4b7a79ec4828b9ba1702b5da7751546ef626f2c7507ca4201e1845f39af9d813a45eff6ec0c234ff31eb9c8c2f78a0d70952ddf010ed03279390e13d6ea464171831ef86855816f9eb25c44e94ea5a40a6f134a55197415c7b621c7ae5cb29ed27e9bab16c1b6e7747e1462e64b99f5b8d07aed6c92ebdda2802269cfa3827d3e65c8ee -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003051300d060960864801650304020305000440b6f769c5eb51469bed21e0e25d8eb3b9f5909a58eaee7435ba9dfcc3bddd272f82d00c6c7992f5caacb7814315f1f58aece9fda52a15a6a80a179c02bc194614efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 25e0b881e32da938611b4156525ce24216c168837fa84479ecb72207e9984adb6eb7393bb3d607b1469d9b7c3f4fdbbefaa4b0218850919a7d66a954b315129c39eb99f7dc08df5c4c8c90968f3ce37b66ee184ef3d485f83d308521aa2649d28c319eafa2aec87031a1ff5d7e933ca56a2410593425fb865981b7976fca021b9d7c3198312fcfea5d0093a62b4a7c49a985c005c3a7ad816e270b25c507fc36be1c4cc0a07cb7c6fa130240062793b18047189aa5e79b16fe80a6955191f5910b701bc1aee6dcd5cefd57194bf54d8e208ae41202744190d5ec8bcc2f977f11461a5cb4306fc9b73afff2863a7b580d454bb1fb8dccb1cbef27945109a8f5a3d2b1a32566aa4e8c01a62a1d735117ff5a6a3cc7e70756e7df10e97ee75c5f8ef89fb0a97d7a35698069f59a9f365d4396ab9a764c2fbefb840faf5f57737801b73ac6f9f524167b4f3a567aff999a0db10d55d82155720a5ddc63c35b6a632a3da59c16bd0c143c437661dcd339652ae42f54f8b2d8e52672613772abfe8cf0d6ebbbccc764b51b3eda2ae28d4ba8747a430ccc32c73baea63d050b86210c485ac9554606070764cd06b423efdda4059fc45ffd7193f7123d14014d5bbe5b542476e7bfdc4905731a0d9987fe4a68cf6077c3df63778af08a1f4eb8f00a4a8e03aa8726f43fa829d87c2d0a32e16b47a3f0472a6368ec50a144234c802e6919 -Msg = 1fa4b8433fa5d5d2228abd92b49e6147f7ed6c79a557102517e406b26557d026cf06429a5be840ecc0f0c9b38399357860c3ba23ebbd35b377a3273237eafee8a33997d01d7a0048d532820cea0ddf65d2bed89efb05f2b8b2117a5f4509c71c64e6bfcbcd839d5029f7f1863022e7781486cdd41d58d09c90d7061fd6ddb228 -S = a65d94748b11294edf430b91e649a7fcbce5d47ab1084c0dac64033e582360f7cc18c1b7e71f8cfa3c0677505fba6769af39bbadeddf6b3ea1031b103f3fd72f3c4d56ff6a75fc2e16c4eeee8a1d4be05e001fe210d07c1df1e62d17b9d9def6d981df183c97b4bfba226cf88dab793eef75fc99b028100ed522e98de4dd5c26fd954a928619ad6024ae454f11f1b56c0c7f04442bbdf4ca282bc76f7f054d5195a5ca398d06e8f149b0044d310b74eac7a14c2dd9999ea248f9a332b62ef97867a4e4e312305860a8797c5f9bb66ca4fe13c054e55948b1e54dfbad12015854fd4ee347bb19bc2b59930056a712f090fccd9b31c96b3426ddbb16c4cfe130b0f8327fd61e1df46e093f6232cddc3f9b43d8b5a7b8edab6937d869353cc3fbf8d050879b8fd8793912f06a603a1936476247ea140212530397e3ca5a593899198e9d3ca1eff1ba302a0713183c7e2d60a5492fcd8b1df4e787dee2d305153ea690d81b194205a54425c1e1df4364a20082868f09b5d11b5e5ebb77e41b5eb91d4ac73a75d29f7bfba2e056dc8d19a483c4256f68a3f4e80e2f8a801cc1401286dbe15636c653a80dcbc73f249fcbaf4b446e21e9cabca231615d44578e2f8466f22e9b2b03d21e2f4e19623d15361336763a28dd989bd5a912fba53bc4d5ea1c790ba81f5fa21ac1a0fb43fe5a550108a27041c7e854e7aef824a29ce7ffeb62 -SaltVal = 00 -Result = F (3 - Signature changed ) - -n = b10935650754c1a27e54f9ee525c77045d1a056baedc8c1ba05a3d66322c8e2e41689ca02b8e6ec55d3331cd714e161b35c774311540c6410cc3b130e65cec325377ccf18a5d77054afaa737e65b68662327627f5d1092df98c08b60a3ba67599b1406986f441528d2f1f5d6fe5ec6b8aa797dbdb3162876b08298237af81c7004863576af572ddd66c487cf32a82d0f9fe260f8f2681613208aec55723622f50d3cb3bd33b1226d5b5b9ea2c97a2c59054e31536849ec2f0f2597c077e621ddea0a22ddfb1df925c9f1941cd431afce0398d28e736cfeab3dd7f062a65a2a4c1ddca1f32afa03b4ddfd8b7ca40cc0ce2ed42229d753f03cc6d8bcdca76ab7c2703c5ddad08aa9bf9a27740a8b23168c6b55917bd3d5c1c057c34d1efb1411da51ab745519bd92b9432fea8fadcb9a70e5dc3adcd3081d3333507b7b998886e988296628dd7265e64eab557712556cc492377f15a078dcb620a6e7f051a1fb8754efdca3de253dd0aad4205b032659e4a4fb307f074fbde340702b5911acb34737d7834600cf2ac77f62f83ccc9ba78ff911021b9f8ad1bf421430ae0d64916944b504542c0f6263c48e5e233ef1869df1efc2ccf6f4a95e4db2de7b4cb1a992bef6573511bab4bf2cd58e72a0c235f56dfc182df4dfffb69433a5677415f35d84f5125f5200eb57868cce6b74c5833417990e318372c9239a36dca1a0b28809 - -p = bd4e8bb7fd7ef1e39d71de06b0001bdadcc81b0edf2226e0d056b7eea70b2249000279cc1c04b1ac2919014fc3fb8b62baca3e261601fb0a58a9f67f03cd60085b2d43906d36ad014f321012a9bde9617478a0c10201afd53f2207de3648afd1d737afadf7fd2c0b9824d4f66b2c7dfe93390888ac088c680c27b1b2486659ccfa8986c8c23f78f18b5815a410328e629e7440221bffd8ec4722bba3420da5234f898f8cd7e6d7dcb1349bc4a0b665b41d930e3957cfdc88797aee5b2b27dafb5ba0949e3dd892f490212dfd249f4b1d99fd3b72695ee0652997127f0b9b417fa8365ba9fd103b978309d9baa9d401902cc107cb8d2af7ce04660900e3707ab3 - -q = ef67f69838735c055145d21fccb42298642177fe3fadc39070a95e4fc04ff058aeaf9070b4eb2de1cca72d8533bc55206d2ce9f2895b148da67c89e5b6496ba682f76bcaef69306a7fa4fbd41a838bdf0fab3e7b56c27a8c18dc4bf970364dff7427cdcc6f532b49712282370a718b7d5287bfc02c4abc35ccb2eab3777f5e0d8a27ff9ebe13e725aa0a0cd48aee1fa33ea6b4ea965ba42fcce7af3c528a6675cedf4969640f2ca73345dfd322620df9dcf16520195df8232061e2bc89c12de24838f255e7b1c17713ba435d5a351e263350198b3fb881b8ce0acb5aa58b7afaff184489d167c9af21e40e2ba9fa69b44a3854329385c97df0de24dc283a4053 - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = d65a050fc06c9f176a6be7a7bcb0a9f074112ea5c7fb03b04bc2fb25143477741d74e5e2ea06873a6c2676bf255ee6668d57ab42b3f0fd40278d781418b16673bad04183ea5e7490152c620056f4a989de33a8a199363f360f78d5a0882ba0d4731520da089ded812d26b351969b7bc1314b2caac1f851fcc82a1cb0abc9abfd -S = 77e7756da33c3918b94a1faae80f2081606e9646ccf2be6aa16f2b4fbfdb8ba57fdcf61e892cf9b77d60df62c07e56fa34177df466710c7f3b4c5084647bc9c9a52d66d080b3a1d6fac9d439cb6f207a72f70337ca9c357e16278f6f846f7028345dc0ea8139359ad62a103c43a922293afd300436d76daa5a92f940df6f21f1c442ee3d4aa8488defebf29127e11413cddf4471fc5324ac14ffc97403505867105ccaee26c742082472f6dee0d985f05777d6faacb166f34da96057be40530df9b1076b645272d154614fad693d4d5270670a20b71103c0e740114f3585c2ae02a4865e0277a76eb173bc2ad65db5e0a9aabc5d47f903643a1cff148703991ddc4e05ba766712a93d3243bcd714d067c8fb54eea3c3b5e69cef976c8794471b5afbcf7e327f14258410394d388ce095e5a623a406d33238d2c37a29eb1d099a2730185da1b2e295a55f74b555a6d6beec7fa7b9b76d916e9f487547d06356ed9e3ba818e31825e97b465174a7fb8404b7da84020f555247c2f03a407ce5afe07d3d9df9c94147697d0591ed2ff6776ee778cd74c07e071bd8b2260cab2e0eabb4c97af8d5ebdbac9323b0a73a9d93d27a635d8d5af1651de596afd4c9012f9f8840d05e80a2afe47399cefebb70450fc4b501fd69f67867123e95a6ba653f69cfe3cb5a38e3ffd92d2a37fda91c06e59eef42c836b50050f8b9fa808a4a114b -SaltVal = 00 -Result = P - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = 7228696b438ee71ee4be5fe548af7423508c3de7e370f6cd416ff61f94d5e140c9b21f4b9d968df7fb9972be859eb43e71d94cdf968ff7b6c61d2ea95f3c59d41d83402c322ec262991dc90ba7207dfde371b8fc1782ba96a7f91f4b22f90ef117a4b2572adeee2966534c13d5bb37294e5d6b878fd1a9348c0baf4d0695675f -S = 34d3fb114d6871eeb6a9cc9960d655df44d2a5c8f1d8bbf1b3b03896f5ba8178c2e92f8c420d537bf9f8e23866c11d0e02e67431a1506b35f97a85ef220635a28eaa76659fc8fe07d0d4f06fc43c2c4ff96f8e27965078c67abcab78faa4299d345ed81a442698ca99d1c0e4f0baed8095dce5d30add437c1f06f79c215cab5ff88eb280de1b75c3f19f8a9c8810143be9e127b04fc0316d65e7cb4af7786886663062d88ffcd0e64c5e359874db6bb63f91e92c14a4f3893d6beb209d4e009d646d14d01dd3a84f445ad2f54877e0b529356d561665e7be8332c33dbce60d0b2075cd88af0bdc6a0d8edc2efdfdacdc5bdb4bd3537f28ee523c1a355cbf94c04329fef5c75726c047caa8119ccc4e9d60f203b0fa48400e07e9270758b99b0fafa65c0cbaf40cd3408716e257c539cb6aee3e171830e70db3a5110ef5a2561f87bf9b56ca69a61f7abb1b0be64d2627d7d78055f4ecec34c9f9768cf2c21f5ce656d069799476ba6c2b223a17dfaa6e958b046658e545ec4a28e2b6565bc320296ea2a8360b6f980d8e81567a7c40a32c82e2576ebe9e2ca68c46239e2638737075c3a0c0dc68795331700cdf2ed1c81b44b69afbbc7776e08ba794be48f16dbbd8d21505d8749deaa470aca86c27314675553afe88a96b80a67e4257c95a57bb3e9262977588717b54814250cce8bcf8e260ec58c6866903bb3f635148bfa9 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443021300906052b0e03021a05000414e3a0e0ee761eba5ffabbc08ba0f2fd689e143a3a -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = 92e658a7f7bef5990043c260671864572e070d373345af8304f76923f4f4464e6fcd26ae8a0bfcbfdeb73a7997208a2ec8d8bfb502000bc824c572ab742b7e0eef0a3535de554856aaa28d43f1e7af48d9822557a57d6062860f4909b366ea75bba36b841a2741260b0da2079ef73c6e0a0e26654444171ad1ddd685d82df14b -S = 4496155562e965348a09e9a67ab0009c2b74275a209729eba350db82e066527d9294cea63a56ba53718250b86c64d29b327cae24be1d1b6e3eb996e539e213af4739a5fb52970e89d6ffb0e4f7074603ae6bc2afe88379fe8685fed5c2e30183199702b2028ce39192b35ce3a7111573b148ccc6b7bb15c6aacc4a72819b860f3704a0660241a5339ce3ac7eabb8eba25370d690a0c478b3be35f3613e6be74fd9904d32bc51762d9c921276159e4bb5930aee4ac654b51c5c77b84af7f71c4b88714b1c1bf23ba28d3ddf32906a1497bcd86fe2d8a6f369d145439119028c82d0cc2eab42a4775193d7c3db38c1b86c4a4c697d726e924120852dd747da3bbc77a906f367cc5f9303b6a4cd076bfd4237975ec9cef8ed1d637f25ac0ee20d1bfd918db031102913f8258de26d3319268d97983d29899b8a394db559a95f0fa46ec4fdd77ca0d901aebf952c321bf38c2e6e7943af071a7492b5220e4ee1a376c9c254cd958a743d47b458a93d993b3f011d81afcb5421ffd4305bf6385084ab3fd2159aaa76510a0bc20abf5bcb36beabf9e1dce3472961998e6aad1a68935283e62d49334fd1a3e56cac2681a9a172686022e1ccb5a215333da9dff877ee2b38484e4824f28eaab90d2f10973cb67f0b0ff7b32733464d1553f18306eda6cb50155a4047e0e39dff11524f97819f73bc3482df0e7d65bcbcbd4dd23f845dd0 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = d51a8b58c08bd2f5d5cdcb0dc596e5a2999e86d6ffa6fc09e5b9b64246b2b4d044fe3c3178a3cf3286815b58f4d8b27f3c0b3bc11fa4e7993d976748e3cb9d7824d650202b0923a7cfacc84c688a71c5e1b187260f739f0541b0aadc19586bae9a2b2fee81c3b89cd9d57ab1cab40abdb216d3cf771b0b951b8be5c4905f08ba -S = 068f422fa9bb79c8f18de3cc684be48ed59521ad0ea3a36326f0e4f96db1f2380b4e6a8d67f15a13b68ab0aee7a7b4d0166d94ccc1ac522de51052ee303c56ffad6d72912443ac8433c4e10229d9b9b605977bcf9ef69e33006c50e6077f6f0ac5d56cb9ef36c3de96653748a9d720841c9e4993fdde385ef8d5197b8da2c9c9b029e58d5d28c8a4d017556f31d45ec3dafd5f92a99c5342f31207b7ca9574ed043279f0cf6b5ecb4927425e149609009b5fd0295faa4a189d093f9635de49c8caf34200ccaace04c42c2f57136618932556a20ed057d60dfd87c8343d3a1a3b8d7b760453877ec67a535676c97ea65fc5623b9b7eeb5419840a27d872b199686381093aef3e968af7c4faee2e88fe7904212e6733c6571102cddb6d222e51aa19eaa59afb7799b0590fa6114c0d0ad5a4b09b104c3b0d1f31c8e90d8abf26516b72c7d0b1533bc66ce4d0e25d08454fa766522a4278080a42eb51d064101c1d845361d4ba69809d1340ab354f907986f759ca18d62861370fc4a5fe147aa6504387f1a5285629e3fc92b53abaf66d9bc135818748f59902752359f074f831a87fe7fee433a8b564e61b07500bc0610f8f17a172f92117edaa9b9e6f5858326590328cc9f12ef630f14b1459f3e6db8f665cc9be64285ad681f5728bf1b1507a72769f1db7ac1231d123b6cbe57f647adf4956b5237e7f754ff910278de89a7c -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = ce5ccd9b81d0103e99c4bdd8216b4cd75f4063174ea2eda94fc16cd31bbe9057fc0e08f83d20983bde3f6c6b8db9acdfd24150808a92368596557181d445e5a04e91112db2812b58035d72378d8bc00a1ef75ec373b81dc6f1f0a2ed96f302cf2eac8f42ca3df11e6ee678440a28b0dfab2a36eaf35bcbf3c759a71e47120f6c -S = adb58e2ca61b110bcc5697d845e3f035fa8ee93203f12475ae3a81ca0a9820d799724b3323aeee7d3d6e978f324c84738d6b56c37dbd15b71bdac3a4102576886978db6d78a0c0291886e3eea01f1e95565789d3998a2613557202cb598d560c1e158e3c30d89a4add63fbebd361a17f332c5c69857b648813cd90c2ba48b720601e9b0533c6baa740223dbd8682fe0ddce8a6d9bac06931ce4d0516ca1cfd9cb06cad6fdfc1faededca19480c247a39c5e4815e79dfcabe5f4fbb0ed9ba17b4f7e25f1c55ed71c31a5e559c60158bd66ba199bba3e091e20393377b3a4561b9f07aaed7c0dd77d41984cf47bf34359b3a513618c4595be045750d47788b22cdf102d7d10726605706b772d2e773215f52b9c073855018022848ad75d7483aea8a34af5a900025f71f0b46c587a550dcbfa011902bdc870d6cea895640e4c775c954e11a3423fc9e0d6ea4421408816ca066586a37210c7ac8aedf032413bdadb41c0e6ff5c57d4a77f71067274d43ad9960b895734aae6a1176ded2883303e24100398a4cca23dae13d018391a8756adaaba709354b799f22f27d4a5517967acbf694e066056c49da87df46829c1e4062c535c17b72989d7eb045903665576e6144478e8938b0b2fb4a916f9f2f65990b683c49adeb6e6d6ab7a7c29c530217626d1429025b7cf627f72c4c588ae86ac1a1aec4120bd4108943675e53bb837e -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffff003021300906052b0e03021a05000414970d2e4e51ca9f81fe2e46fe8ee73b728122b0eaefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = d8807c9c2e144010d462ddeb70445182165168be1a5f33c22346b6cd81e7e162c16dc2a77ed3f80c7aa76b2ced0d3af81c06f5122ef20d773b548861a7d6f96cae8db0f73f7d2ecd0e60dc05e5a3fc263ab2df8f07755816d61a72f01b165ed1c766af531a1bca9cb915973b000f7d5499dc8efd4eeffee71b21da4188aff6d9 -S = 9e7c462e899885020d173f427cd4e15994749339dce4f39a1916635010d984b6d627da831d4264ae8f929eb66b8b14938ae12ea74e4a51877facfd402d0b6945a299ac6b63ac800dee3c2d5e64c4feea4ded7b3523f4fbd950e8647c32fe9b2eab6c64d74fc90d8318d52e482e811f74c1990b80d07622a35d7ee430c5beca1997f942117e48146413a3d07cb42ab16657176edfea16f5ac4cef9870689ac51edda514099ed6665b289e0ad9071b35c9ebcf06b0517260e47a516ff852f278fdd7b3f54db18bc5491a44dc87dcdb92a3e9282f7de19db80424703af856a361a9c9f685c3b16efb5474cbe23c8f04e3d5c5fdd0ae9dc5d73f9f04e267bb4aff348c55e2139fe554dabdf99e90b0ad20a01c1e02af92fee0d8a22136f8953bf999500a6d1a5478c9c6ecfe123b068085928354efadd5a9e41e66a15d73dd5966eead4d39491ee2d74bb6ee5608089ece479e53d599f9c19392ca064761688317d0d178a627b7a9059093107f727f754fd538e223cc6f01ad991c4c35164394f4a60da9de6b1b2dcedd892eafe4e3b04b99ea2f6459a2dda8eb7ac7020bb12656207470362c0a10ea79cf3d5512353aa87cefadd601f25ae15068049d2dc158c04a3a8e00ee4b8af3a430890b572c414b28abf2aa14c5403a1fd918baacc4f6b4f80446dec87ef2c808697f0fdb8f142876d8b7d8d90536e3119bba38fb4e1672ec -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = aefe857b2bd74d6bbc3d1376cac4aa6df362be9d5d77c5f54a0c336bed58ed9b7d8901b187c1948a885e1c16bb7ecf0130c25a921e53d7d37a23f9f2c8768ae732a01857d710ebb8658d3ab7eac09ed6e7f3c65aa7186d64ce0d895e351ec598f5cc3233c2cc393f7b53d520fe91ff36417b69bd9fce6ef16f514976db5a86f8 -S = 30de099e81b7207862eaee842f7bbca8db96c4348cfc148da9ab9bd6479ca79f09d9cfbeab93c20f58351d18f7b88cba4c1ddafb46ae5331b75d216cbf6fac92cca17f2cf7142cd42007be50a24a1c53ddd69890673ebcf6d476854fd0a5f76e7c53b40890855ac801ff2088e0d427ad02d8e43d499a06670ab6e8b43f661c16295f7c6b04ac5494ccf27bc49b5c65233af02d6c15cbcccf40aca45929fc413c566bd07616748b9e5cc8562879c2782c1345973f7777f56ad0dc290458b6f3b5a88f160a8eaf8ad0fc394b283c1acdf9bcf2eccf88164f1b868d07a05b7239e4858c2f3d076a299a1ce032ee4967f7da07198d3ca26912e9ad2db79ea8f49f21544e82f6e231651805e934524899ef854255998c1cc59de1ae49e482ac801e3c678626b3b79bb6be296af03c863f89c73a87bed864636eed84c0a5ff05cdec57a3ec76071137fdb3cdde2c4f03c3bbcffeef28f298dd13fe669396e8fcc3a478f4f3793693e8183d96425ebb92f41ae373aeed30182f8a6bbe6b3440ab2a22ad0199bc59fd631e221223abd2358ee6b8e879b2aac64fb41257fc5983ac3e2de5386819042832a8bf53313c0d77767d53a148bddc46638acfd626b908b056c71292c0f9d1b1ced4f2d2ae70e70de9b3dfe6b150314225f21c03b8b53baac3432a72767c09f360393feb18854ea884e8326b94c225d871cbb003bb94d91a74b358 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = 4793168aa3ac854a7e0bd652b8a57666d96ddc389aca257da748fc46a38ebd8e6c90da0fa1057d5b621c6f27576a38eaf42788a7fb9bd50642d346aab698d0bfa0a29fd22708b7e616fbdbc4e0b4ad92e2ab18a7e70aeb9ef161c6a9379b3a286a312c7b3c9d7a142312e2d05a6a1f872a6054e267ffae6c3d5a45ec2d7e44f3 -S = 9d2457bf29a45871f04f476eb7a43238d3ddfc7c61fc2ad160335cd1c42ae0da5eeb2ee10f2528ba1e645d27b306f9e833b86ab62b1c4785d9249be1ea9e83e80a5b3a774f2af61d6b536d7670833bca21406cf5dbdcbd2a9e17b2679dd33b026351943e841a7ba4fa3f18e2e278a9db180757021fad06befdbe75f6c77a36518a2c3b88b6329849fbb1007c7ddb7e278b64e319f93b4713717282e5845a168b7825b47f23223793a7a93adf68d5b83c6ed2b6cfd850a8c81589032047fdac6fe091e0369a07919329845612a797dc7f9adfab30255e672d8fa8639a597e556b215e83115fe2268f1c9870b1ba0caee15a26c45acac368baff4018eea4414eddd86678e30d2a46ed879ed6795641af64cdae0f94686c134e1f05dd4f59936e1450a26f2927de6c44247bdfceba2b14cbafcded775da0fb0b81baeeb35e52fbd44d7a4668fb4c832ac0a9c622dce6889a1df6d15ab6c956dc4249127eb7f1b45379e56ca7caaf89617491f5ff38daaa5f0d58bf8eb0138919e3e9bbfce08861b92df0124647bc175bb000d8d0661c71d27294dbdf1112d1461081a931c036d5b2e204e94bb3a31502d055cd74869fe7ef5ef78657a194b9b4900f8882c25668d5e1abf37b038a716a2735bbfbed06b2b55b514f24dbae2e570b9b6164707fd4307b7730a48d3395f372be552402c7c1afb94516294c7823e4e295cff2f2e866ed -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00302d300d06096086480165030402040500041cd79527d7b3e43885192c0577d81561869ffcca8d1a7ebf268ef448d2efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = 8a64b6cc5b6a7947d76c4f7392be0e56cab7831b4a04710a8e42d7b828cd727b63d2832125acd2e21a6df3920ebac81c9bdd472b05157d2a6230d36ffe5c91b3fd3ba0c6423594809012eafbefc88dff52919fbe764177c20dd7e6231c52bffda2c696217aaec70b8284bb15fd8f66ea36fd143c673166bad85e973c4b550441 -S = 9d579f90d7339f303ac17951057363d529d1b448daa7d7025d93b111aeaa5a1087a7063515b01f30d245a6d27dc2074a51f33273405f6db2ffc466d96b822b1224f07aa8075b9abf044ad120eeb39b2e48d5f4c9f7aa1657ccc639873eae8b9218f3e800eb560d5a04e2797fb8ff3f7c320f7122eaf227febf6ae3a8e2042074b7d22222be95ede069af032315fc264ea1a85af5de920f1ee1ee3696850b581f2eb4c342d5df7aff1ad5b8164f9ec08f77e60c0afc256de6ef1a18e1e113a60e7b5ba8a0c665c0cbedb4a56a146a1662c8ec88d5796e9352c36f73a5f5845659a0711c818b0b4f7a20abc52a31474f8a51678aea7a13cd3d361ebdc758fbf90af9764bd757c7505b834105f0ba803f444f4e17310fbd76d4ae2205ab134a6134819ab329e1a58a7382624ddc2bb3f54ef41b6549cfd1158a3c363e4c0a5b3474dc75baeb43baf99df031210be3a9ec4c4e910768715b4763b4f3ccf60af91984e17495f4064cdeb4d7b280c8c5565a6c774960bf2c71a917b955f258eaca5b0bb9f48de529b258828c138d606b4531b7f621b9b9c1753db014e8202e94e8ad10c18925ae170ec08d0a38fd493f022a618bbadffabe015ee21414d893cdf20226330b94970d2d9ce45bf63a664febba1cbc3d6fc20ef8f2283265d1fad429bc4c0c010022113fc81bafe06afbd7b6af26f369fe526936d233f5616dc5ddc7eaa1 -SaltVal = 00 -Result = P - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = 9186fc389b58e4aa051fc5a96912c940f4c0159780a5062300fcba1a1fd5d32a2467776a19a79b912c1a826655e780773930040e4fa2d661414b9c0995aca3b58c10dc204a1c254038a6cac1a7cb4cb1b63b617d75d83b1c4a800d8a9426cc788f28334278dc0921f16ca6a2a6e5b456318a33cb3b6ebfbce4421685656bd5d9 -S = 2e7a8b6a247395fc2c4aa4f0fbb4073fc25923bd456da34955a1fbdc66049fa20d093818d0f65611dee0ce14d15cabf313096d629866bc3b12ac8805b9c0487c92cd5500bb5f1258c8769bcb0bb0ac0024d611f317896c472cb9fbe100a40ee6910331e77120bdb6d31603774a49ec63fa0d5a66bcc1d21caacc647e4942efaf53f28bf4c8685b536615ce951ef1f9b790fb1e5e423aa581b54d3ea30b8cebd8bd939f17d0bcf551bf36d3d0080d808291cd60240aa8a6ce963c5688da23fbb992d45a4075feb1263310cea1148ff2ef382b2fc2f96eef811b338be205a0791adb7c07895dec70d75ea4f6a3d94b7a9b072be6b5d72f964e74decce749f3d7ec84e929a1db42e7451e50d50a79631a44ae1dc38eb4e541640b421ac93d33917680888288e063011d80fbce554bec874b0a4d4670210a9fb9f73858e1c0ac7c98d01b1065f2e8dfae52ece1a4d3fdd46d48b1dd0d77bff7fbdf899672c9306cffb4c070f83551002dc564307730448b34258e7ab7a0db18250950752636e34484b7e9063479b2266e639a4a6d3bcb3c9471f1e466c5339e10007751e7392b8591194ab85e00760debf22dcaf83774d1ebf59af46859c264bba1387b6cee391b131b9f633bded7f1dddf7a370742f40a3ed1ef7f5a312e5e26077109ea298c8932d4abd003bc407cab7612db67a94840a381ea7cd084e4d1825eca83ab84ea7043 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = 9c8697689a09da7917bd79af7bc026c32837849ff5f03a1ede464513fa45928cad0fcc581e7e73c6eb0b2eb01cef62b8568803d251fdaa038c25e86840a5db799259fe8f0cf645a44eed6a5a0192813f0d7dd3500c30e9bcfefbe7ea3e1d1cbcb52cd6164db77b9aa829d5b613f0aee1b5df9d210cd11fd19b90e9a1dcf57dde -S = 5cccfe2cb4098226ce3988f1fdde318bd67a4488d48c8dd57b678d4808f0627010ccda741f0420ff14324c67489fe4b55356b5fa14219a6484331cb32df6c649e449d077d35276e2508dff31a421357befdcd05049fe9f3a19fc2b65f7b336e89e953414c708533bdd4c256f6541c87be7c32c2d6a34da805c63ba836dc3ae5ff01f4669185cdb2a57054f2d5645b4010075567374fa60d06dcee10595d35c961e350604d7423e5beb754ae5f34d3c144526ae2cb9583eca938da7c7b26765d5d2816a30bc390be5f1325f2eb9a934cbf9311911127b91aae4aa4c418192954bd89ebef8c54d575248e3827a38ef50486d0fc2ce1080c0d8d750c1bb3dacda49cbb95706fd4af5a915418131f429f50b55de551ec23516200bd5cfc31410d74e1ca7bbf79180f3de84ffa56de13e7f6651928065abd8d3bac5d18ae6e3e3801f102ebc7d08c20f9e9f591351e03c9ca3f6d12ef6bbe356916467154c30306e0519b853b4d073f10f0808a7e2dc22e55d4894c100ee5ca7209e4eeab9a346defe83d0ac34699c4776e1c63ad4807746cd1c05f4fd0f32c2183145eee8ad6df8c16aa00c33ccb871cbe373ff04bfb064bfdf30b8b096123e2e137952194765dbde4d12fb846e9baad76f1eb00ac0ec2c44945095eba3aa812a3d33b96d1a966829cf4ba7a98e8c794abeb2152237e8a261f014a19c2b110d1c6444f8fd8d69d733 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = 4eab894093e01b38e38a8fc8b4d6ada3bc337ad1b30615035a9fdf24bc6cde30b46d6449afe8eb08b35e4411a1bdf1eab7d7cf0d5813f83b1063e714d376dde5852e84c1c054d2d3d18b31f20382dd76216e8d4a36b8554397f2cbb023106933cad532cf4c8b984143f79e94648c3af002dffdb3d35bf5c2f736d32236a349c2 -S = 96d24cb0170440b5a493d313a500c9d095952899b669494cc182f0616d0da2918f4644961a6480e127459f63551bfff6e72f3ba3cc5bd8f529c8bf9e2bb90c9c12e2e70448e4ee1923ae1e3561fb6b5bbefccdd9634903bea982d9be5521914e8d70a51606cfc1ab9806f68487998ddf94e00af91f64b7dc739a62d98dfca35ddf4ef4f2c318b3b5dbb58d0b892fe0932d48d4d8ce0f88eeffc9dc5b8f4ddd9f493a3b03c62679bf261ba8a3e9c98e478e9cc74296714a0e8d16f0246a1e77c48c6ecc43b4c0aaff9a04e6594ce508d4185ac5e189d2c0a124cde1d65e832981dc49a699f9c6f978f0949078be9fcc545d33568b632bee58999fe83a2670d24c03b8f306385674fe3120be26e12325abb051514c95a60b3369d04ad92b85423d7da9a06bfde71265fcf8c9fed0b320909a1f4c66f4b5b6259a4938983c8f547fdfb630a64779a5c835d82c5435f60ef8887ca47fca7767a27c267c9d1efc09018e86340f4ba3961ddcefdd2bab540fd9c038d16ec723b31da7b54f0138cb54aa979d726c96ed2de5b4cd238cbc54ea0440217c87667eeced158009580a66e7432062c5cc108648cd6e52e2aef481891cf7963efffd5f2c5d9d468ea32748b9295bd6d64ecd8744b4a5d44baa2346b2e23a88639b3e6de22d58b201b896bc58c916d748563d0f68d90819cd749f9218f715a012d0e7388dae82363815e389033e -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff44302d300d06096086480165030402040500041c25980db8b2660bb031224d824ac443d7f673a16ff6f4ca64774cd52c -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = b49b676c4b56eeedca153f915c23079f3e9b87a7d02b4565ec1702e77681edf234e716a3e0ed25527c5d4cbbe66c7a60ac3fd22921ad5b4eb147f97671959c21faa3b74378bcf431fe7626c11def7eadb455033909ac3c1619cb2f852da890c0aed632953a4cc154f768b3eb28347c50fee7011fb0af5085cead8e5cd2413097 -S = 410a01190f07def9bbe6b2834634d4f84c4f626e9e286d504c9393dcc751b76327443ab10e9e9da673e668831c231050b8c37c6fd0a92b814924ee73f0b6a2838c7c6bb39f02918ce05a701f92e38680e8c43c75a57ec2fc818316e0e32b85a5126b2ffaf9340338121379a57ea00b1529ca11cd5b6f444654ebf079bc44e3bb487943580f768b2a2ef9a31b0cca4c0c811124e1492b32f4c2a393bd67335a310ec1cb4cf908613c552a9dc68a99f2e633475e5f24c9140a813ca1539f63c7e241b700f202edbeb1133a043d61e93baef9f3a4c0f8e6cd14f9c2a8aaede1486e0f8da8c19b5a2147357f6059da419078e631e48f6a9cf888d22aaaa22073a896bff816ac5dc940b2383397f76255ae9559ec0812444d47f5b3205595c9db1a74b7dd40c704fdfdbe786713a3b79dc52b0c882bbb8a62aa01d8569966ebc00ea4fe5df212ee4a875afc85f48464cacd874b7a63f705cba529b43a14c483032d616f7b965f9784ec1fda02b05a5d310b11b4df17ec35c828b129218d4158dcc58753f5e208ad8a97e32451da1fd591101ad2f93fcd1e6f5d6fb7b468da1937fab4ccc8e9f3e95a4160b2055e8634bbd0798bf0fdeb658a435a21028fa7cd4be555767573e09d5053941aa0814ab314c45bb94a36997e576a026d017ec7a519237d82297f15c1906fc5866c1a3f6096ddb33576fc68e39c6bcd8f087355a12fd94d -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffff003031300d0609608648016503040201050004203a75e4efbd95ceba73b7671c870d5cd4613bae5fdfabf22e8b5b18fab56f620fefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = b31156951f5d041c1a01991b23102d5bb4acad22c777804d994a6a9fae2ab15915777f0bed6788a928b3ece18f905fac06e1872412aba59598c978d6e8e15fdaf996bd82f6ffa1b5fa58a7b319f819a69f835a7b9c6185efa06f51edc3f43817e8d6d8a3430e996819599038c730a37106fbeecf6d82668438a4bc8b474b8539 -S = 9bd1789015404f8537c89ccb750e04b5fdf82b0daa5d56f40ae64459aa23931ee5d8812cfd01102e3749024a881d3e7a13269b8ce17cbe725cab71c53e218d4b97d4f1274247b112a4376fef4686ff0ddede255e8b085d763eedb7f17eddfded5bbfb0121a3f4b6d47f1bcef7aa871817fcffde3f7ebd75c00c5ab1f6d5b2a6f5a4ecf92a9aecf902711572123eac011bf9a406bf4da6ee6411fef5b82aea8038396052e3801381061e5ac04b8f1d0ddfb678f28920fb5ac471a7046383204d5add6bbe78b9a7c9ab1b3f9b4b5984bfc8a03794075cb101bba0aa2fc170cf6da9401850ddd86357b962582f9bf0e174ed42ce101692008e2ecb51fc1185be19017a43e6bb08e2df7082cc9221895f159eefefaff9d8f3290c9f76934d34882c97989d4afd6a42f3815f7d474a7d020c797c13a9b4786d68ca8a700fe3e0abd1df9563344f0a7bba30d043fc5fc1d3d585f54efaa45cddba963383a0a1f979d48e8ae4fd633ec6698ea4f1e14c6fa2a7f6024524e6db1b0b66160398919c4faccd105d82c54fc98335b531baa9a7c96582ae05be7d93b0fa3e92fcb7a2f30950e3f31fa21270882d7a0e75cafc87fbb387bff937d45be79e95d973684a9f2b486f6649436ceb8deda18aac63c0103c705361ac5b318647aa632d98edf09c3ebba86afcc00f3ebd27505b926a59f67dc8b436d75c5a449e13808aef13e805c35dc -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = bafd723d8ef5602cd03f8cc4f54c398a7a6ff4277a2cc9c77fb2b6bf98a66072ab2205750dfeb2f1504eb6495c2b56fdc1b7c2cf4c5b4824d953c8ac676d6845720d881d7d75f917ee4369711e3b22a3b147f58a23bc70c5a4df586026a853afb4c6e47d05e29c6751288f8263040644f02973a127d8aa74895f4d21fbe08878 -S = 4b5029ded3d15dcb29534fc7f46330bf5fb64ebbb4602874e26364aa52614fd05218973224b1936af01aae5990bccbd92c2a6d20d170acdf782020b2a4ee8ccf5fb9402838cf0017af1bb0e2b5cd69c08b2f4ef222f1340972d21e3218fdde4ba3af10c3baf88883698897c52c7b34d84659468400d4d403355d59f1e21812d8304510dd8bb2963c47d91099dc36d7f0e19f69cba4a83b40f49e332d543c7489c62fb3513dba94e9e98fbcdb2e8d71ff544b774b9303b5e8ab1102e4bb34cd6a4839fc007a5031d87b778e858f20127bb09ce92b96c149915a87a2829532c3608d77425ce38f2697df9fa992baa90900e85bf6eb7100ccb6667e093b376b45230c6ab901de3541fc5dafd0cfd9abaabf7d88908261d36f1146757189f51d167a7294abe9be9a16028718ca3dbbab7e5d43ecb428c2956cf1d44c3e8a875e0b9e3c978fb489988b72f04a9cbd06488162d27498b52298b7efa3aee0937cb0a03740d82d43e9b108b0fd5e80ea34336fc5f711c8d62f74011b893d41742449ba91fce88522cc76208bf901fbcaf84e9662ab9ef109b63d03a45b7e1d4075b2ba5323417f675f61c915dfaed6810f663bffcae467bc6bd7772103a0a1e445f2dab341025ba4c2bfc93ece19c64dde97ab7be7c00f9064bdf2a1fe7c4af045a2362d371dc30e26b8e25bfb258c4b479e5109baa194dfa4382669b0734f1b6ab63c7e -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = 65d1c1c5f2aede8f6ef03b53d0ffac64ae6b9666b18a000e4763ec2997cae7e0bacddf3a284f35e270f3132b2d3c005135f2b10213c7221cb83ae6b96dbcbc690c1162be70faae0e2a11da7475f420186da586b07b31fc471490a43da3cd7190c367f359b2f6719a0211393692703441bd4ebd7ad111b316c32dcdc021462edd -S = 7dcd0def685ce0d0dc10cf783ff7e71f69c18d7edf9e32dd583d46201d961cdc1f8381b5dea980ef331ccf27b2db4f7bca619b29c92e04284b14c6c2ed9bb62c323ad22130641834a4fd703dfb714d8d17939b34b9bda15a018b24bb596de618208c65feb7c262b8dbd4f6b10fac674855b5bd1fc15fd1faee28e39bc495867df3847af4c2b8b40bf3e5694c84ec4fca9deec321ae730ef0b10329318e34331e21ae5bc21bffb025821881d54d9a3f7adbb96fab78f1aa6392fa4fd8db78bd3e2bfdef787054c9c85cc2e07fdff85c48341d587b7ff55f9c96e32ef06aef9df62d5f9ab837f3538d822f862120d2e4cf6abb43c620a7cf08a8a72d3d9dc0f7d02d4c6fe620d3d43891696d7ee9731fe448a12070f573043378f3a2acb470fa7eaf01873af3deaa0906f28fbba9fd4b5b05dd806711427a36fbf9d82f627f1620f9d48fc10c2d1f32c88826faa6f49ea6918daab391079c37a76ff76a6a8696567b319c3adbdd0ee5c2dff7ea8411c52f719ece66297797d3ccc99de851f14cd061dfee6288766149dbf4df8ef4554848f22e3d461f3b9eda7d7cfbd2e5b60b434d86507ad1e7718064b030d470307c22ff18439b2ed3e1f757eede270f4ef8b6e75ce824d0e65f02631ec87782e7b4b39bcbb152230c93087676707206fd4966a4d7953931ce284eb7ff9d5b9bb7a86ad7dd561d334b0052a6a23b25ae9a05dd -SaltVal = 00 -Result = P - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = 01fdd22335a45577e5cc758f73df444818c364cb28096c6197678e88bd687746566277bdcda9e200ba02b625a95a7d9b1db875bed471efa94d9bf54b88c32fbe0de308d32f8e0cf2926e9421ebf0a662073e17420f6ef2af0af81e0aa36e3a7d2c67cc8fe4bd9bf575f859abc1098544de3c907f5f683f1ad66850eb97cf602c -S = 2369b3beff47a12b51b8ca1d8fca20136ba94bfc7c16ebe84d322bd65d569af515521c1ab131ea2afeb2620c823b1753a28d0207c7b9e97eacb303a62da587a7a0417b75b8979f492dd16d5f8cf9cf181777f25954b91acb34c7e688d60fc78054d496ad8d6082678aeb7ddd87b02c07c3fbc627ff44bd89d7a151a4ef01e0a9066e19a2fb6271f0a47d7409fc08ad9990e5fc9fb297ee72c50a39bb1302273cf7a042a85e44d48548d859790cd126fa64bb72cf40beda6b651c7e957b8cbeaa7248de8fed106ccc3106ecc1fd0f91584dac294e0747032c854e60dcfb6ff82b6f7df1ef478a69978a558df0b1021fab6d84cf9f76ce0b574768ce12f5d3d44cd54f21339f7189532f7e960f3544a53c70a7027b782089904ef763bfd8d538654076c822fc0df2b1f7cfe297c9f260371023011ef3bb191c0772cc0edf5aae1897e2314988b1a10ba503907fc1b49cd675d766c65a12bd60bb7da104d7fdf9f2987dfcefcd9a27caeb56d2a564b64d1e86d95fca84e6413d1fdf716595ce476fb8e3c3e71c3e574c5222e706177da384a3c21c4f1a418a799513ab32a0c315916ddec5fb80139a7fe05624538be2130cc26101604504714ea0258672049f0f432bda7c4fcde9337423203e1d6323c090e11668470bfd4a2f910ac5c2c15739f3433e6d38fa8685d4ecb2f837a9282ad8c110ee083daf05b0ed7ec04f4711cb1d -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = e880d3f9d8365b9f6e1bf535b95344a882d374417ec91227c73821268de36aae096d131fb3be7343b5a9251c9fcb5be15cb67543654fd3f43474e76afce28ee19756a09fc0f3c57b82e48ba0f042b68f1738d863316521591c81778f0a44c90c7983a101669df94ebd1550481580fdba9aa2c22a4ad4a45d65a8fa1d1ed0c539 -S = 486292eec1aff1481ee618d78c8f28d59aba6cccd74d1d0e82502d1b27df2871f55348713ac01f9ea9dd6dbb8150a3df926326dc136957f91dad72104f2327b19d3890155cd5f018464c7c2c4c3509b2f47426b119fb124046180b2ec409c4a59da8098baa59a97a100c7539785d893932b9efaf2fe5197220d1706b96ce89911883cf50d96e1f8290bd320f47ed916f9254b9cd4be55f85dccbcd0c5731b2432810182ddbd37ecbda7229e9e3bf46c7af5878c8ff4c96f55bc0c46b57a88f8d5e756a682bb279b1672d43edb783b8a4eb4c25b42702dae46db934af12b7fd3852a5a2dbd307e4730aa1c993f5054152547a8a76ec07d47e296fd55b6d405481b9283d4fa2d262a38772b10da63286f009208d6a98f4174c2ee64f790dbd47c2508224d0a96d3eace8938d719ea730f026b6e7deb0eddc967a68d78b34eb8fb3138bff69d484203c5b7c00bfa230a01957911f5589226228d16080003fc1f7b6d544e7b2a46f97b70d111ee1d846535a84dfd43c2b42a90bfe373d9319846bc069cfe2ce7a23f41e0934c97b3964c2b892dc2f66231f8b6185ef6570d4ca31841cf9b562daa5914d185aba76ba58d66592f3237954424b103dfa20268f049c9749330084d007f7c2cd5405b1b1da06a75662f4f7c280430dfcb9bc37bdba64200273d13c319ad247ad7e20ae26920767ba43b2b1a02ab22b188fa5a12108d170 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443031300d0609608648016503040201050004205ea6db376f12859c355a917d06abfb3f5f97736f5bbb23f71ec1de277ba047f2 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = 1179b364278cc399916b066e7ea2adda5701135fe737fd3cbfa320e3d966e3ad7bbd67cd5e8ec4831040969297d0b9f3572150cb36940c9bfdd9abb60105bef904e4b0b6569004f13f42decfa269c54bdaf9a72be8061d32d091f19840a2deb77397960755bb0a4ce81ae50ee694594aa8311f6746b4b96b0073fb6fdc65c951 -S = 96c8373de5bb82b7da57e144e219250dbba46fccb74e1c325e3bf19c16fd38e2a71e642fcbb6f0fc8ef77739ce1b8aff04a967573b1bc71c894dd5bb29f3de66736608f4f4383c0d5329a2a7fb127a243544acf40d245e2068bb21a8dce0b4d7e81e165086afa43929b44e45f3a5d77d57505a86651da1dd4fbe0fb6f83b37423e670e06c810db19cdfb2d1d36c441903affe00f12078b229cb368ee5e63c451ce391f1eb1161076fcfb9dc2f499de5a6b948dd2b3dad0e6cc1ded8b27129197fa0998d6fcd117c37cd4745d844d6443d0e32a7d6cb34510d1270f31b25f7f2b4f5deb8bb94b7638f058a59eedd80837beac603775c67edf03957a6ffcf7c18c8a376a02bbb9eacc175904c0b5c09d29ecceca5ddb3d8143a6afbd89a1a3b372e2c7eebff1223b1bb4f1a26c4fcb6605f1326c6e4a25c9ca7eea8441b0495f53b7c6015fda720e62e1023fb039f1e3cf1ae9490f46ff75e0b5bfcd354f91e0aca5a4ce22e64876002e304bb7eb1212171225de212e0ac5304907bc803b61066cf68083832033f4902cda8e6ef109c638346f0598fb27f38f2ef130c81f78d5721b89b949d364f0336e3b4b982b7213aa7afc9aa35f5fbad2286f4a4639cd981c7908012b4787ab506d3bb745c9a8232253d59c24bcd60f95ae74debd5967491ad8b5ae564a09a79de6438090bea658b232d0dd620e548e020e9971ed4bcae5aa -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = 7a143960d5a8c615dd58a10ba92eb257888befe939812d105f7d36412f291b146c90cc8f9584e5a75d3ccb045b42f805038d9304d5e944dbd4a046a63a53becb6a294b38262cdeec02efccb918742148fe4e385df503885c63b4c10d8400189c5c25dee4f06858ecb5b8cbb2498ed6286117047d0395a29df503cefb75f7d18e -S = 5d5f734d2700f3dcdf27489b57adb3b488de71bad11e6146dada53b80e4b5bcba10695996a7b52f89aab2f3ff43c17355deea644c2ac94fd760dc45aacb4471137a93ae4d9c4fccef44742682f0f985f26da2bc70bbacb95550f99b9003851b7a998bb1535218f7e47d41c52b79736f3005ebe8f46c5d4fcda4c7ae36bf68ac8c527d8589bb841abcb6d0cf12a797622c4275548abfd2c46d35132e5cd631da7f16c05129fbd1647a470f73c7417ac85ff85e71c433c849f5123353e49ce5d6bfbada544e4aee9887262a8c51b5cf6ddcfa15aff2315ad910d74e92245945309f71815dfc23d4b830536f68ad444637a808077650590407e25923247aaf53df43fa90d465ee06d9a9a5a7ae86d8a2180d70430e4916e7005ffb4858712edab095f8a691e2260c3fd56a4311dc25b4ed8c4ea0e43e4bb44ca26ca8ef674019218af0559de44bc0cc5f9463575ec28f3fc9d7a4d0e9b00972044b01187ca06d0dc7f0c5ea336c0e2290e1367d12101f293dab4139124c217cde848e7e4a0f15b3d3805767f88aeec07bda40dd23826afcdca5caebdf54c32021113d711b6bf07300a2ec7dde75d550c93562a30e93810c9ab3ed830a719e02df7dbcd62c4316692b69ae722a01c462e5cbd31ebef67602fdcc9580e6e326d77a4f2a0ad079acf2c2592748f9dd7c7ca7560e4cb3e7b60e9906b8bf02fde02c9c5e0645caed699d1 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443041300d060960864801650304020205000430fd72258dc3162b6f2eb1784384443649d457af90d1c6bd30c443b7e3ce562e7d7e660afd677d87d01695dba2597a886f -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = 8b48c7483bab7109f4d05b8cee9338be36640bb068fbffeab94892013ba9f96c5d60c093b144b229f3b6f8bc46d7858ac0f9b197295323fc00f8f582bf0a136f612ae4a020342dd883293258986d1eb07e33a4d42735e7725ca89783026f5d219b8f7a9810e3abbfad114f896dbccbd778fb2e90ea0a11f4d640c22d8b41a127 -S = 5ec4ad5490edb3c268798a03c1fd36d43cd64e6665ede2dc2cd77d833f15edb7b836fb7c31a9a6135b4ea1c84f8ea7513883d8d38037d7f086d50d69fd730fe300b5c0090f4c7cba382fe27f7ecd56a0df98f6b9e656f11169c717fe8636fb2cc6ecbd4a44ea73f91b9189b640bcf51870ff97b23a4dcaac6e4852a8862c73f80f89e25daeeab317dcc570fd7503421989334ed729d453e2b372a58ef37fc773b25d6911aa52a11d516d1011b052c0f9f33306965525c4605884980a2ba24deece8271d65c1623cee181dba8f953a577d989e1d7f6d5393920cfdb9361ec22c10bc85926cd37f3289b1efa6ceeb78e7a1d1b54be2865aeeaa9dddd4aaa2c72353338c247411463af28004fe154b3e41fc88f137c6ab9c240e98f0441237111f9fea9709f41b45cb601d91ee24725a62e0f04a72aaada19b8a25da14b86fa2a5c7f4a359fde437d7a2b9b6553b6dda023e03d3996dffeb8511eb67959c2c647e28f8e9c0c17e412308105a10c0bc4d2820c7d6acd718c1ff38fd1e27db4dc07d2f12f45f2eb8f414861bbace017c6bc4ac46f815269f68212e1c0a3fca93622fda40102194efc58c816146048d49af8717faa6e58251db269f1fd075816da19ff5a5fb0a9ecebacb276b3bca5f6050b33cf50e065320fd703ec4779b3488f1cacdc6a8d469e9f0b5a97f7632efc417bc9efd2ea18d768b27b8863e753588dc3a5 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = 9e1d1d96ec18b95c118a04d5d8dc554d705565e87ae1048961110af3ea62912e0cc2612d0150acad9d64fc60dfcf694bc6640f6c65b7bfa13a24f5c5bc130a1c337babf1cca58a7ded33530bc660e25a2989b3439bed9a9babb1b45b82279dfebc4fe32b769ebb94a8fff31eb618284241ce39b3430bfb415bbe2ffd6524b19e -S = 728ea547f16aac9bc1449a5614fc3612292831c3596d2897ee8426c04c353f4fc19590bfd790660833fce2152b026327eebe9c934aa8db566bf63938486bf8699bbb6f2cc7882ed6e9e9cb2d3b0647a5355616604576b12d26123bd60732b2e240e9015a7c4044a0ace6f18d522ba55bc9bed1cf88f94680150d05d6a8bc58e74862f7588993892859f88c92e6516f02d57fb4475a4c4872a211ee03d5152b2111ac0f46e9d826f1dfca27a1ded9888b8a573e6702f116475a93cb2d7e6301ac8742f3dc2c48403e4205082b7e4f8fb21b814c6f94634a50e83e4a3c0900906b162621360d506eea63954581771c72b2abf6bd5bf0505e3a8329ca8e1af6b497ddd7695237fe454b8a06498e4308c0b7f79102ef07977932a57927e2c4dbb3b1199ffeb33e244f536a19375fb5ee25279b425eda4693cef0a4904f8ace80e7a1916740563e4fcc18ec4356dfd8f351fb3969b704233e6c877ce339e7e38e98e0dcfebcb0668dab057171e643b6669dc187f9ea8dda2eaa295b8f88a8ba8f4cfb579d5d33681f0a306f2f20821b67613e18545059b2f6e8049770fe4b280ba849ba38dc6e70949cf6ca160910653a7e3a2c36af5fa1eac778216ee33a60e67dac7ceb7a35cf6bd926e1a16160e303e46afdfa28b018a872f205309035da90752c179f8d4de48f671c08a6a43f7bebd4c49391514783e6989897fabbfdcd87f196 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = 45036afedca29e7386c707f029cd67ba4740e7eddd38146d8be5271ef46c895868f19695c1f5a26d8ae339c567e5ab43b0fcc8056050e9922ec53010f9ce10b869860f88d4fdca375ecf3a6e65fc37351cf33aac75f067fb4588cb8ba383e27790e95c3dde5f20ba4ab49255ecb8117ad14dc44ae6c09790175980f7b930077b -S = 634e95db19d75fdb681e468e2e9f991ea38bebcd5e44717148be6c79625136182c8c3b136f09529d3f95e42d4da796a4b9010fdf3d3a483e5c78ccea3ae200a382f1c690a01e2f450dc1128c014f533bae31237d48890a5bcfb3996aecf790d18e6601d9b12022d7f134b1243965727a8ebc1479dfab096298a116440818aaf961ed9aa730e3df72f7d115f57e1294ff53549161b66d6f15f3219323fb067bcc492e9320c7b706613cca0ef030aeae3fe14d04dbc2416ea6d0ef89ac48e0ba83c90e33df7dbe215da1c7c70bfba0cf1ba2ceef1900c76c9216d9c5db17c9d3e2401814609defd932c47b864a65e9c30f75e63f2609ec2416405ef072240092dd23f835fd415d190eefe2afb80f5c02ab433946062d3bcb5c18f009677e43f5e02fcd4a330eaebac40dc788e4fc6890c1c75e22cc2e801153018b316d0bdb0adaf9b2fd98e4ba7b3507ce1f1627c006a49ed81177cbbb5a37cb952ca93655ef2fc4dc34532f9f5ce35906682a295230a0824934dc9ade9ae445d4f5342395badae4371c23635bfc03effc650595381a352cbb8c9c8a353bf795799b3d41520a966f48b7fbb28389f6eeb02c62ae21f7776e8a65b7b0fe6b10f0a498ba9d2ab503cd7e8b79fed5c1a9239766f577266a868db7b74e274b82107cb2b6e8dd04149d556258bfb92b5fa0ae4f05f407191bc28774159066857383d64d5b567e44e706 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003041300d060960864801650304020205000430cb91c002dfd7118dbc156c9b6c6faaebf14d2d79a0d28a084b2fef838a9fbab5fd2e5f9d6ee8b032d4f6588e5219fb02efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = 4d72aa3953630bbc1c51a7fb6c7e0375938e8afbeef430c1b0ab56b6e226ed11a989df2cc819aa9665f14e6410f86ac7010fa2e4a18f43df4df22a3956d0e25d4c0e0c757c520482b7b9c1ac55cdfdd67ab19676989f35a435952d71ef4aa679bd67fabc77f45fa99910c77c44e604ca85dc305ada0d4c37f2fa2703b57c818e -S = 13e21486fe238e70f645edfb21dc32ea0f415e5e260483799870d947151362a7249f700818014c1707016d71a83c389ee6f17354e20b55402f4c6036dff827d237fc7b24cfb2b5398fb34beb35d2d61b5c4d089ef832c219162484d453587869f1139d7fd3497ff4189517ecbb2d314c049d4e86dafc418c716c3e4c2803ea03c66b90b93c620aafac05e4252212200dd1448e34914da304148d1466e5e32edaf6743fa43c307f24ec1a0d46b4bb941945a2ed7c02da826476522cf7fe329268774052310d4b817a4058d9ae6084b4f1428ea1fa5a5dc0e666ff9466480b9f1d6142890010fc2ca3ee46db1ab084a524bea1c27b89adc87ceaea0a1d9e8d83358cfc20997b8c94204c80871c0e9da89b224ba42181743b285157d3eae18f19f8a38a102e53d2378aa241b5300a20592bc487651264dcf9084c3b1f0095e848f1af5a940a25ce3d0ae660ebe9ea09858bb366451fe8f4d1dfcf018938db14bc4efb1c4a2a7f5b08facbf81256ffc0453e4ba14744d1611e85cba35baa9302bbe959dfc2c0b96c932063fe40991c2ee47bc1ed97999f8e5f747f8138691db117784a5800ad4d210caebdbc3ba84e8fceee3bf59ff163c7ec9c0eaa468813a1fa8215464f390fc62d45993db71a7e56c4a022fd4ee377a725e87a2415877a6365b086c76bd2702abb265ec3b37b198eb84e9ce6e1037848c10bc132aa2f8e1af165 -SaltVal = 00 -Result = P - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = 709abcd4c8297d89f8e4a5446dd32ee612838200c5a990950b091e21029661d997dbcb35f89924ac4db2dcbea345a038281b2bb49e425f5f0af794ffacca303434fc77fd332ca57fd0323a02bc4c963d6878c5d375209c1d6cfc052aaf359704afc66a356028298aea2e6817a22e387b3861f966318c705898e01aabf11fbfd3 -S = 95fbadad59d07287451d54b9645279f6fc62ea2c6dcdea2d49548a992844d46b559be0328662c2be146e3812aa9bfb073ef21f2c73dafdce8297d70a04ab3bae8e0237f6da726621da82066ec76afca2340e3ec256ab5f3e0bb53833c78770ba95e39a7f844e9e483a6cb7f98d496e4eea095f08d809b422dada7dc779303939e5dcc644bbd0b22a339bbee4a9203005aa34a276ca5c1135418c705b8d70284ef279f49421304b28d1ef8606ccb2c9591ef36b418ff3f52933ce1b059d9a3d04e483c2baafb719131f29f1fbfabb85c7bf0b979ae3377a35fb877eab9dcc630759d18b3974a999bfab9704953d661ca6449cacbace130869c2b0751d205c5c6ffbeaf3017e9bce964b2d4b6af2ee8bc9897b6df0d53b061e89918eabc9ed4f46da59748576e816c5bdd0c847a411948d43509e994ba816d6391b041f23c9d70d004e9d3c09fa717c4531af5b8dca8393d28dbfe3b07d6a88da2383181050bb033b8f21546432f62caf52cfb364e87ae5fea1c6e2948e39aeeaba89797163fb2b3bd35d8bb8832218a5d931d351e9cee457504ae70c09b51004c826c913cbf61f570504951e02b1e47e9ab3dc47b44559e77d79b734790a1faedef901d267129139c66c992f039ab42d15635ca1ced47ab12ba87e12fec8bb574c9dcd94e7c6ef54a75fd568755042e8d928f344c65497b3183eda9534db97a90b24927d77e2e3 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = 2be1649aab8e12b337a5d974ebe354a0ce3e74f4fc76c45a05edf16090b889e844f60321e86000b6c822d0455bea3812243e72fdd61276b1bb9a781f565db22b488b63a47090187a56e92a2bca36887fc891b6759f1f167d52e467e73fdc8b9cfe478d0c8c44e267a9a1ef107ef2cc4f83e04846a0c42d269375c5a2915d9ca4 -S = 11a6268f9ab602dca7444e9e821e9e9dbf2ff6f875f255d8dc202f953d91d6bd13c74697c70412131091a062f7511b06264d083ed49b24ad429d35e9fb02326fbb2b206dada13f5aab60b5b3db5df6b83e80eb946e199206dc2fc7246ffc6f663217fb5ff2ca14eed28a58ba010b5ce47993b4b66ff00bcd20720a4a6df35a81aba6d277b2ac3fe65dd7089b6fb918831c54165aa833fd84fddc5350bedd1517bbb180dc63016a10668add62ce782292af053a1419970cce6c6740d9654b62d836b7446db56267e08aa204fbc3d3352c196c6b757cb08f137b0653bf362249dc7a7162eb3d82764b51b8f7676401e89c3437ea3fef7b727a096143033d2dff653107e6bf20f9586b2ab75a164d5ab84cd0bc6e04749ad4599c80e4edff189c472b02c91b31955284c42aa5390d83defd8c4c24f14e2aa9668fcfb0b683fd7702da5330e73cba32b77a1c197c4385b5ba5e0ce2e5a3732838fe136020b870c238ddf5900b662dbed59e9664754b63cc4b8fa3766797b2120924d712935f4a591e61d292782bd6029b3eb434e33c06dc53d1152471c000dd8e9eec094ba6b3dd5d5e71e23039480df29c2b00fffb5358bb5628adf89260445ce4ea3cc4a701af52d382ed2e9c1db9837c29e211332f9b6c176630f307c5b0d0e28a1a09fd285ce2c12d1f18269cb1a04e5c1c1740fbe8af04edd32abffd09ca5641806520eab220 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443051300d060960864801650304020305000440a6e9bd72eb12cb01af08cd796b9a5d7f70e34e1c142af67f862971169f7110687017d74eac1c5d45f013743c20ae189d7c9c61802770a915b37a0ffba5ee490d -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = 1dce67cb88490ddb92b9528b478d3cd681c51ddeb0a76f3cd7b40394d7da5b6cf0eb543e854e07cb1ff5f2b3b58e53432bfed58e180b6ebfcc5888ad92975fb032faaab4baea7d8b7efc6e885e21f749471d1bd4fd3a4ce6173d8d874b99d4e2ebe3b254b08635c3b7b80e31c9acef90df0937d8e59cd158bf4959498a4881a9 -S = a73f90dd956d119b2364f15b1772eb3398cc0dfa717bef2d0180ffb42c5a6a9f6240e56297fffc3ec10b8527678e37c126a033cce08451a5052575ad1e471801df563e447e57626a09a5b218aa5d1b3ae3dafa8a43e0f5b187f9d11333cd07a52a9b0844bf61f37f9107fb9770ecc17f1858767475e9e63945bebf12c54a25f9759cfa4b11c605d41cc2b7aadb786a03fc41146ab249d984f6b78c89af37a6d788c67f0575faba520cda93288479f02c83e78122ae5b88ceb6ecdc429f5e8cffc9e1fc78d8c4e638c74fc905a2ecf6fb2e797a1d8b86d458d0d594836f66b801445e743d33a5f936138a1c18dcd08f6a826fdbe71bac84dea0884e5310316d9a28b50d5f40d441d5385db88f4934b4fb85538e9838ae64f9055da047f8d49d432feee879301bed3cb7c2774179fd4f76813284a492d1c89df758ad141eab289c504bddf9934753d94588c2c9fafd69b6b261ce320c103bbba0842e9e2e14fd88d17319f9a7596a55701c22226e255d06f5dbcd432a930758725ae73adce8be417d7a94a712d5c5b3809441557b348720a35da7de59923e59c92df63de405fd913fd7fbf3407c72455d3be934e3d7a878bdaf88498842fe533a03387ac4a6271f0c3621c33424f610eaaaf6878fc99660b2f8833935b6eba90636eeb9b9f52fc0f3244183e59caf31d890b22cca748c80abf9837808b4a1fbb9cd5c9a9b84a2dd -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = f0b048e510fd9d75f3d7bf3f460ece324aaa452f6e2c2d6a23179114ecaf3137b4017ae16523b684b6bd819d45c87c94e59645e33913a67b824a0c63b52b3ba3d18b41606f6ca8489a7ff031e2e73dfcac404cc0cce0ab25565c2a0db04e8d7aec5683ac555fdc894824f64246f2783446af430c501ba62f4756d15907a38d83 -S = 05eb7a32c9cefdabc9208a080b7542bdd0e1e2e4a8529c29a7529527207a0b5105464d0cc445e7e64fe2a9be5cfe6635d4fc1ae7bb7ee36b86fb2ac72ac7d53af6b1dc6df2c85d9aa3513ecbce8ecfb1926332f3119a4bfae1b01b2565376be9872cbc7bbfed88a4d2e67a78587ca53e09863bf21ac1350bb38e009c3c458d2df736b1212e7980d0a3735925cabf39ad4da1b98e9e7a6e4f73aa048d8d686297fc6885e5a939e3195908e17d32f7e78d22e9eaf3e9373ed923f0b2d6b45497351cdbc9fb8ba0aa912223121a24b2b44b291743bc3ece0d3911c4d54ce82f883493805273b0fbcc964ae9529b83e6f22d0aedc8b6f8b2a410abbce970cfa44e30c9b97ffb312d5a53d904d5e99a86745a70c6c9f8f3303c31b39dd587211cc49c973837d89117583ce5be56ce263976d9c19303b7d8971bd1bc0a7bfed7af8ac90329a628a85cee99a3c5e9bddaf857467a8fd3b015345e983946a1a22c4bd2c18e3af937555a08dcdaa055a8fed0e06ebf19f5890ed0dcae6e031e9150810d654925a9347add44fafab80d3bc8342e9f41e60ab742d17d368e02e82d56418c22ef10021431c00af4e21b7436aaca8b67dd7c5b1519ecf0c414491c1bd8a1ab3fcb1bee7d202673c0a080f56ae2966605132998c79ea59bc6aeab631bc0064187f11ef3273d5c6459ba6ebef569b99ac751ec0edc37492c7c563991a0dbeb2710 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = aaf54244327c90f0aec7add583fb42cfae696074fefd5c9a80d9dd1a3b3d33d31eaaeaf137479f6f268313dad0fc7e5858a026ea4b112fee1a4eb5e8ce911881f77397d0e55621d91b046753019436afd98e0455f44fc93126ae106e77df4d811b98716aa573bc367794d2c97d8b12da1b7b233f637ccf6b8c3f15359ff179db -S = 0524037b884cfc8ed0047ca0cce7f7cfda9893c065ea6a1ebf673398e23a56aa4b0a179f1b776a3bb716ea83f0f9f863661aaefe7f50da0d714d9cdea2408a09708d50aa4c6bc6ab31240341098a1d8951c82e4708a5cba44d0d0b98b09dc8f8781ea59d9d6dc168bf80d50e67fb53763aebc6dc12b19ee6ef47b838d58f1bee5f6f3a263a430b22f633195ed0d32a92c08b2a4e75807f1b56edac08a6a87720c611ed497dc184974ad7d3fc17dac4c409a44c3fd29a35259fac0ac2395f81be0fcfedacc8044397f4fbc858640af552b2cab5f85a042d41050470f7fa485ed38a0fee6f9e935611e33b50264ca04f8fc1c6e15d20d10b023ae7768b0b87f99fd298e7663fdaf5dda0f61c019ce0516daa8db07f46dede1ad63f8839e58e3c33e69df238c3481b7ebcbeaf448b986ccfb09b3cb62249ecea2315be42cc6876b7ad17a79a10d8bb4cb83b7e33fd28218b58690daf5de8da3824bae1bc9d84a8c9c09b5f4d67497d2d5b215bd530d41decf24d32d1c73beae4e6edd3d2859f11c7d8ae60673c94f1a233e285aa2bf8be8de7c5791bb6bc624ed74bc1de32796bf656c744dfa9ebc3958b71f2f26a9d28de16927aa2923e6b897c3c3c1f719b3239d1e59a136890b21efe97081cdcdc69a39668791fc4089fccb694a77a88101358ffb961792ca3c41b15bb81e1edd7fe403ebce86ff17c5534d441d946b7763806 -SaltVal = 00 -Result = P - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 1d8188e62be3759b150e29a7b864be80ba2f00e747cf6caf45645f91085cc25d0ae6c4c55c97bd20e4dddda23d8d03af33a13e082e3576602ccb4832d10f7cb30de94cd2ec64e92b8c7f1bdea66491665b313b153a2d6dcfeecac1e5709f113999d8abc4128b58dc232853a3d50fcbc971beea4a4883b1691d6b195b3f295a12ab6bb393c7e3dcfa3bcb6bf7ddc6b22d4550657ed311590330172763930905d38234c89f889d85bce48f451b21945cb980e25d8de6b6fcb2828643f5695105a4fc5705cfa9da5430f6fd98af78b2f2a255eecdc268922a71dfa3fd65c6645c6204fa1afddc7f009e24ff973f70accacd07ce05b1a3e352b4cbceca24c691c94acb40f9ec6f1964a3c73d4b50ad1279598711ffbd1e2ba3e283cb33d0189ed5341b2991aeb6ccf331e23d49f473adf4524a50d876089c824488b1a9d9253d9f3471ab73cceacdc169bff8b6ed6258a940ad03454ee148c86376c6c35971db2a4901980fdc3e78d1149aeccc32424162bc1fdf115e5d2a138b914397d3384bd4921ddbaa251569f71d61aace4b5d947eec59fe57827cdd38c5dd01a0f7beccc0f80662073a52aee4faa558a5c1e9f98327fe91e29340f678c8734e5790994c1ac8d9da22b57cb2bab896d45a2eb0524cc8457275dd61f6c4eec4c2f697a07d33d07a46685c95ec2658259a7bc0dad3d9529ac5485de5cb014e9b7dc7cb6e2bf781 -Msg = aaf63b5ed0e0aeb7ef3da4f134dbc2e8942acc27029e7366e5556f51c9face8b54e98cf37c936326f824e445f464c7f809db80b26c39133766f5285c0433620e0febed963e48561bab4ea06984c094f103415810a0b9439485faf07c42a491ffc24586d07dc52fa1f002fee64ab7d0db69a27dc804e6ad832aaeee37eb130465 -S = 28cf265ebfccf2400d6129058b7168cdd9fd44f44a74630d8df79d306b41a82d9ff0e7e08ba01d31514ddc3ef87dff19321346aab5c67959c551695cfdf04bfbb0ab74affb9edc69b9aa6eebef1d4fb7b1ecf7fa30ad5834136de2510fa774a24799b6f5e6410f4f14354c010f7f9e4976d7772ccfdeab7eeff704e9531ec3db509c1f0913144a444dff8e36f9f50e6c2c7a693c5ed440d95b721664aff953a18f033df5ce2fbc2902d9fe4644f10d50f69abbc7d2f58a80e6b6b4c94d75fa53bdec788315e87c103e81dff4c5cf7c5f1fb14a3019cc89a871328969ba9d12fb14326458ef1df1dce42b02ad17db4bbc75161e66aecbdba7ebbf1709fb208642e3e1a3c12738440502cd235d6a43a08d24f6a397b0a5b86d0a8456e939d4422934917905b3772e2c5736ffc0b3cc8b8bbc1c9629ac37d54def02ec83a106a6537adcb6559ea3cb2024a1007384e604fc64ee9fde2aedd129348c7fc34b240dc841fc45b2fd2c9ec16264b067f139bba8f3c31bcb4291b71e590bc953fd63d1ee44a901d47fcba0d12150ebde6f50209646831e10cf3fa7e129e5504fbcdf4832f5589f191925dd85ea7d11031cfcefa5ed4f9bde552c4270930204d37c37faa8dedcbc2838a36fd425d2bbad87660fbf8df20610e666a9c382b81b27b0cb172a188c46bed70dfca37563129376b2d6e78d4be92b81978031a84eee45f9731a2a -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003051300d0609608648016503040203050004400ab1a89aa9fb0c29b4163f44d7662e24023b152d820dc90168548295c7e1b5836d3de20a9fae39be49bcc40d0c54e271a4f6fbf4050c315553dcb6a3db8b5eabefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -n = a74f2eeb83f4f87768ad1068802b453e7b9808db9d1758ce52ccc70c3cbc4cef2afccf66b1116896fa27acc8cd779b4df59757e24bcc0e69f409b638cba8adbad885f95680dc4a7423d576c448cc38b00ec0292ea3323bd1eabe2bcb6d9e9c94665eda88dae5bcfdac2a3ca71b6d3bfd31cddda0f41f14dc5ddef946a9f779398b05e46678d2e490ac28c8807e9991bdc00ecc28d1b7cf63b6f3f47961080fc45e43729013366c654e1189888cfdb7458fbd56ba3b29756087ad1a0f86bc5e1637f7c6f881343033bec98c22e5c22d91ec2576c66214aa895d08c29707e0c181c666727767f5cb99835eb35a75d44033e5fbf947f7ca249861d5fa5b5d1cd4845d4d241048bfe2b06ffec934665ce371c826a2bb4c2de1dbd115a1e220465c6eb9d26297e2f9187726926e33f6ac7154ed73148aab86813b11b7fc043a969c8b9477aeb6305a73e10cd9db0cd5dd323a9c7ddc08accc214b4a555da9cde05f3a351948e56848d543ea504071f6251e035af576e04e55725516e215ce5b40c13f4029caeee38e4183c834127c857e1a0ce52e2db2faca43542eed0fc2331980be2e70ed938e007d1ef56f103f800dac041bae43d2117fc7030da4f4a87b1161c7cdd46de4098d10167e028fae2eea05da82c687ad82817efa65e973845b5a103424d17234fa78da06984549569443fb9c8755c4627a5b04992e15c0823b45a855 - -p = d86293ff70f21a0aaf50f3e91a38fbd29c3e84a034b5a9d5ead0dfdf0707cd9a85bc5e17c51f149c804f9feb00c2aec790e605b53108cf008e7636ff32e0329af9049e0bc48b91e2712deb4c0b1c2e943da090ea0dfe4e64c79f4242366eb8761a827e64d7fd3ae66b340093a21024418db44dc8305fcb097b942b2f7c790835d27e24a9653eb7af54aa06482f6438d4676965d602f3f1f8939e184f6ac9c9df083fb862d617af4516d824f419e11157b208009cec826538f80331286925a47da40e6317914dcab19706831ec84f58d158d945a354d3d2d1900ba044e25741168d334c5100ad408591212f26481759d46a735fa5f14b650bc5ee0e4f059538cf - -q = c5f08c5456b320360fa4338f92b57a8c6715fb6ddcb07c2d0ff93b6549e7df6e8d3dafc5710f02b42d82f62ff2d365fd7d9b1518eb512f55cf10f347829aa961ba9edb5c5e36c1d899b4fd462e9e89050bf7edcb20c0b54771bf22056a7f2091739878dfc53047ea7cc2af9ced1fccee39b2e9502307f44b1e8f3065aa9d2a45e1b5ee174d067a32fd3573f8d85c17fe3153736e9b2ed6a9fe068530eafdb0c42c7ca5cc9fbf44f84594b324965f537f1862f2ec303b42a838ae892dd1a59b577b7506c663638c837b67d6e6d03066b71967ce938b381f91f50fa526089fd146f62977cc41111597481d9c3af2c099279be8e6cc9fe7c64d394f9298b44a4d9b - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = e5f707f500cc4d0d36ebec7b49ded4c1c1d8fd4186f5a1a5aec2a97e9400652b2aa57ffd90243299e5eeb79d5d3900869300a9d1214b2c606fb05420c81af4e9b3c9d8a5809afcb52189fc903b74ccad7d22a9a431834f9010396db75b58566d276af935f9b7132a92c3a39d0c179f002644e502dd2674fc3c66dc8c7442f37f -S = 84108250f5183b7a1957f5ce9c10b762fa7cf3444f76485c0b5033e1f922d45ca86feb96407efcefabd35bafa24b1f3e5d86ffdced1c3757e23017bc2a816e940391eaec9c2b1e01c1f29119b4064c60a2f5ed91162b308e21f70374815e916f134f7e8907a8fc120dea9cc15c53741ae1d1146942a06d0e1d297ec0fcd1e7024bacf58b0b64ab63f95ee3e3f3893a6a892c8c949ce1ad5664196bc7370411d6c18ac7b3998e5d9d35e6c649f9205f0453ebdbc9eb6da6b4aa549b2af507deb7ac776a89b43b87e01be516e4ba36cecea8fa598321beeb7eff47e7561b52be6ca99fe8114b9be68b0f77c5d8769c35fa04d5c4894d331e7a1d65f25b44ca95e8074931bda83dbb36ee622582112fd918a732afe4040280395fa87dd566e69b3668b295a53aeb3ade6835b32dc8bde3e59f6b6ee36322b39d50c14cc98f7af082468be675b73548f5194dd4c907d99db54f785097cb9ed28c812bee694ec4ee85a8d41501d0a70d82cd8316c2b63d06e2e502be79b5a1f7c06735eb5b850cb0562a117972f171e04870caa751064db6fc4b2d64a2ddbdcf1d17f6952b630b86d6124bf6a7449cc57ed4cafa192756571fcaea3e0a52a92baf4d18f7b61ac404876b1f7e6a53498bb9eccbfe94992a1f326017cdf91039266d9a3deed3dcb124ae6aa96402f80372881a207dd833b4ae38d9d9f5ea2f30a4fa45e566e33e1e1388 -SaltVal = 00 -Result = P - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = 5eaae0a318af7626f80e9c31a4e7bc127d24e823c80b1efc0c13cbe7baf78d95130a3d0f47ca2deedab7aecf4c66d602f9d180823ef1932add8f8825a35726a7482e90da96c5821ccd6ed867472f5010581590b578cb6b71a46b60510194630cc3bde1ee4dc9fe1699db21e1db6bb2a6619a22a4bec22c3827525b541dd9cd2c -S = 0d5434fa33a83f13477d6ebecc596e1847218ed9dc99e9d75a175a85d3bebf47ac7fa9b537d48f49cafc12ad3b239a7407f56a27b9dc4ce222ac838a6bdffe594fab2c6d0bc15365a3e90f6765e837ad864105decfa723101affc6c87dbfa0cc0234b9f1fe033d34bd9a5c4fca3a5e228b3ee3c75bbf000a6ab654c2448a43a6b4d2439ee84bd125fb44688a942e847dba0ccf781840a0341516080bf7dc1ed725b566c07e846840d02ab8fca219127ba0f7fec701c79a1a8c7e1a3db32985eac37a2d15b8e22ba159a78bfaab05f00934c95c1aa8d9b350af9ee17de47a69ec25a05572fa57ae33d9ef1d7f1f6d149870c96b2c3f266df32e1e9ff28c718bd03d1b1a7ae7b63fe22a82c2b7879c117c7d16a805efda0925c02aa5759653dc6cae6f1d5ab02d718c78403e40ca30a9f5473777927980d142845178535dcef705d3ffc0f650ce17e8e984da4bf98a78c0436dcb00f96c8aa5f893ce4c2f5088d87d6ce2c90b09a107e3431c0cf855f641d964866b56f409e9bc7bc6147ea3838c1d78c833c973f2f3040872cae6d226aa77e95ac907dd514bfc3534f76621c4b663a0886fcf34e5f741a2dcad200943da40b38da72d6d60eb3ea0489ba6ebc1d0a5b19c966cfa87d72ff8ced17ac770f4ac20c88ccb2e3feae775bcd9747a5c87ac38c7294c7a99c04e1a421b14fbea33dac05f7efa2c0fdf6988cd8f15ac6751 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = f11684d68056464935458c80bb76ecc5ffb35a4c35ef4cc51d7c1c32847fadf60da0512f3106ea46858250c53b0af368ec6ac27695364b51df03234ca3d688beaddd4555c05dd6acdbeccd1fbbe074dea107b4405599355a6b6ac7d1c56401ec593527ed344551a2bfebca3742e0b74ea6f4f9517fff54074a1bd066f2105fa9 -S = 61caa531f63359df1779d5765223207864a01b218fca9a8ca97c125987b1aeca6e0f667276421e708f4f6943df074c48b58384cec8e773e60b4d2c2ecd9db62afd9ddaaba4398d98618ee89c6ea170ff53ad6bc0c08fbb3ec07954fdcf980df778b36c823f42844be7793e78d70248139fd8f6b8cef38d2f5a93e8c5c0b5f5f879f3f929da5b7d9d9727c808ece9290570051238b75dc13decda4e619800acff51f99538f97db8dbeeadf8f54bcc58c06433a3e018dc9bf8ffa876534cd4d2f3b5e88021e8141f0356d01f5198704ac9ebf3d4433f92e12afd6dd6ce5a734800fc874a0f1a4281f7120380db8f27d2cc54fc51291d68c2b031a046426243d2e1c34cae5302685e1eea7aee04d01a1cd4326297fc605af8a6ca1943dc43d9cacf9e713b9cf427628b54ef0da3bb13eb64b9dfdb9e173176c693453ebbcfeeb9b637bc9bfa401fd63f1edcd6fdba3504f73c7f2305683c8a58ab77250813cfe94fda23da973d3db920e3134e94efa3ecb5f43211b3d12c2ac67d7d43fc7237cb629bc8b2bcfe8593945feb32d3a9d2828a2e16efa56111c3d1e6406e8a738313b615a9ee30edb4d03028b7ea0545efaaddcb2a941129530f67e1d9d870a529c6c649ba7db4bf2878e268f7794943a19a0b9d230250491a870cdcecf971bd7e66bbab6a6e9ffaf5f8b727f00532a609975c78820b48b0af715ecaf6867bebfbd708 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443021300906052b0e03021a05000414f3c22813bf0da5f5ce5244a03ccc74c41a51caea -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = 6b7c63bb3b14afdc085c08805123108fef29976a4c856c74d34473d1a553f86d8e9f4340377a6dd19d4172f9c13b86eaa2c5ad6f68ac8676e2db67cb3236af26c7c558688c15cc225fdbfa57c5dba883dc080bdb91ed95d7124b0eee8704e6a0fd37cabaa2ad75d63874c921c4c91e61863cda362e0e419f4dde8fc10a8444e4 -S = 2980e019c0c7e460c720ca8e45e8742a14a5c712db17cf51e8a5fc7ccd6b2878c4c609b1ccc6258493a965a444bcddb6a21dc129119f4425d1a707555a6b50bdbbe0cdbdf0abcdfaf8cff67c2056e2e9df573f425dd0f56fb1ce3e8171e12ef6e9b0062d5b393fd61b723801a9f57bd8dcdf01d0965641607e3c952715a729e71622a3695e16e92b7f8028c3ac25edaf3ebc34bde80113fa8d4d4f7a56b6aa0100cfea550a220a22ed7b24d35f2e89ab0709ab7e3478fc1a61f94b6726d5c3120e2de4cd8ea7f5c5651f425d4435c1de0696babe95094397324711e4e7892e287fe8131f976f263c0ef209bd78a248b1c72813c963ebfd52162ea9a6065aa32b0a97bb33eb39e3bcca888e6f92afb8f3891317bba4fbaaa27f638bd7900801683ab6a4f66d0101246c1aede70ddd6367d255f21e86ee48734df39549501ecd4367f6b59e386a9a42874cf0db6af11c998d29a62392d1bcc40f2feaaff847aee8bce8a93af3f1c0280966f9836af3098c10260dc6db8372939d020e863919e228f0df85ac23f67a5cd84e7a564bfae74a307140e636f10681514383d0b270d03cdd969b5e2eb5fec36af874b1d7f387b7ba69daba036527474fcc803f823cb17734e8faa073cf470ce65e480bb137332422a55d3bbc72a148758ee0a222f8febe8f8d99c1051df894132dea5b0387b5753719253ff3dcf94b006f2c83e06b4fa3 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = 3be0bbfc2f5d6da14c29e7dddaf4630f902fe246117bce54b661dd248e43384da392dde67f42419def7b3a0307921d2a66372372bcf012a089c61930273dfbed0a8a70be4701c8c353cdd1a00de3fb19ff39bae0e1322caa5f5dfc881d608675f72f3b2b8d82473cff85725df5d14405e39b6d378b2b649bc3904dd47893200e -S = 632af5e0d55d9eb7d4230c6818d1a178df225d91919423df4168a3e1fe2142f1f26f00c5666dfe6817b2a27f3c2fe6546ca747d74467f85ac0b73b8e34639e8448e0a560b1bc3ec827819db0df2d22874106205f93dd0d903926ec0478a5361e7a9878c6974a8c095d1b5779d783823d4355ebe24762045229ea839d05a177ffabd39738488ff449111238397da1266eb97ce6e3c63c7cb9ab2950140ac4a94dd148520dd67527c48d086e20bb6e18a26fba04a81008e35e0cf04388eb4ae9a1193d4806bd2b771117dd2ee2f349b01805dc056e5f0f3ca4df9c15562d6e1c9fb611059136fa581125c383f6cdf2ca7f7bdfa6cc8d7a2aeb1e2ef7799941f2c6c8a34021be8c771ce3e37aaf31157f91c37ea9ee02e6ecd3001ec30bcd6a45258ec7761d967798402ad5976f22542e5604d58627fafba14bc5bf3145861eed0165484286a2bfa0e17a37710b3a17bf9090f3493c81ccac46078084dd2eb43456cbeac804224083b5a9bbac414a57332086b8e8b0881707d41d4089066e36469b0085da76c6fc16d2486b3f7fe31964f928d3d902c3d5598df2f72d1a2d5436779985bc9e7264d07448f792a7f394aa36c9534be9ca7f431e90729481d0397ad8e4db9f4a429f238f7e1cea5c03795d82beea3ccdec38ee4b727272a9eb520e943ef2a1ffb10cb9e8147e1ea0b1d3208810b891b37f9ed8722a93328468b9fbcd -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003021300906052b0e03021a05000414a42c6b6337793e971d69173bb994a17471dc3642efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA1 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = 25627026d11f380f939eac2156adb1bdc2e9c087bb318c782b5ae52f0224dc887b6d2870a0a5c8f81082eaa800f50c15805c61b5fff976f312a3157f71bb6ae84262646c9be95e0f4289ffeab7555ec6746c6ae973738a30f143805e72de93b405a8edc2c9d4427cb01cb29083b5f1f72682a5ca1e880f5850a2ee750b75a015 -S = 3c76bc9dfff017dbc6ce8cddfb1066ab8e669761c9a3ba229229eda74f05d7790c0993883aab90d16c2fc358a7117f8118c9147c69810f2fe1d7cd4220c5df5bc67ce3d2abbff139083bb6d6c48f6122f71b30f20e37e39f760f9c3b317bb26d6a14fd864d97d13c9a1dd7480c03727a6b6fb2b1b74340678a68c0efbcd36a39d42bc8dff44eb78d1ab4131b80eb4cbcbb6687f0cda506320882dcd70c1839c653a026179a0615175660fe557f45867fe6d883cb808db01ab41efcc0cd2137355fd2ebed412516c8003213a523068e47ed03e58f529af079a5f86bada203793808d0454e8170c666b2638c248df1e6b9a0cad05a94f9710d7912d833e3a474a58b450e10a22188444b18dce363b1bb3cfba548206fe448e84a608694f060e71bc17e50c1c777b6fe8f0d2f480f154b90ac5c6ec274a62d23d72a263cf0fe797c5a1b226d612c2007b502b42c9cebe5fe27b5e2b731852ab7db8eaa8fdc005072c96ed55284cc59985aad5528100062ee96c482e9539cc0b5a5e30954ab4a386beef0dae13c681ad8729a4b3dad39739892f2789f18c5b517ec2ccdb2b9d539ee51546783e633efe4d22363858090a0f501ce4acb8231e2515bb06f02ff6b42ffc62b30056f71ef4ab1952b614c32711bf8211f99a97bd3d3c5780142f3730e7763a476584efe9d8bb8839d27c405f52306f3d4db3168a094316c699e9190479e -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = d40724deeeb76472778ad98431d2e2061239d0178df747d81349e77cda1e2c9fdd1393d924a1ff9245955a182bc17fee16f25868e32243748eeebbbbf54a34e9de7346483c250e94ae0fd20b4984e3c39773c840df999846a7f5a8ec787c66f2e10f8554beaa5b1fbbde87841381d62b9ea468ca0ac50ef56846f738eb1e8c63 -S = 258f159cb8bb860c3c3db9d6b59a44600190f0076d1f2ac163b52081e01fe2e7423861ed9bb5df8b40d4d1354dd74219c71247bbdec4be0e90910f827da0565b6d13c5f60db49e0932220c1861dfb3f0b13a5fa74477aa329ab24913ca918ba7cd4e72fa532e044910f6a72cb525853f926b752adc76d39bbb9a265206c9820c3e331670103fb82a9a0071dcc48ccc1a650ea1c95341a48476af0a9b0e4286d96f0a976d3884ba97e5aa78909748947996f233ba02d6586a375dbaa81f3f00f880352f7e1842dad59733a40bd0c9393276c47b8baa99e8404b1f539d09cd6958007b297ac8c82f66fe2768fcf572766522a104d2de11435a19d2d1ad77221ed22d045a227f437752f3029f6cc55a99511f1febecbd45d529e216803b335cc206810d19804874760f66872c8575022f7eabfe437924b931d18e8156f33e6eac5d5f1540476359c130781a436b17f3bc23eac0f9fdc06e9123109bfba7d9a7eccbafe6ffa87f6c872d952e7fb3f6f2f73455d0f4f7fc63a744e7713219425e746d7d2f9564c4cd1a6301cdd78b0945debc122d85adb52b3cce920b22e77f0c835a87da3a2c9ec3c0938551f76f229b7c734242c6b78eb7ede1424368834e94d9f7df0070dd4d5c7503b5b023508483c4977b0a69e4183e83b88fcd924df78387b916ba475d9cc922deabef2dd07a3920870ef1a8105d6a6aaafb3210a7b1848b81 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff44302d300d06096086480165030402040500041c560c52ba7c3dc1e996063b94d4238054241198d156f307d890406f06 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = 662e6fd267dd8f2e5f0fe89034e4b0a6e8241a256dc8cd6bbbbd966421e459aad85d4ef0de0569a0013d1ac33aee37223dca37aa4ed4a0155622c2c736e1a6f65b9b420e93b5ee541f3c1cc909e14351b8411c14c16a1125009bf362e84ceb9b176eb3f62df40591df92546a47c5bb7c7e13332b6d9408e2e0b18efbdc2c10df -S = 76070d1cc628d84353c5535dfd3dc19573a91911217d3f9382de19b3d51f3f5607c7f88d82bdca4871b5361f39b8316b45a9bdb3775a69714bdaaded31dedd9716a8ae202c0237732b935c469ba22adb7dd67f67f5717787a6bc33e303af0f341cf202f8696c72f54772bd619c7929afb2785912701e91d96f9005942e6d11fbd757239a5cafbc93ca098c5632424f7b930e69457cc8810cc9ac3b5a1d1e17009ee45887a632cab31c9d9dab6e843481a09e5a7ca77be9d3d5b0d668689bdb82e4e2e43310fbddd5774d482b43cfc1499196ca521fc58bed44971eb15d216ee55b125ea8f65439425dfe1007d0be5418113484e1ee9b1fe3ab25625ac624eecbd03ff9e1b7dc66503afb625ff659917635098442af02696feb0b2d9559c19505cfde72470d34dd1719655874c8d4c23a94d5f91da9aedfc38e96e271ecbeaf924d7a9313cdcf6f485cfb1f3107c3ce8e0fa06a326ed75732738d52a094e9babf6e14f3f67ed48a09797020c9ad48a31aebcf4fe0e0b4d1c128a0f90f2bfdd520c566559747802367e95d45cc8202a479fead34c90c4663f313f3db337cc244a85eb595a904ac9c8c213fa6e762a251a4b84e733b7990aaa92a358ef369732f2224b5d37692f48f8cf6589034755347eff0c34725236d3d55ec27ae919e6d255025e4d2636b6c07807c66751942d9362143de6133a90f3d3503d9b50f91d549a7 -SaltVal = 00 -EM with hash moved = 0001ffffffffff00302d300d06096086480165030402040500041c58df3479e243f7dbe552ec444cc92a91f478808b02c5c6b5c28d44d0efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = c65baead3c9c432956e7da3ecd9f9b81b220c054b3f6f9b79a4e0f6116a9c810bed80c1d5324455345cd0c0179b6014e4a5efacdce1261515a61d70348d11db1f7d0356914edc4471848bb8b124736eea78ba5375723290902ff41ffaaa7a5fb7a2d72ba075f88acd742300320bc030ad19107b9d6911a86980f947dc4942893 -S = 6676debdc5c1d257b6bf532f1f61981e769e3bf0676b5050a8dbc65ed78ed3b88c687d0213ab1c0ad73b8606e2e2e9ffe7ee8f9b20a532a3fd59945b9f371d13807e36da1aed420d4390c26980cf70465e3dedc22368b09117e4606257677132a7c92e73c0633718290535915c512d629bd3db35306f264c5681e4b48e3f5e63f46289e41d74ab29a099c637132d2b8a04bf7649e4fbb0a6b3f37873d2c001d7833c9bb1f4de8043858223dd005ef43c6ea6e0806d2958ead96fa89af9119b2ac16b6302e9f23c5a2d79a2d6c4bf5b576ab07de117857ad4766606e52de3b1cfd368746425c74154cd814e63ee05d419c9f05038683970019b24961de26f0312203358cf5a69fc3a8c34376774d93a07e8ee8cb4e49d3c8061cd988ea9a96973b07dc8a8b96db165a0f287df5a538304a9b05e2ee294c155e17bef1df251297213904b56fbd3770d6587e0f610b291d0be288bd744315aebacdd71d00316f9d169d542108747a10aa65c36398eee21d7c580d088871e9c7be4b590f78b8f315f92e6970ba9fb9f929af324d02a281972cf2841155de6a76b54c1316c818f9c21c52eb8ad063b53aab1b22e72054ecfcd833efbd3d0da69c3730e81d48f54cd9c22da891fc589b3b61b5a226bf54d401e576f2ce86c9b651cba2d93d63e2e3181a97baa20a15f6e584dc30e1dfcf1a3d2b69803eb84d3ed4f1e153b76f14def51 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = 953446b04306756e65d0cd8bdc3960a0713b59fdc73c90ea8d7b5b33f8aea6e371ea464f8bc28a5637b313e83bc0e6c5e059c087eb81aae3cf30cc2c21f686184ce2bdc786a2730103eb9bc0681c2bee821e726f388eac62be1ed4a40c38b9968fe554211eee59f72f410c1b4b9556a3bf5118bd95aabff0c20c19a4a1bc67e5 -S = 179296ecacedd93047d4442e8dd5a0de7e2799f45ceaf381cde74f3dfb96d5afaac92bae3df1a572c24757eb2cf91b970cd038278623d6cda864d2db12a763b94198dcb47e6041100ad6308403ad35859d19ff3608dd6dda433c4a30f53dae2d615e612cdb0c0fd4543243b02e873a3ad6a7315b0144a9c1ecd18c446781d7a8cfea621f646a219d6d108b5679520158c3d51287425cc920e65c94eeb01f9b92bb16d167e60906e30e9d2dc8a3fb8d509bfc406994e3d0a39e27d13b3ed5015c61c624e1f3425793c6b0a96a4982997715163ea2ffbcf38680edc6f03a9981d0283053bb3b84061e5c5ec886ff6cbed8041980a49af1ab383f349ea01be6bb0fac45be52a853770e9b0e8f1ddf69a18edbd858eed11c0c8739379de177074aab7c9e20d1783ee7dc46c186eb3966abd35ab08df3574db45b674858b3baddac03fa27d818eac14d3edf5f53852a6e42b052aca9b1ec392d70d53ed10af5b8b5e0df1a6318c558ca47740dee0e5293319a398f01e92743a425a8d4940b65bd16ad266c0db2eb5d53dc3532c98edbad8faf955d65811003a2d887374218bc4504b82b710dc828d838638ff3e8a25cc898c8d210626388132b9e023900d4867350c72ae8c3bd6f0c4d2732294403c1b6b2ef03670e44b2e33e05c5a00299e070a237186b85271a196908609a996cb386d20e285ed3446bd0f03a184aa47998625cc5 -SaltVal = 00 -Result = P - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = 4a51133aae088367ed396b7e7c5115f017ee32fc10e9cbd2e8947af91c40d9ee41033b0e53b89ab54b46d1a8ef260bb0ee1f7c882c544ff95b81df44cb8229c0831582c490e085c79db650c6c416f0e7a4f4195bb4bc1a88d695116830e35b2c370f4f260c8a2ce50c0f4fa2a329aadb60f6713d4f2a16c78356782df26b587a -S = 0eb8a7a48915663d4feb5c00c37b1862c248e9305c2644f40b32654b1899e0469554dee6495c6142588d25c7b04d9e498422902307bb8a861ffe02bd3e15eb521241f69afc928325c85508e698dfb5f2ecbdb555829a6c0a1ed7f97a711ade294107101bcae30d469734e7344ab29b03d7bcfb364d219d3d984c1f5915bee9fb6e2255cdcb0e8500bf69d9c8751dacad6e966438eddbe6325141fbdddb4d9c45554e467df872a0dcf5fe9e12b7bf610117bd0662cf2d97c33988c2244283dbd3cf8657c69a94bc48ccb22fff87308eebf175874dca3d5baad98adcfcad551b8f397f76a96f02f398f7e1a5c5d49ad6490d2476b03eca81e806089b5f88c368cc63421f20f54e6b3eff6c020fb3f7a6df34c2592dfa3f45327541ebfdc7f6f37e6ae0609fdd6aae6add86b9a793023bcb0bdcdb051e17ff51ccfde476a87c04a5b2f5ce11e014360dd9547996dffa7c075f7eb4d2d779443ba313af95670a33ecf0db05c7fea3760e53d08707441d7ce6f068d45c746d047ce7fca96106b100d704363bcf82e0b384f789284b8e472581a52004a7632fb6c8d4bce4e325a321d0ed7873aa62b9098c73ba4cd185a5ad2e99850c57167dc75561d630fa9e9b2094c2f327f6f3d097121be3d1444d941002861feddc38ddde941a223d9f525bf5acfe4e5ca39bf39e5f37b5db29bae077d451198f1e0d99fc93185c2810f602cd1d -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA224 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = d9b8ac36d3fe6d7e9c008affd1752d4b928c1f1787dae8da249738972b0b85f67243f69ae60880afd0124fc2577867d6466b8bb410245d82121bc897177a9b8e21d17699670bea189aa1dc6b6c0d2a04538292c08adacf775ad004d2976f5e5c6dcaf5dc5deef4e38215faa1191cc0fc4037fbe4fee484e0841db6edb2d21789 -S = 14ba242af3387b7b0489a0012f787986254b084dfb24cd31d7aa143756886345462f6d98ee33e8477cf0606c60c99b585b52dd301975f7400e73d5cbdf7d91ddc5b7262b615d39f2d0ae48bd5695a61630b082ec78cde6d91dc4b3fd518c413bea61a966b1d5b316cd3878a91d80a64d52f5ef24da2378c43e528b4b912d823bce8987a9b908ac884fba7a03a2129996a60859761d8498e5b9e0c9afd9aaa901c8abfcd80a940ddd9731351deb918cc6177ce0c12cbb27695487e9de6fa23203dad7137e9eadc5259a3c850530c2283e1178c0b2395eedf183c3cf78ea4f3c20b3e80017f669ffc97649f439bd6476ab484b04e0de8e96b596b1994b6a99d732e54886daf9ec82d22e2bccab9ca64db92e1299302eeb031c667aebb0509f6a39e22f2bae56e7cbc06c9a1ab76c16ce0fe5ad92155b330f31830a1df7af51f1178e8aece7bf595152b2530199193eae8c4586af91eb1f713c45b08a87b75d825dee919881ccd9a6448dd2bd0767fadb16415c305825d7db8e01d89ca97821f0293acfb1e85b08d83349f37e99131d3766636d6c7f61afc77c059035cc090e95e987687f3d764264d2c82c1ae4c4766365977365f30b26ba23755dcb6b1545433284a4129dc39625156057f23c44103ba0f02706b16f630ccea0fe204d43d9ef162f0bf17fbf83a10816b66365cfd5b9c4aaa08ec8e1260540e9fdc19fcfd2dd91 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = 9b1f5c7d045d72035019a18dac59247ac99cd251dfc74557f2623b6054043ce56b0c7e57b49205b3089e0e571e97ae1452feb784a45cdb9d04781487cdce43ab8f3d170d110030db96df844660a6029073d776669b9cad71b0ffd928195d36e88f18ee46238d3ba48346cb0279706817b48fd8a0cb7002f97f5f53ea419b60c3 -S = 3a9992cd8247ecf8ee650608b4520bbab5fa1774b8381c702930216b0dc6b9040b0dcae567c552ff5870a438d478c805edb56f396e9dfa422464b9559091aa231cc83ba676029936c204e58e473d93a8bb598135463614df6a54dc050f8db86bcfbc942979c3f011b8db0cea0b6bb0695ea1fb8c2f5872e4d89d9ae066b62b062156bba2ccf2be26ee1dce469219f387ec865f16d5b6babde6d0eca2efe1c9a51ec9f1f44a3cefe4eb054d33b80cf945c8bf530b9f8f924952d02fa75c410f3a57dbc2307f03a2cb9455f8a02e1b36b75f0f64087dcae1e639cd360da5d6a7394dcb7c1baeb4b323783cd3fbd207d8faaa5cc3b93867be4d47d934260129f0e51fd1dfb78b3c7c59f02b71be439722ed22654db5c1dc24b83785490ced8d0b97e11f85ee42f95582802446a38d812d59efbc6012a5dadf162aa0979a5de4fb7e4a19b4531c1b11231cb509f3dc05c74d90a1e2a8d9e6168da9fd226d5e53e0cd5ef93fc7ed638287207932f2b1451bab5c4bcabedf244585fa27e1a526cd9c7535768078c2b447cb30b6687d373295d6983ffa31083fd5230eb3574c4b65cb4bce0059d8e77e240d6be41f63fe98e94e76ea9969d8874f92c971a98d184ad6f78c33d5a1051a33b99c2d481ca3c06372f639d78e9601c20f93368ce8a1830d0c5b67aced9f2af6d3e8770321b209e271645e6909e251d31be1156d99f1204ab3 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = 82f869cafa1e8bec3d9891bf59cf8f15a0581b41f223afe13ff64efb471a6a4ca45506dc0b1818d6cff83197a6625f05b08b5322b5a7bfe1af5b02388874077624d96ad7a2bedd55df1bcbc23c5d3b14a25bf600c38beccaa276d45b55691394096edfe2487aa41277e8a667a326e9ea7daf4e02a239fe44202f0b8c3661554d -S = 94d64e8a8f8ff9fb1fc76207b8be1a45f76f09bd0287baec04cc53e08639542dbaeeeaff537b0de30d63ffd961080d3b94708d60b364990c6db0c8ad673e6670f2c476ad7d7a957bf3c46e09fcca93812daf509ed7b88b182ce6f8315ec4787da0b4a0a09f6f48f2cd4a2cb3257abbb1b5c921a0db8c9de8bc64b98f4c347e27d5d063e232e4cfbaae6cb78effedf18ee5f7af1765cb95a3a8db21cf94166de19a0180f7c152f6b25ea2a68703d5d4443c27523baaa08cbedd2e489b0235f2203165f13169e7df9d930fbd7556fd594571a38f4eeb5b428694ac5b9858d233cc2bfe0d21e2fd6f599479024369b7f102b1624ba4160c48028017aae2fa815f7fa439b1545dec9b9e372f7cd8323c8bbf7e182b064deef2b65731d18d2241899f4f573fd9421a4b9a809e9876188db404cb262485761fd9bb315fd69db37601da5805e8e3fa7a64f654a11259c0764b28e53bffcf03d71683ece0fb9571aac451c085c1190353ed1c7a07bc03bd4abd0ce68c6a848a17720dcbb03231e1f505f1a6275d422dd89de55c0d70ada23f5240626c42e64bf33b668c69b6aad7b16534bb10d1aef16ee155df6b0ed2d3768e48171c62838a84c982713aaa5e982370fe10625687a5a960bfb205f85531dc093ba443abf4d22abf519b7db2afc36bae0c10283a551e5aa41c942c9a28fe199522da96b4bc2d640453c6bb495c258578fe -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443031300d060960864801650304020105000420b2b9f428aca658a676034a1382b07d422f560f637c9fd49e258e742e065a852c -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = ee7d5046460f07173172b1dfc3382667b6080522b99da7580a115183475caefa82187ccc938785efb2d6d19a45a31aeff6be80dd092c7e45ec721d5b10106750f84b1f2e902faf03bfd562413fe2d365ad50a6d7dc7175116f300d04a79bdbb7799ea132e4116d9a81f6cc9d5cfb3b110247ded7db727506bad58b45b305f079 -S = 0642e1315d86676ff3f00490d4a2b8285333c7f7a14a152543d85a9f15fb2d54d60519d1896697b1ca9469c382469725455a7124191bc438b3566ed434bf318097e396c049aba9fc85a293ed4187d16bffeef55229cb52b950b504621cf13d683ccd6a0fb53e00d358551a8989c7afc09e34ec90f8286e7413de3decad04496b5a749a081c0e82ff71f6838780808270d72265e9abcf87f0e1f4439f0f7b3ab95729d4041a502573f94aa8fb1989dde4c2287335818f0fd03a72b4e6811249f665b0d05acff32069d80f570782f568bc851c434d82cc94fa168b6f2619a57a97284789bc41d9bbb29749bbbc3470c774079af80eba8287a2d53f4e14df1e619cc8b5e7709d5c54cd4b0cdcc8693c3d04b460c382531e749638736226a9ac2605f82eca3e3df3dae4f2e7cc70e0d39fd2772f193a4df10a25b58bfbc5497a0ee98e8f60cccedb1152741e52e53bbf3ec1a23bfa44b73753c60d69c1615c58739f2f093fbfd6c9ab25799cdd9e8b65bcac94af0ebab3f66780c3fdb486cb20427db12a97fd0257f1b7c956733304c4d30e3faa78c27bba260d697be1ef36eaae6c87d49f36112d7964ed7683fa47597fe58b212f19f4cc1d88805cad324fdf4ee05687421e827266d452a851401cc02c4af7a61fb1bd40f772bc1cca4e5955710f2e9ea23bec04ed7e3054fe8f1170c70935ee22384a43e82e1e855be59d428f8f -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = 27331a2203df81efd7f4d19278bcbd4050c32f8fb6df3a93786e5147b6dfb62ff774343c764511f0bd893fc27511d2c47d15b7833933a22f2db548fcca13cfc787b882fd3409cab98ba4592c09e5a942fcafa582dc69a637de46a0cdc7ca9e7dfe8a6b2de63392916acd8997da412a02f519625447882df2b5aac283560c0a99 -S = 4bd55acc43b26d2e69cdee990682e40580642fcaa9c0057c2f3c6e3cff14234f8e7304ef16cd79ef50c6e52ea8b02a46915ec21371556d217da4f3820eff0dfbc1a3dfe8bb43756e2e829d4bb240742e604e1d6b1e3dcaf69f346839e0351cad7b10c165f34603864c47e6a01420e677a421352f4a20a18814b1fc0db029825ba182732ae1480cb1e18fd1ecfc6d0fb6b6bb32944580aad72dc7e9f0f9dd41c114f8a5e77a1a07da0b51ea830a5877ba964460d45ac122829976d459dd7e49b74130c201d413ac78525f75463f69bd2c9da63c848be84a240368b7dc004e4c26273e5ee4a0bbe2903bb59cc2200fafd222fa59a5cbce12ce1a375ad512284043aa4d44abf3846d9d21b3a27c28b03d5cac655f91fd17a9d0a15f450db44a09aee6deb337ff3837bd85045c2f716ea147f098ec2560655492427291a1619404c77985c860643e85e01a767a8367ea387f930686becd9cf51e6da3a5183ac306d30b42d7b41646355f77192939af92a248d9243144d6ed0c440c60e656d535d5e656d8d22df272daeb01336ed4f57f5dee8f8514d7a100e996ce32d06c1bdcfa8d490a53d0f4329052491e5f3173f0430f07f18869f866f8403a389b2be6b68efb44dcad6537a2e305500acda845b5f50e91433ad84a094c12c0a38682bdc3a54fd3f6b322cc72fbd2ec805748f7e82ee3e5fc4603140e3b0813cf81e1861fb2e4 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = c8ef4787dbd28656118a8cf26f182c77f48ffab67b6b522be3239c306c02cf6f6432349d041a6d6695eab5a3d67369d3a23dc8c9ced3f7a2516247faa782bb607754c50673cd51bd7f5104211684c611ea5d7e63cb7c1cd5cabddd469e0dca26477c832bf1943a451ae902d5f7f24a1a1417a4eb3c0bccac985ce57b1a4905aa -S = 578c8c3166a0199da16eb3f93eebe5d2bfc3ee668432bcd26d8c87ab349137f5392f60b66578eaaf47c3fc7ed0101ee650b51fd522f8d06474345eaa73e253f8b1c133a9a874c6234381ba4b8dc0494d1ff5d65167b0c46adb12538cfbc75ce1042e4d69cfaa4ef5083c08f91f03b295e0433597e0aea94dc596fd015b4770db71592b9f41e3b587313148a4a2784f1bde2755034bd99b15ae982e0e4ad4c9dc8f8d8ab06d692251520c813b540f5b514f88827ab94b879cf61bfbadff5277239079b90d023826f2a8f330c37bb3279d0ebf0659196cedbd91a347e8e0235a009d7f39fdad4faaffca75f6343fea2ec8c588776b64ec1371c90046ba5b6bb148a75c7748e11649442a77ed80e76a23b1c761b9e3636e3147ac6fe408fede1f4c7c7b8ca651abbbbd20d131218e2e43bcd2252b1b180678d9196c6067a0473c8c73f0610973807746b44c2bde619a5e4f4cb3371e260c47eaf31e935c025b523c39b659098369fff0215e17edda2985247c90b3d84676110e1344d538aa34dced5f97c71921406adca7bc1ec54ca66c43b7321497a71310f70184aa3691451f5207f455ad947e33c9f22f7a96fdc970c325a286848413fb092271a295bc0de317c0b76a2617fb0fdf2c792bcce16b9c3f5c4f03dddd7ca4b1adaa6f4dee058b1b3a2326086e5140ad8618c0c7517b148f1054b897548f881961d54bcea391f7a8 -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003031300d06096086480165030402010500042077cab6a7538318a9ab5fb2c9399130c8fdd3064629374b4a49b2b88bee0e6463efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA256 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = 5d5e9a1c2ab1b7c859c7cdbb21caf3fe77ace0bfdfb05af6832df249828fef2c8a9e884ca903562e60070813fa9f59201ba63fbb9c6965389668dcb5bd5b0e42f074f3460ee4871e0aa07b0642652a3d0cf9d06492b5f627e14031203c9d0cf8b66843d0005c32df7f198c5ca124509e7230f9826a9cf60d893c5952a75cd396 -S = 5b460ece8562655899aa4ffa98650e7043766b0b2735662ceaf6958df776efbb60c92330790a57cc26093db03f6dd9a02f0046de5f71397d496ffe41d70f4a0b2e98c0c080dbb546726cc4808e70cdb31d84c23c021c45b617c7778d102bad94ba0f98980211eff7ccdd43ea61c17d08f9e319bf6b36b56ca3dcd8b12a240d81cee2b7a7eb234dc822f610e2bc712eb1d9562d826f8fa902107487949fba4538ddbf5d41d161c55fb3fedd6d2c6f90ec177d672e136f1352f4d07d5c21f0173928292e310fbf40ea6d9e974ee5db68501069310b6255e0a541bcb335934e15f6e504807884cd46c91efa9e224f8402fcaef986da5f159a35a40ea221afcb9e00aaf968cacb7d720c2aa1c5025cbd2ae9e3857e857e9bb82981e43f3f197c1286ca0819a7caff78e3621807f2682fa10a49e7091419d99ff0f42ccd22c5b455ca8214117aaad92e46cfd8598dbb533b38d8a4d5f8cafe6caab99468a7bf540f5a7f15414c76b5b404a6cb855af8ad7d62c60959e489a40ded9898a3ee04fdd3de2f8ef95a207b226daa9e4ddcc688e7636fbaeddafc0282f5924f7ffca4f9cdd8115bb17c36ac2b8804c3afaccc1ed4057b97b59d01705cbeea65cac20c6623cdd66cccede7f1db9d98d567e5c48116159b8113f8247a879e0990c2a3ac8c817bf6c98902f8b497621a53ddbccb07d01b7f8694a45ee68d2d04a33cb3535db2e6 -SaltVal = 00 -Result = P - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = 0a5d9e0c5ffd0d0eab672509388aa606fb5063e26d23aef59ab011f274eb3f0e6e5349654677159922b90dbcdf521470a696be4cc079c082ab53a5bf6de0c353288b6e92efec6b7ad88fa79652f72921b9e2466f28cf14898fbe2118053764845f8d735c0164f7f9f4715d5e3981cf635dbd63134e2c92526d79ebc3e4f708e8 -S = 31af3922e01de9d2ad34e11b89c1ec21ad76c2913375137206c779459c2db5fa9f180c1a061393f1106c7bd7c0c19e316f37f47f462e1fd870d05332ebaa582579f15e48729e5f8380c947f563244d08aa2104570334c60fa0a01a9f0bf9aae07e2e7c3e5de6acc71f8b3aabb9fe6036674d8eefee4fe7c0e5d3d9323e3fa92931c1a19689e53f4fa53381c4b73f8d91577ca7ce8128b88e8340b63f2e89a4618138c68ee53fb05ca95c94ecfc2526eebc9a38930c12c6f4416db316c507dbee0fe64a3bc66041aaf95f67d9a0294d97b4a4579e0f946fbf7309f042307fd3611f5ff2aab4a738410b62327d2b57cbfd05c5af3e6d61c794732fdf160e61b8bc6a4d3511668d2340bf6d2d1d46bd960e9be045d83bb71a93f1d9f72c67d8e318dc9c78da55758b660e2b1feb7ced2e8ff0a4a29e5febcb40078c92b8019db63551ab866959732aeba71a94df7c35d753e5a831da820d45f09a530176ed964387dda6e7e047302428583c16ace2f4a90f86539c756c0b7baf80a1475851920107fb9f742db3086067fa0c8a6a326f14ba69f8dee961e5cd7407dd5e6d74e81730492d03f825cceb96f2261f2d6b3bb48df1ccc07b9830df23aa26aac452d99d61bab38735b9daae68caa8a36ac7b57e01d181e6ad3321851bf42cfe627c0e2526af37abe7a8f454d754adbd24fccae6778547651d281354e2b167a21cb2e58a86 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = c265cc1668d494b6dbbf477f187eed2a862a49392b00b180200a1de342fc7d612b5c505261e572eccc2e350c6e87b4344e2364cfb57decbd9df4370b67b8c702ccea4c6416ff75f2906606313b6a2b6ec2590b00b0e6a1cde1ccc71036b494598d59e8d5f1ea45cf0db0e177e7f0f9e2cb136753840477b9d3daf77819b78d6c -S = 7b6e5c6672b76a49b637135878e9738da6b1ad1710a1f8c557c5de7c3a5364d4927f3497d6b7daedb931a65e3433dbfde8791af39c97e90437155a3eb3fc96c37d2b0a51126faee5706b0b73c63413f9082d6f0a3d2ad7fcc69e935c016a4abbb2295135bcef8c078e11e262c0c1038f4311926823cb1b148dd8e63942a927e806a84260e51341ff99eb02fa053dc9258b4113da1d76d0734f81234a51a196139171a90c60c9a6f6baadd3e3b99769bd1890984b3e434f94e9f27c7086d86ee86d45ddbd7130bde845b6c47b6dca29edcd6f7898a42e499555700683732feb4c2e200c0fb1e11c0f314682ead943aca08e276eacc1d67e02018690d159a7d50561bec7087c5e21b32bcf2b27c0245f410df9c137696f014befa4a0c13fe7302b44393bfe6e3747cd88ec2dff0c639bbca4e7ecb77f7989a35c2acdb6a9dbb70092a9b7f4f4c8c8d9f7286d9666b24393c95e2cc256c03645944fc7b194a73be5a6acca491c0a98e551aadf5b002a1c42d57149f6788697eda81d1735a85442b6b313ba798c92ec0464a4f02ec3cd5059694428e0961c93e75155d1e5f965e5956a82d7f9ebc51fae9ed151710768ff1c172ae2b68c81da2190575a35cbb5f9eb52f56ba5f838d05d40c35b9fe901a75d5d96e09b85841d68d055bca786514fc6249b136a22870379dbd54576a91b646406ed12445521b67c694e94626ed15f09 -SaltVal = 00 -EM with hash moved = 0001ffffffffff003041300d060960864801650304020205000430c0d206b5a6126ec9a86519315cb38f2484d00f36f2065d3a0dfe6f34657ad926ff281b90d8187ae2c2eb45c68643c352efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = f1fb8e6cfdfc5dd3931e8fb5c92b974650224e935787f170acfe69b22418d09f3e6d30a303eb8e45306d2758978ff976c3c185aadb9bd46dc871b8d49a2654072845def5f74da4465e4d4d91e7b162d0f75c0d11b2f7206e1988583e7546e48df9ac21caa3cca8c063e68ac87f39da3c36196c2ea442dd5ae56cd35a7d1f8619 -S = 2c0ce9b108db78aebb905e421bd0a993b38d9e6b66bba9cf5a9ad72fea11f0ea2a8eec30e7947fbd552c63535f2097e4d6ccf07024e833967a119abb869327d880ca2c21c3f32dd559eb8fb6090107832aa884eea6c9284231a6869013cb0654b3cf17cc87b39a9b7612e2c91f77ccbc1736d1c7e5816694632fed14bb764c4c4f5f80193b6fb9247026a3e754805f00cb8a73b62f01b6ca9206890aa3008e63a2ca87a0eb54affe1e94f2a676060921620ef8bfc8563abfc9006b8ed0f7c71cb8a987daa6d96c0b819e4d1cf279417998e8d9f7f4334186923a10d3ea888e0b8d8699494c9e5a0468345f1a93a79b436b864a4f84c74f77d95ac7095156d96d4b83000177cc33c8ff9f555bf5afd2968708eee4b10a397ab76c3ff22766caf8d3836b5d5fa7a580bceb6245063bfa74fa9d79cf2c61b8ab92a92ffd93eabeae820ddd5f4c94301bd7210b18142126267a1b2ef3f8725110ad570a7d46ef5a18fd32b031ebf23d0c4f56e134f76b667217d486845f93e965bca006934ef68d5e11f8edb1adcffaaa51b5b0f42959473c53348709ffea3963436dd7794aadee13aa24e1872152b9bbd031e71700a8924556b703c7be70d33e523d9ddddacf0641756468872c7ad17b71208c78fa993561d54aa6255b6abc5d1b9ea7c58f28554a76acc9f662e186a1aff26e6f7ce8c9ac20fb64cadfec72a08ece04b51bda01a7 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = 879645d6b8014a368de5b3f59c0f6d61d05150fd6978461c447db0af5d00055c92f1bcd0aa916d55959933a7f5b85403de432482da2926a5312575316737623d05545f899d5d1c11084eefe2f2b8792d9971879ad18936de4c815b9018b821386926f4aa994c9e926d6bb04f9af52405874140ed5582bef01dfa2975786b8a77 -S = 2287114cfb12bbdf370c453bb39e68bea8c24afa1db85239b54f7ced68798dce71ccc3a283859cb67717b7d0299f28238cf05c9016e867203afc345498a98cc933165d1d2103263f0556ad6b89a408227b3d68909f1c31460f818da5a389033004e5d89909661995a6c98fa3a59a56869cefe67d06a7e5580e288a1d69eeffb1aed49e77adfa674123690d42f83411d807ee7fd5a2b21c055ebf9d393733c1fe96d9a9678814fbed5cf5478a54edb8e432524d0c05022a5b477c4fe901ae8b4a8e8d00b1519075fe5e160eb5b1c090a7b1deb970c7f900dd47c47bebcb3fb5334be683dadaf023660d0d82ac0de747f0982cc31428ebcabb03ab4eb46750331fa88db48c15b40dd18a83dce93e7e769db6dd32cb99a78243233d509528b03825ddd5eaf2f29b68396e23293607e8bd5455c23843f63304d5d3865943434b61f471e2b3464f37fadd3d29dd104b36c9f6f859f4d84446364fb56af34e9eb15882519b072b890d682b254d6461f997e056b42452a2346ac6f0653845d456b20c3a273a7d421295ff91871fb525c7274471ecdfa93c9358067dd4911a3010b629d0c2b3a2db23af2a4510d6230522b170b61e804ebf561c7ecf45c5b741c37141ee407809901d557e2c8f88e7a719f2d3b5952928722e96311b9a1ba5106cd5ae9d8d101d583d321fd42c68cf4c28d944ab9433153831e3884556d485c927970f25 -SaltVal = 00 -Result = P - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = 92b5088f66c761117eefe5d57d490b0a2d8f735adaed7065f910c46f0e81aa55cc311ac67d5548afa4736ef7e1bdcb6d169febffc8942a2cc83d74bc12b44eaef51e1a72747f9658edd3a749f85a55b5923316cc7b2c4ff1dcd9186b2de3405e56a390fa14ef54f39f3418318ac5b0c8ea737b2aba5ee89c7e0b38e627b6864f -S = 50758bef01ca5623082d4fb6888e9c27598bdefd63abd5168c8a122d4bc26e45d50736136f9f28848b082f18ae69cc2c3cba98f3458cbe71167a6629ea604a606b7a10fba68edd1576367ef0551b1c0dac9ab830ba41d7c9825ddab0a4cf01c62669d3c7f434e18c6bba0c6b931f6317f66f0aa6694441bbb9cfb74220920d9d861a857cd984c0e35666eded9d6d67fead62231f2cef40fe4252d02aaa3b12418d26cb646128fa69e13c57f90a85a7606859f84da62feace94bfb607cbb8fce4c23006b1a3f0aa6724072ade5c1cc2c664556edb9d40ff63d0de44b35a68e81aea98e98d52883c4fe41cca6f1f09398251f28d30165f34b74b008af8742b93c8fb7586cef90efa60e0542f3f5f85dbee12b3008c834a13c587dbda2e570dd12149390fb7e8788b46502046e0e158c3aede9c789895af2508663d7d1b9ede251321800db59575bd7971bb9a93a2c0ad2ec377f0268e7b6eb404c0cc02055d0e69726176f39b8826b1bcf8f4df7a7ede44a5ebe2d862825d6b1c11e9a30ab838789bee11344aa1d88e8495792c68344fa889ee8c2dfa418b5fcd18ba7cce65018fb6ea8d00dee814084eac349f5a233f34b2921cc0f09b5f6b6aa4cdaf90196f14ea66dcc9ab1ccc4acc1ca2d097bff923252db6d19db50e877f6848e3a14dc8d799fd8a8722aa6e98b5b4e53225af9d2c40811c6967e525db1993ed1539fcecde -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443041300d060960864801650304020205000430d6b9bb354aa8acf8326afd721b8bbb21603ef5d2f897c52cc0f27f9169f5bb894168a77ee4a65079fd68e9b38a7a4ea9 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA384 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = 9a5592fd0be381aad74258865cab802a5f161df848a2e3a38e382af2706b45c0e6a31048d77bc99f8c672182659a9252ca27f25d6566495f8e99e04907cf9a40ea0987e9df9cb7e492d64c9665e4d32c62f3d5dc7396a86ed5688bfccaf2f3f68ecf1f688d0df280d3d7024bc451edbf0dc4ecfedafbaad94aed56931f9cf6e8 -S = 6b95909cfb0edba3177083097f74edac27b652bfd73575efac3db0971290bd7718b5a5491724c095a25c1a75b67a24a9e7caea4e2319637abe40efc0c5ce640a879978aac6ec898a4cce02b87cffb59f0c27c1c01759d7f698adf77003e033e70895e64a1f50f8cc471f61cb8e4c37a6a32e0875551b558314442fd7880c1fc74046b960f6fb4938ca6a7b1fc709cb046cb51c5fcf32c5d8e63324c88cd3ba6ff43406688771d1fd5ace55ccd8c90a96f403461f65c1cafd3068c4be660ccd740f34edcc1b4c57ee0e5ea5a3c2b9d76e583a9d1c70f480f508d589e72dfb0e5a6355bd70a2f90bddc1847d582d426f37b1060e475bfc62ca3133f4431407b948cbbf8ef4ec6488d773c5a840ffe2bf2cdd8a9aa753d0e66733daa5837f26eee99be7ac230fe0437898b6f9cf8e92419f0ee112d0475dfed75f8a8dfa4fe2f1e7d54da8fed8bd883f7326890f74a61beb22ad9822536bd3780f8a18573d16376f4f393e8e2305decfea889933b92d673569b4038d49547cde3c11e4f1331ded794c6fdb266c02048ce0be47b829e9be709ceaea89c3acfb12741332d147d8fe981b146955a29186f1b44f69ea276e78448d5752117eae565cfa54e6dda92387f330542dd30bb9426e1965a76a5a438f55ce22d252fd8e62df04c4e8c7a719385d4d56f37194f7e03368d17fe8165ed176d636b3b55fb99c483d707d160543561a -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = e0e52ff4aaaab424199c5cf2a172d1ebe64f7b6e2096fe19c400048161ec3c26c7f6a3a66fca0230173bb73cad8fb9796e1dd7074f1b40e79cb148b0df516983034b8840b99c7afa1b07c7a98f68ae1fef44693ee7a4b2679e2485359847286cdb0d692c50c8276b6d2b13a211a4b8c5afecb979afdc5a821182427a547480c9 -S = 8c61782fa17abd9424bd4df6333f775a1a36cb913fc3324d4a860c4619ab778ec699e88cbf7d55d8b9e7c9a4bf760ff1238c1b65f3d3afb50702c844706e855187ca2fbc92c18f5ac9558b8b719f7e985d791caf719721c66673026c393fd6fe4aaad8829188e5978ed401256ab8ece9d6713b55a0b8cce1c33b9dc333ed48d83bbbab4290471866d1d4d3e239daa5f315e18a19f78d7679ea1ba028032dfbca40ab0ac436f948a129c7d182911d0452548755a90dffa2294a4089c2a46352b1e76e06c203e230a0229989ddab4171deeef125af7ad0be3f28dd2d3cdaf25ef500d8d7134546bc79806ad7bc8dbdfd882f6924148b2480cffdd9d4ef0235385c76687fe669822ae14238736c4e8fa48d494ea578a6a940f07be7284274dbe9aabba9b6077d253eeaecd483f60763f8baee3d5e27a7c820c103160df87f875b10ffad7d810283fe118fd040b0e64b8b007aaa049a5ea739f85ad8245e0223f3bb3c66904bb89bb58eed61324ceb4b49b951de42d1ffff7ed9905050d05c73f34946562d5d39acf768f7be5292f20448bc5b61795fe077631587abc5465e67fff8118dbefda942bdbbe673eab46142f047d0359f112f64ba92eb54ee45b349bcb3befb89e31080d48303c90acafa4aa09466348b50f2923d29c1f9bf34dad7b3246653c7fd20f480b33ef3d9e116ddda73b7791f2fc5fc4c31bcac2bde5b79691f -SaltVal = 00 -Result = P - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = 2fd1aa7be544c3206a9d43464b3fcd90f3f8cf48d08ec099b59ba6fe7d9bdcfaf244120aed1695d8be32d1b1cd6f143982ab945d635fb48a7c76831c0460851a3d62b7209c30cd9c2abdbe3d2a5282a9fcde1a6f418dd23c409bc351896b9b34d7d3a1a63bbaf3d677e612d4a80fa14829386a64b33fa217c9b26e8453e4a6b2 -S = 560a204f8a24adc61ac4d3c8de48304d9c59f6faf1bf1059bf1edb7e786ad81d95d6e17acfc30d84a151ff5496507da3094b7464839443d5530e22d6316076fadb5ffa013319230b14115e0905a997f4019dad2abde8d415a2b040bc6413c172a620a878d3695f70ffceb14fbeeb4538bf3c9b905e5907cba8ed8fc4a6ef9eeb863c99251abfaa9c483198618f2858a0c2d04a3f7e1e51128c9309303e01182cbfa20ea398c02354247fb30d32e977e6ea2dcc97be8921149257d13e31dde63b4992b167dd87f53116114a6344a3913ee313b4361d9258a2b10e9cefb19d0455466574bd58c0f284f99362737d0ad83d3ed0d587084f4e677a6748d68c1e3fee364600905873bb10de67b02e0aca45273ddb2f667aa22e885231b2bede0b541b79d2adf5e251be56e43b2577bba5244838471ed6899871016372771f88ebde49a776bb11697f15e50d490be4e52f95868f01bbd8ca549a60c50f1e99ddfe399f76fea48567e6abc0a845ddac6e963964624e38e1fb56565f99f3cdd7ddb7aebc3c53c7d82c6e3eeb058d128b4bacaca5f5fc8b037818d34c732fd15aeb70b0d688a233b5f91b65ff1f68cfa6f3a55b144840a9979996dfcfdf84cd9b02d385a842b27121cbe645155521e2c53ba3f1747af5609950b0cc808f33402dbb94fd1128fe9b309850b9ef11e82ec0498d595ff6436aab76a4df49047d76e5342c14b1 -SaltVal = 00 -Result = F (1 - Message changed) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = 6ed981437f350723c4f1677f7bacdb78d12a22a19b3ed30646edf16d11d0bfdb79bad65af59b74fae4a41716c4ac4bd8a4d3c0ffdc659fe0fb011eab01fa53f0cffd4562dbf449da282b8c9f76b1ece4b6020c92c0e2a748488c24a00e0c6bb556eaf8e298082dcc78cdeda2f88366a3edfe2ee1b07f924515d82bd4a1d0b230 -S = 4684f8bc41880feaebaf54fc8cbb1d85c378db4bb916a7e162fa6683667b2f6df1e41e722f57e027486dd2c89ec035e2fe88ec082bbc105422b9116362bb00fac7f687297a858a08bea678d8489ce7cc27133c4f0acba0c7aee1daa55938ba2fc8957e6dca7493c0f054cc8a61d96b1d2689b1af69b491f58aeb6b3011827ad0d60bf1385402d4c7e7dac0f6f1259e7069a788816cce8db301639007ed1224bbdcbef9447df741cdb6a1f03796398372eb86ed8c995d281326a834688010becd7c737096de2573eb210035f14b937cf614cab6d1717711685e029b7b23d922bf2d6d63e354af5cf1b8609d021196e04a4e1baab203b1adce2b9c4bdf5a9a989157d2832867abc5173e5944ff070c9f7b06a14373fac3bfd76a73129e4cd0420c4696da9ef6f672f4cc9973434bcd2f0e351fe4509138d20a55bf73e42365da8d7ba3dd74b86055a785d346546de0f9837ecbcf52d6658e16e657b20428a8003a9b31d9f69e8206da1068fea98ea282a8731d96fe5e5be7d0b68c9eaf16090eea1f424e4cc5a509f8d6efb97f846d8ff1bd739288deeeecee6d0122eff6efbba9541ee1b2387f2092022df8584521d556bdc7ff9c8914d35a7b44075382fa3f03a3d4ec1ad11539cdf3b92eb37da08949c7ddbc2108e228c4548f41224b4da41098ae67a048be0fd22254a49186360bd0cea7877621130af6b8abfb490a108ab0 -SaltVal = 00 -Result = F (2 - Public Key e changed ) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = 3a33da20cfb3e3ac722e7df7865330b8f62a73d9119a1f21992e240f16197b0970775cb6bdd5b0a858f4c93e33ca51c86eca80ed2865924a95d1795c5009cfa0f3150ef8e68b03517456808324b6527846887291ccc880455b546c0ca2f2777beb955ab0efdcc4f0efdc0a8f001f1a10a7ecb28ea5c9cf5b143f67e6b3dd5ae2 -S = 2fd9e8beeb55cf3640f615951e25b1731e1c51b4a1a2f251ff2761c3de6393c00f1ee2876e103a38c3149eafb804efa687b953eaf86b270d6cef192869aacc206f2018067df43db0ad8de6687ecd0535ed299180521066553ae2e6ed21604193eac012986767e48aea294fa3769482bcd2c167723707284dbcc7849d8320220319f7087baae33e7d05cab1e1430d3b2ba0e9ec5c5620f097c13b5a5a7c286ec9061f1963d27aafd79e2a217da1cb99389a5335ceb7690db3ce5cac022a542c14be25cb3e090400653a46863f443bd40807c546916b8090098fc5416744aa8d167bbcd48d718f5fee47339ec5446bbcb53ff6270f761e57589c399b558a24da5a5b3121a4a296e1ee1e01395f20b967c6cfaf2dd92e6e9fbc7c866b910570808e8dc87b66a8d9518dd9829f71f6a5e7e544e86551d907fcf2da2f4707e19586c19598a063ec1bfb252d91449f22ca90f2f88bbc6266ede3c19912a2481f70795a0a6ab6c1644a9458f9dce7a6459587135f5e3f20944a00d0874ff3b748a12a81e54a33da1a65df5dd932dbd979c79116e7d1138d35abf18b2a82c364490975c118c194c102a7c0eae6c629ec8043f9c55b63e55eacb3b352250ef5fa489ace55ec6b0771711aefd26f35483dacabe89fd15e248f669b5b2c343ba9de80b523432b9a0e4b05486c0132c4e1608f49efd481aed7b6da2ddd78fd5bafefcef2f074 -SaltVal = 00 -EM with trailer wrong =0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff443051300d060960864801650304020305000440ece68078ae14353fad83f9da0bc52f954e4f83bdc06abda384df386e15c66759f7a78859e7627c41d5c146cb5f8a46a147f1bb3ce2fbccd6d7efaa3d098c0a64 -Result = F (5 - Format of the EM is incorrect - 00 on end of pad removed ) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = 244581a2b06130d1af01b83ab281dc252d97481cd92819575660a0781501637975fb65e22c3ea83fe9ccefd13812c884a578ca2124371cc5b06a37923369eca4a652a84679e8f76635a1474760faef76a10e6fff2467f9e0401431be57fb32d7fe71d1385e082530daa84704f3e256e46880be1ea161ba924d8418664b623dfb -S = 45b532bc216a9e6c0b58ef1e500e0cfc11cb85614faa4301e5c373acbb46f1fa655975b8fe4d50098f5b1ffff7e45db3e339b27b2d6d3349fa952922b876dd333c862bacf6cf4d3b1b98fca4adc2a4674b0397326ebad63a553f97cbf763d5549e982b999eaa77dfa074311d236936056a2f097385136ea5d82f76190e4a896bd5c2ef3580eb98340b136dae2215c3ec324ad44fa1920213fc6985faa58fab2a5ab4f1c268dc1489c4f257e54c573247a6e32640780f7345dcd7c371de12696a2fff5d94ab9677914d3d21fd0b436405b8122f410a3374ed67c8b414120a1c50c18b6a8acaff5bb68b2ced8036d30045378402e4cd193cfab277e9808045b30c65f947f39c4b3b25af8130a46d03fef6ab01c8d3a5807ff6a96628523fcd8447f24d11cbad36b5553f5d4c8051739a700d6113d48e3c28bee871fc00c46b013e887ba957ab45911f056d4b98c00b4e6b5b02b1d674918b90b40ca688e096ad0705d6f72e4999b0cbe9ed94cb297df6872e02fbd3ed2a8be758d4e6af7fa416b14d6785852b2a06d001e1b10e9829e3c6ad27bb2f1ce05104115decac07ff9c4e3cbb0bc0d264e9f27e9dcb48a9d8ce44b5e6cb37defc81e282071eb0ea06285c5afed12fa5b509a54449dbcd19431ad4522348ab0aed336c351709d3aa717d1e453362bc65d041af2fa7c1328231420741b433373e78d98f23940d6e59c132e7 -SaltVal = 00 -Result = F (3 - Signature changed ) - -SHAAlg = SHA512 -e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 -d = 09d77b3b07c31dacabcdf1e8078a1321cb08f1765488e71b320c0bb56cfc04868a0edf060a6a6f90691164844852546dff634167aa1b0fe81d69fba8fcebcdfbee9e781425b29af7c5df6156d71b1264b592d53efa8a7bfd4a0b2fc0ac1863904241d09ea376ecffdcf36cfac560c74b210c1c1886d4a6dfc94959f5190e8ea9082d85e7e8fd58bd374db170f86362ed0b4c2a2084ce93ba924a95e905b52e1a9c2215cc3d5d8de7d76a718080c3a15e71ddf60af46bd9ba62557a00e9ced85ba8f0751dad3f4e212957265c67de3eea774d7f7514d40a0814880b724bc1ed43de7e7f34334ab19f9e50dd5fac9403c6d14b0ea9e1663e63510c96419c10c134de0eb4ecf88918f782e272ececca42a6c04898a0c738eceea3319e81c0e6fb4236fdaaa191b196a7e8fc39e35a88d844b2c2f0929f029e49b03f1b65804ced3594c1304fe2ae987ab4d24a7faed4da097d58c94125884d095b59d26f2fd207e4dca58c54c0a74115d2f635a97e86e484ea8fe5a25a0dfb787fcefbe53f4dcc299ed23802b79ae2cd433227128eed0bd640bb5f51c93707379fd715c7a39b69c559fb8ff6d43eadb2eae2034d93c0c7f39b5e50044aa201d4d0c3036e4004201d558c4b87e31bfbd10654032808d9133200f8ca8e8206ea26fe2a3ef27005d2b245bb91c528fbe9a45687e94aaae83cbe25b452b3c26bc17c3efda7818f24201d -Msg = 24c8f1e99508bd234cf1161e94b439ac41e6392994d4ff685e178fee68688e5e13b501353c7458b76237ab2a0b80434163d75cdb271b29eec11619bdb55359523b349a282d3f142824b9cbd6df7611cde4ef4c696995f9c37465f1e242bdeb2fe66e432a3212fa5cdaa0fd8cd73daa360a55903922eb76d0bf2d9fc3d74c4ddf -S = 3941bb2afeacc1962b51ffecb000ed9406ba6e0935006203eac5aab1e35b980e6b3bbacf6d79f249e2c0fcd4259298d659870fbfa7e5c78d0e72aec15768e9e9d7353369ef2c91240645dfe40d85f68026bc4aff204798ad20cdf05a66640f6885ab633597636cd5af965ef1d2bdcc5dd0922f23e150ba67cdf148421d6ed43349b2ab426af2c9609eda45b980c842c2817513f8d0ec7c1b404fe07a7269088e359948fa05a6d63d3002f88ccd3167dc30242a42a07b17940a4f5763013800fefced30d42daef920e15d167e6bef092d440be42624e6f855ab7842a8871140dc17458f479933e082f1794a4c56cb338d31ca4f5bc6983dc2ec124e6785b16a0530b4c7e33488da83a184aff5448277a61c32cf6a8a4995a939552e0cad8d37da113b7806510577af56f9abfc7a37c566405be6d0b3271d8dd9071a0e83c51467f2fd3d22c805bc9ea025d1b1033a99235acb145729df2b6dcd761196c74b02f8aec2b53d19c20be6b3f7e46c21690737c675d46d240d6774278c0dc7db0a817b570cd493530d2acc0685bb1d51a81992ba45a3acbb690467fcd2524deef1b2efd643cac753d86a760c9428427a7b5cfe2624efdcca0f4c2c02ae67c3e3df01c4a19c3172377b425834c1c376366eab600693f63ece2d6ff94412f768a9dba4d202d70a9324f76b2f58295015164213c71d3bae7b90edd800ada1d972353f320c -SaltVal = 00 -EM with hash moved = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003051300d060960864801650304020305000440f8b77aee7f4480f3de4575717e774c7735f9d46cfbc3706fcc2cbfed078b75fa59223ba0cda570d5bdf5ba1bd9d087f37e36b22b65552b85cfcc01a7b30c7f78efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefef -Result = F (4 - Format of the EM is incorrect - hash moved to left ) diff --git a/lib/openzeppelin-contracts/test/utils/cryptography/SignatureChecker.test.js b/lib/openzeppelin-contracts/test/utils/cryptography/SignatureChecker.test.js deleted file mode 100644 index e6a0849..0000000 --- a/lib/openzeppelin-contracts/test/utils/cryptography/SignatureChecker.test.js +++ /dev/null @@ -1,61 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const TEST_MESSAGE = ethers.id('OpenZeppelin'); -const TEST_MESSAGE_HASH = ethers.hashMessage(TEST_MESSAGE); - -const WRONG_MESSAGE = ethers.id('Nope'); -const WRONG_MESSAGE_HASH = ethers.hashMessage(WRONG_MESSAGE); - -async function fixture() { - const [signer, other] = await ethers.getSigners(); - const mock = await ethers.deployContract('$SignatureChecker'); - const wallet = await ethers.deployContract('ERC1271WalletMock', [signer]); - const malicious = await ethers.deployContract('ERC1271MaliciousMock'); - const signature = await signer.signMessage(TEST_MESSAGE); - - return { signer, other, mock, wallet, malicious, signature }; -} - -describe('SignatureChecker (ERC1271)', function () { - before('deploying', async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('EOA account', function () { - it('with matching signer and signature', async function () { - expect(await this.mock.$isValidSignatureNow(this.signer, TEST_MESSAGE_HASH, this.signature)).to.be.true; - }); - - it('with invalid signer', async function () { - expect(await this.mock.$isValidSignatureNow(this.other, TEST_MESSAGE_HASH, this.signature)).to.be.false; - }); - - it('with invalid signature', async function () { - expect(await this.mock.$isValidSignatureNow(this.signer, WRONG_MESSAGE_HASH, this.signature)).to.be.false; - }); - }); - - describe('ERC1271 wallet', function () { - for (const fn of ['isValidERC1271SignatureNow', 'isValidSignatureNow']) { - describe(fn, function () { - it('with matching signer and signature', async function () { - expect(await this.mock.getFunction(`$${fn}`)(this.wallet, TEST_MESSAGE_HASH, this.signature)).to.be.true; - }); - - it('with invalid signer', async function () { - expect(await this.mock.getFunction(`$${fn}`)(this.mock, TEST_MESSAGE_HASH, this.signature)).to.be.false; - }); - - it('with invalid signature', async function () { - expect(await this.mock.getFunction(`$${fn}`)(this.wallet, WRONG_MESSAGE_HASH, this.signature)).to.be.false; - }); - - it('with malicious wallet', async function () { - expect(await this.mock.getFunction(`$${fn}`)(this.malicious, TEST_MESSAGE_HASH, this.signature)).to.be.false; - }); - }); - } - }); -}); diff --git a/lib/openzeppelin-contracts/test/utils/cryptography/ecdsa_secp256r1_sha256_p1363_test.json b/lib/openzeppelin-contracts/test/utils/cryptography/ecdsa_secp256r1_sha256_p1363_test.json deleted file mode 100644 index 9cd94cf..0000000 --- a/lib/openzeppelin-contracts/test/utils/cryptography/ecdsa_secp256r1_sha256_p1363_test.json +++ /dev/null @@ -1,3719 +0,0 @@ -{ - "algorithm" : "ECDSA", - "generatorVersion" : "0.8r12", - "numberOfTests" : 219, - "header" : [ - "Test vectors of type EcdsaVerify are meant for the verification", - "of IEEE P1363 encoded ECDSA signatures." - ], - "notes" : { - "EdgeCase" : "Edge case values such as r=1 and s=0 can lead to forgeries if the ECDSA implementation does not check boundaries and computes s^(-1)==0.", - "PointDuplication" : "Some implementations of ECDSA do not handle duplication and points at infinity correctly. This is a test vector that has been specially crafted to check for such an omission.", - "SigSize" : "The size of the signature should always be twice the number of bytes of the size of the order. But some libraries accept signatures with less bytes." - }, - "schema" : "ecdsa_p1363_verify_schema.json", - "testGroups" : [ - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "KSexBRK64-3c_kZ4KBKLrSkDJpkZ9whgacjE32xzKDg", - "y" : "x3h5ZOqsAOWSH7FJimD0YGdms9loUAFVjRqXTnNBUT4" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", - "wx" : "2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838", - "wy" : "00c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEKSexBRK64+3c/kZ4KBKLrSkDJpkZ\n9whgacjE32xzKDjHeHlk6qwA5ZIfsUmKYPRgZ2az2WhQAVWNGpdOc0FRPg==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 1, - "comment" : "signature malleability", - "msg" : "313233343030", - "sig" : "2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e184cd60b855d442f5b3c7b11eb6c4e0ae7525fe710fab9aa7c77a67f79e6fadd76", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 2, - "comment" : "Modified r or s, e.g. by adding or subtracting the order of the group", - "msg" : "313233343030", - "sig" : "012ba3a8bd6b94d5ed80a6d9d1190a436ebccc0833490686deac8635bcb9bf536900b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", - "result" : "invalid", - "flags" : [] - }, - { - "tcId" : 3, - "comment" : "Modified r or s, e.g. by adding or subtracting the order of the group", - "msg" : "313233343030", - "sig" : "d45c5740946b2a147f59262ee6f5bc90bd01ed280528b62b3aed5fc93f06f739b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", - "result" : "invalid", - "flags" : [] - }, - { - "tcId" : 4, - "comment" : "Modified r or s, e.g. by adding or subtracting the order of the group", - "msg" : "313233343030", - "sig" : "012ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1800b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", - "result" : "invalid", - "flags" : [] - }, - { - "tcId" : 5, - "comment" : "Modified r or s, e.g. by adding or subtracting the order of the group", - "msg" : "313233343030", - "sig" : "d45c5741946b2a137f59262ee6f5bc91001af27a5e1117a64733950642a3d1e8b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", - "result" : "invalid", - "flags" : [] - }, - { - "tcId" : 6, - "comment" : "Modified r or s, e.g. by adding or subtracting the order of the group", - "msg" : "313233343030", - "sig" : "002ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1801b329f478a2bbd0a6c384ee1493b1f518276e0e4a5375928d6fcd160c11cb6d2c", - "result" : "invalid", - "flags" : [] - }, - { - "tcId" : 7, - "comment" : "Modified r or s, e.g. by adding or subtracting the order of the group", - "msg" : "313233343030", - "sig" : "002ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1801b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", - "result" : "invalid", - "flags" : [] - }, - { - "tcId" : 8, - "comment" : "Modified r or s, e.g. by adding or subtracting the order of the group", - "msg" : "313233343030", - "sig" : "2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e184cd60b865d442f5a3c7b11eb6c4e0ae79578ec6353a20bf783ecb4b6ea97b825", - "result" : "invalid", - "flags" : [] - }, - { - "tcId" : 9, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 10, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 11, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "0000000000000000000000000000000000000000000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 12, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "0000000000000000000000000000000000000000000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 13, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "0000000000000000000000000000000000000000000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 14, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "0000000000000000000000000000000000000000000000000000000000000000ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 15, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "0000000000000000000000000000000000000000000000000000000000000000ffffffff00000001000000000000000000000001000000000000000000000000", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 16, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 17, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 18, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "0000000000000000000000000000000000000000000000000000000000000001ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 19, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "0000000000000000000000000000000000000000000000000000000000000001ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 20, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "0000000000000000000000000000000000000000000000000000000000000001ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 21, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "0000000000000000000000000000000000000000000000000000000000000001ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 22, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "0000000000000000000000000000000000000000000000000000000000000001ffffffff00000001000000000000000000000001000000000000000000000000", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 23, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325510000000000000000000000000000000000000000000000000000000000000000", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 24, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325510000000000000000000000000000000000000000000000000000000000000001", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 25, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 26, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 27, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 28, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 29, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff00000001000000000000000000000001000000000000000000000000", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 30, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325500000000000000000000000000000000000000000000000000000000000000000", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 31, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325500000000000000000000000000000000000000000000000000000000000000001", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 32, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 33, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 34, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 35, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 36, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff00000001000000000000000000000001000000000000000000000000", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 37, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325520000000000000000000000000000000000000000000000000000000000000000", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 38, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325520000000000000000000000000000000000000000000000000000000000000001", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 39, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 40, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 41, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 42, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 43, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff00000001000000000000000000000001000000000000000000000000", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 44, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 45, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000001", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 46, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 47, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 48, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 49, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff00000001000000000000000000000000ffffffffffffffffffffffff", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 50, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff00000001000000000000000000000001000000000000000000000000", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 51, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff000000010000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 52, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff000000010000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 53, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000001000000000000000000000001000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 54, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000001000000000000000000000001000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 55, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000001000000000000000000000001000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 56, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000001000000000000000000000001000000000000000000000000ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 57, - "comment" : "Signature with special case values for r and s", - "msg" : "313233343030", - "sig" : "ffffffff00000001000000000000000000000001000000000000000000000000ffffffff00000001000000000000000000000001000000000000000000000000", - "result" : "invalid", - "flags" : [ - "EdgeCase" - ] - }, - { - "tcId" : 58, - "comment" : "Edge case for Shamir multiplication", - "msg" : "3639383139", - "sig" : "64a1aab5000d0e804f3e2fc02bdee9be8ff312334e2ba16d11547c97711c898e6af015971cc30be6d1a206d4e013e0997772a2f91d73286ffd683b9bb2cf4f1b", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 59, - "comment" : "special case hash", - "msg" : "343236343739373234", - "sig" : "16aea964a2f6506d6f78c81c91fc7e8bded7d397738448de1e19a0ec580bf266252cd762130c6667cfe8b7bc47d27d78391e8e80c578d1cd38c3ff033be928e9", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 60, - "comment" : "special case hash", - "msg" : "37313338363834383931", - "sig" : "9cc98be2347d469bf476dfc26b9b733df2d26d6ef524af917c665baccb23c882093496459effe2d8d70727b82462f61d0ec1b7847929d10ea631dacb16b56c32", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 61, - "comment" : "special case hash", - "msg" : "3130333539333331363638", - "sig" : "73b3c90ecd390028058164524dde892703dce3dea0d53fa8093999f07ab8aa432f67b0b8e20636695bb7d8bf0a651c802ed25a395387b5f4188c0c4075c88634", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 62, - "comment" : "special case hash", - "msg" : "33393439343031323135", - "sig" : "bfab3098252847b328fadf2f89b95c851a7f0eb390763378f37e90119d5ba3ddbdd64e234e832b1067c2d058ccb44d978195ccebb65c2aaf1e2da9b8b4987e3b", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 63, - "comment" : "special case hash", - "msg" : "31333434323933303739", - "sig" : "204a9784074b246d8bf8bf04a4ceb1c1f1c9aaab168b1596d17093c5cd21d2cd51cce41670636783dc06a759c8847868a406c2506fe17975582fe648d1d88b52", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 64, - "comment" : "special case hash", - "msg" : "33373036323131373132", - "sig" : "ed66dc34f551ac82f63d4aa4f81fe2cb0031a91d1314f835027bca0f1ceeaa0399ca123aa09b13cd194a422e18d5fda167623c3f6e5d4d6abb8953d67c0c48c7", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 65, - "comment" : "special case hash", - "msg" : "333433363838373132", - "sig" : "060b700bef665c68899d44f2356a578d126b062023ccc3c056bf0f60a237012b8d186c027832965f4fcc78a3366ca95dedbb410cbef3f26d6be5d581c11d3610", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 66, - "comment" : "special case hash", - "msg" : "31333531353330333730", - "sig" : "9f6adfe8d5eb5b2c24d7aa7934b6cf29c93ea76cd313c9132bb0c8e38c96831db26a9c9e40e55ee0890c944cf271756c906a33e66b5bd15e051593883b5e9902", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 67, - "comment" : "special case hash", - "msg" : "36353533323033313236", - "sig" : "a1af03ca91677b673ad2f33615e56174a1abf6da168cebfa8868f4ba273f16b720aa73ffe48afa6435cd258b173d0c2377d69022e7d098d75caf24c8c5e06b1c", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 68, - "comment" : "special case hash", - "msg" : "31353634333436363033", - "sig" : "fdc70602766f8eed11a6c99a71c973d5659355507b843da6e327a28c11893db93df5349688a085b137b1eacf456a9e9e0f6d15ec0078ca60a7f83f2b10d21350", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 69, - "comment" : "special case hash", - "msg" : "34343239353339313137", - "sig" : "b516a314f2fce530d6537f6a6c49966c23456f63c643cf8e0dc738f7b876e675d39ffd033c92b6d717dd536fbc5efdf1967c4bd80954479ba66b0120cd16fff2", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 70, - "comment" : "special case hash", - "msg" : "3130393533323631333531", - "sig" : "3b2cbf046eac45842ecb7984d475831582717bebb6492fd0a485c101e29ff0a84c9b7b47a98b0f82de512bc9313aaf51701099cac5f76e68c8595fc1c1d99258", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 71, - "comment" : "special case hash", - "msg" : "35393837333530303431", - "sig" : "30c87d35e636f540841f14af54e2f9edd79d0312cfa1ab656c3fb15bfde48dcf47c15a5a82d24b75c85a692bd6ecafeb71409ede23efd08e0db9abf6340677ed", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 72, - "comment" : "special case hash", - "msg" : "33343633303036383738", - "sig" : "38686ff0fda2cef6bc43b58cfe6647b9e2e8176d168dec3c68ff262113760f52067ec3b651f422669601662167fa8717e976e2db5e6a4cf7c2ddabb3fde9d67d", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 73, - "comment" : "special case hash", - "msg" : "39383137333230323837", - "sig" : "44a3e23bf314f2b344fc25c7f2de8b6af3e17d27f5ee844b225985ab6e2775cf2d48e223205e98041ddc87be532abed584f0411f5729500493c9cc3f4dd15e86", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 74, - "comment" : "special case hash", - "msg" : "33323232303431303436", - "sig" : "2ded5b7ec8e90e7bf11f967a3d95110c41b99db3b5aa8d330eb9d638781688e97d5792c53628155e1bfc46fb1a67e3088de049c328ae1f44ec69238a009808f9", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 75, - "comment" : "special case hash", - "msg" : "36363636333037313034", - "sig" : "bdae7bcb580bf335efd3bc3d31870f923eaccafcd40ec2f605976f15137d8b8ff6dfa12f19e525270b0106eecfe257499f373a4fb318994f24838122ce7ec3c7", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 76, - "comment" : "special case hash", - "msg" : "31303335393531383938", - "sig" : "50f9c4f0cd6940e162720957ffff513799209b78596956d21ece251c2401f1c6d7033a0a787d338e889defaaabb106b95a4355e411a59c32aa5167dfab244726", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 77, - "comment" : "special case hash", - "msg" : "31383436353937313935", - "sig" : "f612820687604fa01906066a378d67540982e29575d019aabe90924ead5c860d3f9367702dd7dd4f75ea98afd20e328a1a99f4857b316525328230ce294b0fef", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 78, - "comment" : "special case hash", - "msg" : "33313336303436313839", - "sig" : "9505e407657d6e8bc93db5da7aa6f5081f61980c1949f56b0f2f507da5782a7ac60d31904e3669738ffbeccab6c3656c08e0ed5cb92b3cfa5e7f71784f9c5021", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 79, - "comment" : "special case hash", - "msg" : "32363633373834323534", - "sig" : "bbd16fbbb656b6d0d83e6a7787cd691b08735aed371732723e1c68a40404517d9d8e35dba96028b7787d91315be675877d2d097be5e8ee34560e3e7fd25c0f00", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 80, - "comment" : "special case hash", - "msg" : "31363532313030353234", - "sig" : "2ec9760122db98fd06ea76848d35a6da442d2ceef7559a30cf57c61e92df327e7ab271da90859479701fccf86e462ee3393fb6814c27b760c4963625c0a19878", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 81, - "comment" : "special case hash", - "msg" : "35373438303831363936", - "sig" : "54e76b7683b6650baa6a7fc49b1c51eed9ba9dd463221f7a4f1005a89fe00c592ea076886c773eb937ec1cc8374b7915cfd11b1c1ae1166152f2f7806a31c8fd", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 82, - "comment" : "special case hash", - "msg" : "36333433393133343638", - "sig" : "5291deaf24659ffbbce6e3c26f6021097a74abdbb69be4fb10419c0c496c946665d6fcf336d27cc7cdb982bb4e4ecef5827f84742f29f10abf83469270a03dc3", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 83, - "comment" : "special case hash", - "msg" : "31353431313033353938", - "sig" : "207a3241812d75d947419dc58efb05e8003b33fc17eb50f9d15166a88479f107cdee749f2e492b213ce80b32d0574f62f1c5d70793cf55e382d5caadf7592767", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 84, - "comment" : "special case hash", - "msg" : "3130343738353830313238", - "sig" : "6554e49f82a855204328ac94913bf01bbe84437a355a0a37c0dee3cf81aa7728aea00de2507ddaf5c94e1e126980d3df16250a2eaebc8be486effe7f22b4f929", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 85, - "comment" : "special case hash", - "msg" : "3130353336323835353638", - "sig" : "a54c5062648339d2bff06f71c88216c26c6e19b4d80a8c602990ac82707efdfce99bbe7fcfafae3e69fd016777517aa01056317f467ad09aff09be73c9731b0d", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 86, - "comment" : "special case hash", - "msg" : "393533393034313035", - "sig" : "975bd7157a8d363b309f1f444012b1a1d23096593133e71b4ca8b059cff37eaf7faa7a28b1c822baa241793f2abc930bd4c69840fe090f2aacc46786bf919622", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 87, - "comment" : "special case hash", - "msg" : "393738383438303339", - "sig" : "5694a6f84b8f875c276afd2ebcfe4d61de9ec90305afb1357b95b3e0da43885e0dffad9ffd0b757d8051dec02ebdf70d8ee2dc5c7870c0823b6ccc7c679cbaa4", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 88, - "comment" : "special case hash", - "msg" : "33363130363732343432", - "sig" : "a0c30e8026fdb2b4b4968a27d16a6d08f7098f1a98d21620d7454ba9790f1ba65e470453a8a399f15baf463f9deceb53acc5ca64459149688bd2760c65424339", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 89, - "comment" : "special case hash", - "msg" : "31303534323430373035", - "sig" : "614ea84acf736527dd73602cd4bb4eea1dfebebd5ad8aca52aa0228cf7b99a88737cc85f5f2d2f60d1b8183f3ed490e4de14368e96a9482c2a4dd193195c902f", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 90, - "comment" : "special case hash", - "msg" : "35313734343438313937", - "sig" : "bead6734ebe44b810d3fb2ea00b1732945377338febfd439a8d74dfbd0f942fa6bb18eae36616a7d3cad35919fd21a8af4bbe7a10f73b3e036a46b103ef56e2a", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 91, - "comment" : "special case hash", - "msg" : "31393637353631323531", - "sig" : "499625479e161dacd4db9d9ce64854c98d922cbf212703e9654fae182df9bad242c177cf37b8193a0131108d97819edd9439936028864ac195b64fca76d9d693", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 92, - "comment" : "special case hash", - "msg" : "33343437323533333433", - "sig" : "08f16b8093a8fb4d66a2c8065b541b3d31e3bfe694f6b89c50fb1aaa6ff6c9b29d6455e2d5d1779748573b611cb95d4a21f967410399b39b535ba3e5af81ca2e", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 93, - "comment" : "special case hash", - "msg" : "333638323634333138", - "sig" : "be26231b6191658a19dd72ddb99ed8f8c579b6938d19bce8eed8dc2b338cb5f8e1d9a32ee56cffed37f0f22b2dcb57d5c943c14f79694a03b9c5e96952575c89", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 94, - "comment" : "special case hash", - "msg" : "33323631313938363038", - "sig" : "15e76880898316b16204ac920a02d58045f36a229d4aa4f812638c455abe0443e74d357d3fcb5c8c5337bd6aba4178b455ca10e226e13f9638196506a1939123", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 95, - "comment" : "special case hash", - "msg" : "39363738373831303934", - "sig" : "352ecb53f8df2c503a45f9846fc28d1d31e6307d3ddbffc1132315cc07f16dad1348dfa9c482c558e1d05c5242ca1c39436726ecd28258b1899792887dd0a3c6", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 96, - "comment" : "special case hash", - "msg" : "34393538383233383233", - "sig" : "4a40801a7e606ba78a0da9882ab23c7677b8642349ed3d652c5bfa5f2a9558fb3a49b64848d682ef7f605f2832f7384bdc24ed2925825bf8ea77dc5981725782", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 97, - "comment" : "special case hash", - "msg" : "383234363337383337", - "sig" : "eacc5e1a8304a74d2be412b078924b3bb3511bac855c05c9e5e9e44df3d61e967451cd8e18d6ed1885dd827714847f96ec4bb0ed4c36ce9808db8f714204f6d1", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 98, - "comment" : "special case hash", - "msg" : "3131303230383333373736", - "sig" : "2f7a5e9e5771d424f30f67fdab61e8ce4f8cd1214882adb65f7de94c31577052ac4e69808345809b44acb0b2bd889175fb75dd050c5a449ab9528f8f78daa10c", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 99, - "comment" : "special case hash", - "msg" : "313333383731363438", - "sig" : "ffcda40f792ce4d93e7e0f0e95e1a2147dddd7f6487621c30a03d710b330021979938b55f8a17f7ed7ba9ade8f2065a1fa77618f0b67add8d58c422c2453a49a", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 100, - "comment" : "special case hash", - "msg" : "333232313434313632", - "sig" : "81f2359c4faba6b53d3e8c8c3fcc16a948350f7ab3a588b28c17603a431e39a8cd6f6a5cc3b55ead0ff695d06c6860b509e46d99fccefb9f7f9e101857f74300", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 101, - "comment" : "special case hash", - "msg" : "3130363836363535353436", - "sig" : "dfc8bf520445cbb8ee1596fb073ea283ea130251a6fdffa5c3f5f2aaf75ca808048e33efce147c9dd92823640e338e68bfd7d0dc7a4905b3a7ac711e577e90e7", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 102, - "comment" : "special case hash", - "msg" : "3632313535323436", - "sig" : "ad019f74c6941d20efda70b46c53db166503a0e393e932f688227688ba6a576293320eb7ca0710255346bdbb3102cdcf7964ef2e0988e712bc05efe16c199345", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 103, - "comment" : "special case hash", - "msg" : "37303330383138373734", - "sig" : "ac8096842e8add68c34e78ce11dd71e4b54316bd3ebf7fffdeb7bd5a3ebc1883f5ca2f4f23d674502d4caf85d187215d36e3ce9f0ce219709f21a3aac003b7a8", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 104, - "comment" : "special case hash", - "msg" : "35393234353233373434", - "sig" : "677b2d3a59b18a5ff939b70ea002250889ddcd7b7b9d776854b4943693fb92f76b4ba856ade7677bf30307b21f3ccda35d2f63aee81efd0bab6972cc0795db55", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 105, - "comment" : "special case hash", - "msg" : "31343935353836363231", - "sig" : "479e1ded14bcaed0379ba8e1b73d3115d84d31d4b7c30e1f05e1fc0d5957cfb0918f79e35b3d89487cf634a4f05b2e0c30857ca879f97c771e877027355b2443", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 106, - "comment" : "special case hash", - "msg" : "34303035333134343036", - "sig" : "43dfccd0edb9e280d9a58f01164d55c3d711e14b12ac5cf3b64840ead512a0a31dbe33fa8ba84533cd5c4934365b3442ca1174899b78ef9a3199f49584389772", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 107, - "comment" : "special case hash", - "msg" : "33303936343537353132", - "sig" : "5b09ab637bd4caf0f4c7c7e4bca592fea20e9087c259d26a38bb4085f0bbff1145b7eb467b6748af618e9d80d6fdcd6aa24964e5a13f885bca8101de08eb0d75", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 108, - "comment" : "special case hash", - "msg" : "32373834303235363230", - "sig" : "5e9b1c5a028070df5728c5c8af9b74e0667afa570a6cfa0114a5039ed15ee06fb1360907e2d9785ead362bb8d7bd661b6c29eeffd3c5037744edaeb9ad990c20", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 109, - "comment" : "special case hash", - "msg" : "32363138373837343138", - "sig" : "0671a0a85c2b72d54a2fb0990e34538b4890050f5a5712f6d1a7a5fb8578f32edb1846bab6b7361479ab9c3285ca41291808f27fd5bd4fdac720e5854713694c", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 110, - "comment" : "special case hash", - "msg" : "31363432363235323632", - "sig" : "7673f8526748446477dbbb0590a45492c5d7d69859d301abbaedb35b2095103a3dc70ddf9c6b524d886bed9e6af02e0e4dec0d417a414fed3807ef4422913d7c", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 111, - "comment" : "special case hash", - "msg" : "36383234313839343336", - "sig" : "7f085441070ecd2bb21285089ebb1aa6450d1a06c36d3ff39dfd657a796d12b5249712012029870a2459d18d47da9aa492a5e6cb4b2d8dafa9e4c5c54a2b9a8b", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 112, - "comment" : "special case hash", - "msg" : "343834323435343235", - "sig" : "914c67fb61dd1e27c867398ea7322d5ab76df04bc5aa6683a8e0f30a5d287348fa07474031481dda4953e3ac1959ee8cea7e66ec412b38d6c96d28f6d37304ea", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "CtmVACiNRmlAAx1yqfVEWk1DeEZAhVvwpph00t5f4QM", - "y" : "xQEebvLELc1Q1dPSn5mubrosgMkkT0xUIvCXn_DDul4" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "040ad99500288d466940031d72a9f5445a4d43784640855bf0a69874d2de5fe103c5011e6ef2c42dcd50d5d3d29f99ae6eba2c80c9244f4c5422f0979ff0c3ba5e", - "wx" : "0ad99500288d466940031d72a9f5445a4d43784640855bf0a69874d2de5fe103", - "wy" : "00c5011e6ef2c42dcd50d5d3d29f99ae6eba2c80c9244f4c5422f0979ff0c3ba5e" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200040ad99500288d466940031d72a9f5445a4d43784640855bf0a69874d2de5fe103c5011e6ef2c42dcd50d5d3d29f99ae6eba2c80c9244f4c5422f0979ff0c3ba5e", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAECtmVACiNRmlAAx1yqfVEWk1DeEZA\nhVvwpph00t5f4QPFAR5u8sQtzVDV09Kfma5uuiyAySRPTFQi8Jef8MO6Xg==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 113, - "comment" : "k*G has a large x-coordinate", - "msg" : "313233343030", - "sig" : "000000000000000000000000000000004319055358e8617b0c46353d039cdaabffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 114, - "comment" : "r too large", - "msg" : "313233343030", - "sig" : "ffffffff00000001000000000000000000000000fffffffffffffffffffffffcffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e", - "result" : "invalid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "qwX9nQ3ia5zm9IGWUtn8aRk9CqOY8PuoAT4JxYIgRVQ", - "y" : "GSNScSKMeGdZCV0St1rwaS3UED8Z9qjDL0lDWh6bjUU" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04ab05fd9d0de26b9ce6f4819652d9fc69193d0aa398f0fba8013e09c58220455419235271228c786759095d12b75af0692dd4103f19f6a8c32f49435a1e9b8d45", - "wx" : "00ab05fd9d0de26b9ce6f4819652d9fc69193d0aa398f0fba8013e09c582204554", - "wy" : "19235271228c786759095d12b75af0692dd4103f19f6a8c32f49435a1e9b8d45" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004ab05fd9d0de26b9ce6f4819652d9fc69193d0aa398f0fba8013e09c58220455419235271228c786759095d12b75af0692dd4103f19f6a8c32f49435a1e9b8d45", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqwX9nQ3ia5zm9IGWUtn8aRk9CqOY\n8PuoAT4JxYIgRVQZI1JxIox4Z1kJXRK3WvBpLdQQPxn2qMMvSUNaHpuNRQ==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 115, - "comment" : "r,s are large", - "msg" : "313233343030", - "sig" : "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "gJhPOaH_OKhqaKpCAba-Xfv-z4diGXELB7rfb91MbFY", - "y" : "Ef65c5DZgm56Bt-0GHHJQNdEFe08rCCJ8URQGbtV7ZU" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "0480984f39a1ff38a86a68aa4201b6be5dfbfecf876219710b07badf6fdd4c6c5611feb97390d9826e7a06dfb41871c940d74415ed3cac2089f1445019bb55ed95", - "wx" : "0080984f39a1ff38a86a68aa4201b6be5dfbfecf876219710b07badf6fdd4c6c56", - "wy" : "11feb97390d9826e7a06dfb41871c940d74415ed3cac2089f1445019bb55ed95" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d0301070342000480984f39a1ff38a86a68aa4201b6be5dfbfecf876219710b07badf6fdd4c6c5611feb97390d9826e7a06dfb41871c940d74415ed3cac2089f1445019bb55ed95", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgJhPOaH/OKhqaKpCAba+Xfv+z4di\nGXELB7rfb91MbFYR/rlzkNmCbnoG37QYcclA10QV7TysIInxRFAZu1XtlQ==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 116, - "comment" : "r and s^-1 have a large Hamming weight", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd909135bdb6799286170f5ead2de4f6511453fe50914f3df2de54a36383df8dd4", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "QgG0JylEIBwylPW6qaMjK23Wh0lfzBmnCpW8YCtPfAU", - "y" : "lcN-up7oFxwbtaxv6vdTvDb0Y-Ou8WYpVywMCo-wgA4" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "044201b4272944201c3294f5baa9a3232b6dd687495fcc19a70a95bc602b4f7c0595c37eba9ee8171c1bb5ac6feaf753bc36f463e3aef16629572c0c0a8fb0800e", - "wx" : "4201b4272944201c3294f5baa9a3232b6dd687495fcc19a70a95bc602b4f7c05", - "wy" : "0095c37eba9ee8171c1bb5ac6feaf753bc36f463e3aef16629572c0c0a8fb0800e" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200044201b4272944201c3294f5baa9a3232b6dd687495fcc19a70a95bc602b4f7c0595c37eba9ee8171c1bb5ac6feaf753bc36f463e3aef16629572c0c0a8fb0800e", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEQgG0JylEIBwylPW6qaMjK23Wh0lf\nzBmnCpW8YCtPfAWVw366nugXHBu1rG/q91O8NvRj467xZilXLAwKj7CADg==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 117, - "comment" : "r and s^-1 have a large Hamming weight", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd27b4577ca009376f71303fd5dd227dcef5deb773ad5f5a84360644669ca249a5", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "pxr2TeUSakpOAreSLWbOlBXOiKTJ0lUU2RCCyHJayVc", - "y" : "XUdyPI--WAuzaf7JwmZdjjCkNbmTJkVILnyfEehyKWs" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04a71af64de5126a4a4e02b7922d66ce9415ce88a4c9d25514d91082c8725ac9575d47723c8fbe580bb369fec9c2665d8e30a435b9932645482e7c9f11e872296b", - "wx" : "00a71af64de5126a4a4e02b7922d66ce9415ce88a4c9d25514d91082c8725ac957", - "wy" : "5d47723c8fbe580bb369fec9c2665d8e30a435b9932645482e7c9f11e872296b" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004a71af64de5126a4a4e02b7922d66ce9415ce88a4c9d25514d91082c8725ac9575d47723c8fbe580bb369fec9c2665d8e30a435b9932645482e7c9f11e872296b", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEpxr2TeUSakpOAreSLWbOlBXOiKTJ\n0lUU2RCCyHJayVddR3I8j75YC7Np/snCZl2OMKQ1uZMmRUgufJ8R6HIpaw==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 118, - "comment" : "small r and s", - "msg" : "313233343030", - "sig" : "00000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000001", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 119, - "comment" : "incorrect size of signature", - "msg" : "313233343030", - "sig" : "0501", - "result" : "acceptable", - "flags" : [ - "SigSize" - ] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "ZifOxPBzHqI_wpMfkOvlt1cvWX0g3wj8KzHujvFrFXI", - "y" : "YXDtd9jQoU_FycPEyb5_DT7hj3CbsnXq8gc-JY_mlKU" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "046627cec4f0731ea23fc2931f90ebe5b7572f597d20df08fc2b31ee8ef16b15726170ed77d8d0a14fc5c9c3c4c9be7f0d3ee18f709bb275eaf2073e258fe694a5", - "wx" : "6627cec4f0731ea23fc2931f90ebe5b7572f597d20df08fc2b31ee8ef16b1572", - "wy" : "6170ed77d8d0a14fc5c9c3c4c9be7f0d3ee18f709bb275eaf2073e258fe694a5" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200046627cec4f0731ea23fc2931f90ebe5b7572f597d20df08fc2b31ee8ef16b15726170ed77d8d0a14fc5c9c3c4c9be7f0d3ee18f709bb275eaf2073e258fe694a5", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZifOxPBzHqI/wpMfkOvlt1cvWX0g\n3wj8KzHujvFrFXJhcO132NChT8XJw8TJvn8NPuGPcJuyderyBz4lj+aUpQ==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 120, - "comment" : "small r and s", - "msg" : "313233343030", - "sig" : "00000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000003", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 121, - "comment" : "incorrect size of signature", - "msg" : "313233343030", - "sig" : "0503", - "result" : "acceptable", - "flags" : [ - "SigSize" - ] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "WnyIJehWkczh9edUTFTnPxSvwBDLcxNDJiyn7Fp39b8", - "y" : "727fYqRJfBvXsUf7bD0irzw5v86V8w4ToW09eygS-BM" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "045a7c8825e85691cce1f5e7544c54e73f14afc010cb731343262ca7ec5a77f5bfef6edf62a4497c1bd7b147fb6c3d22af3c39bfce95f30e13a16d3d7b2812f813", - "wx" : "5a7c8825e85691cce1f5e7544c54e73f14afc010cb731343262ca7ec5a77f5bf", - "wy" : "00ef6edf62a4497c1bd7b147fb6c3d22af3c39bfce95f30e13a16d3d7b2812f813" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200045a7c8825e85691cce1f5e7544c54e73f14afc010cb731343262ca7ec5a77f5bfef6edf62a4497c1bd7b147fb6c3d22af3c39bfce95f30e13a16d3d7b2812f813", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWnyIJehWkczh9edUTFTnPxSvwBDL\ncxNDJiyn7Fp39b/vbt9ipEl8G9exR/tsPSKvPDm/zpXzDhOhbT17KBL4Ew==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 122, - "comment" : "small r and s", - "msg" : "313233343030", - "sig" : "00000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000005", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 123, - "comment" : "incorrect size of signature", - "msg" : "313233343030", - "sig" : "0505", - "result" : "acceptable", - "flags" : [ - "SigSize" - ] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "y-DCkTLNc4Nk_t1gMVKZDASOXi__mW2IP6bKynl4xzc", - "y" : "cK9qjORMtBIksmA2BvTATRiOgL_3zDGtUYnUqw1w6ME" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04cbe0c29132cd738364fedd603152990c048e5e2fff996d883fa6caca7978c73770af6a8ce44cb41224b2603606f4c04d188e80bff7cc31ad5189d4ab0d70e8c1", - "wx" : "00cbe0c29132cd738364fedd603152990c048e5e2fff996d883fa6caca7978c737", - "wy" : "70af6a8ce44cb41224b2603606f4c04d188e80bff7cc31ad5189d4ab0d70e8c1" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004cbe0c29132cd738364fedd603152990c048e5e2fff996d883fa6caca7978c73770af6a8ce44cb41224b2603606f4c04d188e80bff7cc31ad5189d4ab0d70e8c1", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEy+DCkTLNc4Nk/t1gMVKZDASOXi//\nmW2IP6bKynl4xzdwr2qM5Ey0EiSyYDYG9MBNGI6Av/fMMa1RidSrDXDowQ==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 124, - "comment" : "small r and s", - "msg" : "313233343030", - "sig" : "00000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000006", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 125, - "comment" : "incorrect size of signature", - "msg" : "313233343030", - "sig" : "0506", - "result" : "acceptable", - "flags" : [ - "SigSize" - ] - }, - { - "tcId" : 126, - "comment" : "r is larger than n", - "msg" : "313233343030", - "sig" : "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325560000000000000000000000000000000000000000000000000000000000000006", - "result" : "invalid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "S-QXgJcALw3qto8NmhMODtM6Z5XQKiB5bbg0RLA34Tk", - "y" : "IPEwUeDuzc_OTazqD1DR8kfKpmnxk8G0B1tRriltLVY" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "044be4178097002f0deab68f0d9a130e0ed33a6795d02a20796db83444b037e13920f13051e0eecdcfce4dacea0f50d1f247caa669f193c1b4075b51ae296d2d56", - "wx" : "4be4178097002f0deab68f0d9a130e0ed33a6795d02a20796db83444b037e139", - "wy" : "20f13051e0eecdcfce4dacea0f50d1f247caa669f193c1b4075b51ae296d2d56" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200044be4178097002f0deab68f0d9a130e0ed33a6795d02a20796db83444b037e13920f13051e0eecdcfce4dacea0f50d1f247caa669f193c1b4075b51ae296d2d56", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAES+QXgJcALw3qto8NmhMODtM6Z5XQ\nKiB5bbg0RLA34Tkg8TBR4O7Nz85NrOoPUNHyR8qmafGTwbQHW1GuKW0tVg==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 127, - "comment" : "s is larger than n", - "msg" : "313233343030", - "sig" : "0000000000000000000000000000000000000000000000000000000000000005ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc75fbd8", - "result" : "invalid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "0Pc3kiA3Fq_UvkMp-qSNJp8VMT67ujedd4PJe_PokNk", - "y" : "lx9KMgZgW-wheCv14nXHFEF-j1ZlSea8aGkNI2PInME" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04d0f73792203716afd4be4329faa48d269f15313ebbba379d7783c97bf3e890d9971f4a3206605bec21782bf5e275c714417e8f566549e6bc68690d2363c89cc1", - "wx" : "00d0f73792203716afd4be4329faa48d269f15313ebbba379d7783c97bf3e890d9", - "wy" : "00971f4a3206605bec21782bf5e275c714417e8f566549e6bc68690d2363c89cc1" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004d0f73792203716afd4be4329faa48d269f15313ebbba379d7783c97bf3e890d9971f4a3206605bec21782bf5e275c714417e8f566549e6bc68690d2363c89cc1", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE0Pc3kiA3Fq/UvkMp+qSNJp8VMT67\nujedd4PJe/PokNmXH0oyBmBb7CF4K/XidccUQX6PVmVJ5rxoaQ0jY8icwQ==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 128, - "comment" : "small r and s^-1", - "msg" : "313233343030", - "sig" : "00000000000000000000000000000000000000000000000000000000000001008f1e3c7862c58b16bb76eddbb76eddbb516af4f63f2d74d76e0d28c9bb75ea88", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "SDiyvjWmJ2qA754igUD52bls6Dt6JU9xzN67uAVM4F8", - "y" : "-py8EjyRmxngAjgZjQQGkEO9ZgqCiBQFH8uKrHOKbGs" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "044838b2be35a6276a80ef9e228140f9d9b96ce83b7a254f71ccdebbb8054ce05ffa9cbc123c919b19e00238198d04069043bd660a828814051fcb8aac738a6c6b", - "wx" : "4838b2be35a6276a80ef9e228140f9d9b96ce83b7a254f71ccdebbb8054ce05f", - "wy" : "00fa9cbc123c919b19e00238198d04069043bd660a828814051fcb8aac738a6c6b" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200044838b2be35a6276a80ef9e228140f9d9b96ce83b7a254f71ccdebbb8054ce05ffa9cbc123c919b19e00238198d04069043bd660a828814051fcb8aac738a6c6b", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAESDiyvjWmJ2qA754igUD52bls6Dt6\nJU9xzN67uAVM4F/6nLwSPJGbGeACOBmNBAaQQ71mCoKIFAUfy4qsc4psaw==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 129, - "comment" : "smallish r and s^-1", - "msg" : "313233343030", - "sig" : "000000000000000000000000000000000000000000000000002d9b4d347952d6ef3043e7329581dbb3974497710ab11505ee1c87ff907beebadd195a0ffe6d7a", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "c5OYPKMKUgu8R4PcmWB0aqtETvUgwKjncRGapOdLD2Q", - "y" : "6de-GrAaC_Ym5wmGPmpIbbrzJ5OvzPd04sbNJ7GFdSY" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "047393983ca30a520bbc4783dc9960746aab444ef520c0a8e771119aa4e74b0f64e9d7be1ab01a0bf626e709863e6a486dbaf32793afccf774e2c6cd27b1857526", - "wx" : "7393983ca30a520bbc4783dc9960746aab444ef520c0a8e771119aa4e74b0f64", - "wy" : "00e9d7be1ab01a0bf626e709863e6a486dbaf32793afccf774e2c6cd27b1857526" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200047393983ca30a520bbc4783dc9960746aab444ef520c0a8e771119aa4e74b0f64e9d7be1ab01a0bf626e709863e6a486dbaf32793afccf774e2c6cd27b1857526", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEc5OYPKMKUgu8R4PcmWB0aqtETvUg\nwKjncRGapOdLD2Tp174asBoL9ibnCYY+akhtuvMnk6/M93Tixs0nsYV1Jg==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 130, - "comment" : "100-bit r and small s^-1", - "msg" : "313233343030", - "sig" : "000000000000000000000000000000000000001033e67e37b32b445580bf4eff8b748b74000000008b748b748b748b7466e769ad4a16d3dcd87129b8e91d1b4d", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "WsMxoRA_6WZpc3nzVqk381BYigVHfjCIUbilAtXfzcU", - "y" : "_pmT30tXk5srjaCVv215QmUgTP4DvplaAuZdQIyHHAs" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "045ac331a1103fe966697379f356a937f350588a05477e308851b8a502d5dfcdc5fe9993df4b57939b2b8da095bf6d794265204cfe03be995a02e65d408c871c0b", - "wx" : "5ac331a1103fe966697379f356a937f350588a05477e308851b8a502d5dfcdc5", - "wy" : "00fe9993df4b57939b2b8da095bf6d794265204cfe03be995a02e65d408c871c0b" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200045ac331a1103fe966697379f356a937f350588a05477e308851b8a502d5dfcdc5fe9993df4b57939b2b8da095bf6d794265204cfe03be995a02e65d408c871c0b", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWsMxoRA/6WZpc3nzVqk381BYigVH\nfjCIUbilAtXfzcX+mZPfS1eTmyuNoJW/bXlCZSBM/gO+mVoC5l1AjIccCw==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 131, - "comment" : "small r and 100 bit s^-1", - "msg" : "313233343030", - "sig" : "0000000000000000000000000000000000000000000000000000000000000100ef9f6ba4d97c09d03178fa20b4aaad83be3cf9cb824a879fec3270fc4b81ef5b", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "HSCb6N4t6HcJWjmdOQTHTMRY2Sbie7jljl6uV2fEFQk", - "y" : "3VngTCFPexjc41H8KlSYk6aGDoAWPzjMYKTyydBA2Mk" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "041d209be8de2de877095a399d3904c74cc458d926e27bb8e58e5eae5767c41509dd59e04c214f7b18dce351fc2a549893a6860e80163f38cc60a4f2c9d040d8c9", - "wx" : "1d209be8de2de877095a399d3904c74cc458d926e27bb8e58e5eae5767c41509", - "wy" : "00dd59e04c214f7b18dce351fc2a549893a6860e80163f38cc60a4f2c9d040d8c9" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200041d209be8de2de877095a399d3904c74cc458d926e27bb8e58e5eae5767c41509dd59e04c214f7b18dce351fc2a549893a6860e80163f38cc60a4f2c9d040d8c9", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEHSCb6N4t6HcJWjmdOQTHTMRY2Sbi\ne7jljl6uV2fEFQndWeBMIU97GNzjUfwqVJiTpoYOgBY/OMxgpPLJ0EDYyQ==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 132, - "comment" : "100-bit r and s^-1", - "msg" : "313233343030", - "sig" : "00000000000000000000000000000000000000062522bbd3ecbe7c39e93e7c25ef9f6ba4d97c09d03178fa20b4aaad83be3cf9cb824a879fec3270fc4b81ef5b", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "CDU5--5EYl46yq-i_LQTSTks7wYzobj6vs7gwTOxDpk", - "y" : "kVwevnvwDfhTUZZ3ClgEeuKkAvJjJrt9QdTXYWM3kR4" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04083539fbee44625e3acaafa2fcb41349392cef0633a1b8fabecee0c133b10e99915c1ebe7bf00df8535196770a58047ae2a402f26326bb7d41d4d7616337911e", - "wx" : "083539fbee44625e3acaafa2fcb41349392cef0633a1b8fabecee0c133b10e99", - "wy" : "00915c1ebe7bf00df8535196770a58047ae2a402f26326bb7d41d4d7616337911e" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004083539fbee44625e3acaafa2fcb41349392cef0633a1b8fabecee0c133b10e99915c1ebe7bf00df8535196770a58047ae2a402f26326bb7d41d4d7616337911e", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAECDU5++5EYl46yq+i/LQTSTks7wYz\nobj6vs7gwTOxDpmRXB6+e/AN+FNRlncKWAR64qQC8mMmu31B1NdhYzeRHg==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 133, - "comment" : "r and s^-1 are close to n", - "msg" : "313233343030", - "sig" : "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6324d5555555550000000055555555555555553ef7a8e48d07df81a693439654210c70", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "ius2inAnpNZKveo3OQwMHWom85ni2XNN4es9Dhk3OHQ", - "y" : "Bb0Tg0cV4duum4dc8HvVXhtmkcf3U2rvOxm_ekrfV20" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "048aeb368a7027a4d64abdea37390c0c1d6a26f399e2d9734de1eb3d0e1937387405bd13834715e1dbae9b875cf07bd55e1b6691c7f7536aef3b19bf7a4adf576d", - "wx" : "008aeb368a7027a4d64abdea37390c0c1d6a26f399e2d9734de1eb3d0e19373874", - "wy" : "05bd13834715e1dbae9b875cf07bd55e1b6691c7f7536aef3b19bf7a4adf576d" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200048aeb368a7027a4d64abdea37390c0c1d6a26f399e2d9734de1eb3d0e1937387405bd13834715e1dbae9b875cf07bd55e1b6691c7f7536aef3b19bf7a4adf576d", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEius2inAnpNZKveo3OQwMHWom85ni\n2XNN4es9Dhk3OHQFvRODRxXh266bh1zwe9VeG2aRx/dTau87Gb96St9XbQ==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 134, - "comment" : "s == 1", - "msg" : "313233343030", - "sig" : "555555550000000055555555555555553ef7a8e48d07df81a693439654210c700000000000000000000000000000000000000000000000000000000000000001", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 135, - "comment" : "s == 0", - "msg" : "313233343030", - "sig" : "555555550000000055555555555555553ef7a8e48d07df81a693439654210c700000000000000000000000000000000000000000000000000000000000000000", - "result" : "invalid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "tTPUaV3VuMXgd1flXm5Rb34siPoCOeI_YOjsB91w8oc", - "y" : "GxNO5YzFgyeEVoY_M8OoXYgffUo5hQFD4p1OrwCa_kc" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04b533d4695dd5b8c5e07757e55e6e516f7e2c88fa0239e23f60e8ec07dd70f2871b134ee58cc583278456863f33c3a85d881f7d4a39850143e29d4eaf009afe47", - "wx" : "00b533d4695dd5b8c5e07757e55e6e516f7e2c88fa0239e23f60e8ec07dd70f287", - "wy" : "1b134ee58cc583278456863f33c3a85d881f7d4a39850143e29d4eaf009afe47" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004b533d4695dd5b8c5e07757e55e6e516f7e2c88fa0239e23f60e8ec07dd70f2871b134ee58cc583278456863f33c3a85d881f7d4a39850143e29d4eaf009afe47", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEtTPUaV3VuMXgd1flXm5Rb34siPoC\nOeI/YOjsB91w8ocbE07ljMWDJ4RWhj8zw6hdiB99SjmFAUPinU6vAJr+Rw==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 136, - "comment" : "point at infinity during verify", - "msg" : "313233343030", - "sig" : "7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a8555555550000000055555555555555553ef7a8e48d07df81a693439654210c70", - "result" : "invalid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "9Q03G5G_sdfRThMjUjvDqoy_LFf54oTeYoyLRTZ4e4Y", - "y" : "-UrYh6yU1SckfNLn0MixKRxVPJcwQFOAsUy7IJ9fot0" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04f50d371b91bfb1d7d14e1323523bc3aa8cbf2c57f9e284de628c8b4536787b86f94ad887ac94d527247cd2e7d0c8b1291c553c9730405380b14cbb209f5fa2dd", - "wx" : "00f50d371b91bfb1d7d14e1323523bc3aa8cbf2c57f9e284de628c8b4536787b86", - "wy" : "00f94ad887ac94d527247cd2e7d0c8b1291c553c9730405380b14cbb209f5fa2dd" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004f50d371b91bfb1d7d14e1323523bc3aa8cbf2c57f9e284de628c8b4536787b86f94ad887ac94d527247cd2e7d0c8b1291c553c9730405380b14cbb209f5fa2dd", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9Q03G5G/sdfRThMjUjvDqoy/LFf5\n4oTeYoyLRTZ4e4b5StiHrJTVJyR80ufQyLEpHFU8lzBAU4CxTLsgn1+i3Q==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 137, - "comment" : "edge case for signature malleability", - "msg" : "313233343030", - "sig" : "7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a97fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a8", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "aOxuKY6v4WU5FWzlehSwSnBHwiG6_DpYLq6w2FfE2UY", - "y" : "l77RrxeFARf9s5sjJPIgpWmO0WxCaiczW7OFrIym-zA" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "0468ec6e298eafe16539156ce57a14b04a7047c221bafc3a582eaeb0d857c4d94697bed1af17850117fdb39b2324f220a5698ed16c426a27335bb385ac8ca6fb30", - "wx" : "68ec6e298eafe16539156ce57a14b04a7047c221bafc3a582eaeb0d857c4d946", - "wy" : "0097bed1af17850117fdb39b2324f220a5698ed16c426a27335bb385ac8ca6fb30" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d0301070342000468ec6e298eafe16539156ce57a14b04a7047c221bafc3a582eaeb0d857c4d94697bed1af17850117fdb39b2324f220a5698ed16c426a27335bb385ac8ca6fb30", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEaOxuKY6v4WU5FWzlehSwSnBHwiG6\n/DpYLq6w2FfE2UaXvtGvF4UBF/2zmyMk8iClaY7RbEJqJzNbs4WsjKb7MA==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 138, - "comment" : "edge case for signature malleability", - "msg" : "313233343030", - "sig" : "7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a97fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a9", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "adoDZHNNLlMP7OlAGSZf77eBoPGwj2yIl732VXknyLg", - "y" : "ZtLTx9zVGLI9cmlg8Gmtcakz2G74q7zOiyD3HiqEcAI" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "0469da0364734d2e530fece94019265fefb781a0f1b08f6c8897bdf6557927c8b866d2d3c7dcd518b23d726960f069ad71a933d86ef8abbcce8b20f71e2a847002", - "wx" : "69da0364734d2e530fece94019265fefb781a0f1b08f6c8897bdf6557927c8b8", - "wy" : "66d2d3c7dcd518b23d726960f069ad71a933d86ef8abbcce8b20f71e2a847002" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d0301070342000469da0364734d2e530fece94019265fefb781a0f1b08f6c8897bdf6557927c8b866d2d3c7dcd518b23d726960f069ad71a933d86ef8abbcce8b20f71e2a847002", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEadoDZHNNLlMP7OlAGSZf77eBoPGw\nj2yIl732VXknyLhm0tPH3NUYsj1yaWDwaa1xqTPYbvirvM6LIPceKoRwAg==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 139, - "comment" : "u1 == 1", - "msg" : "313233343030", - "sig" : "555555550000000055555555555555553ef7a8e48d07df81a693439654210c70bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "2K3AACOo7cAlduK2Pj4wYhpHHisjIGIBh78GehrB_zI", - "y" : "M-K1DsCYB6zLNhMf_5XtEqCahrTqlpCqMoYVdrojYuE" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04d8adc00023a8edc02576e2b63e3e30621a471e2b2320620187bf067a1ac1ff3233e2b50ec09807accb36131fff95ed12a09a86b4ea9690aa32861576ba2362e1", - "wx" : "00d8adc00023a8edc02576e2b63e3e30621a471e2b2320620187bf067a1ac1ff32", - "wy" : "33e2b50ec09807accb36131fff95ed12a09a86b4ea9690aa32861576ba2362e1" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004d8adc00023a8edc02576e2b63e3e30621a471e2b2320620187bf067a1ac1ff3233e2b50ec09807accb36131fff95ed12a09a86b4ea9690aa32861576ba2362e1", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2K3AACOo7cAlduK2Pj4wYhpHHisj\nIGIBh78GehrB/zIz4rUOwJgHrMs2Ex//le0SoJqGtOqWkKoyhhV2uiNi4Q==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 140, - "comment" : "u1 == n - 1", - "msg" : "313233343030", - "sig" : "555555550000000055555555555555553ef7a8e48d07df81a693439654210c7044a5ad0ad0636d9f12bc9e0a6bdd5e1cbcb012ea7bf091fcec15b0c43202d52e", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "NiOslzztClb6bYgvA6fVx-3KAs_HskAfqzaQ2-dat4U", - "y" : "jbBpCOZLKGE9pyV-c385eT2o5xO6BkO5LpuzJSvn-P4" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "043623ac973ced0a56fa6d882f03a7d5c7edca02cfc7b2401fab3690dbe75ab7858db06908e64b28613da7257e737f39793da8e713ba0643b92e9bb3252be7f8fe", - "wx" : "3623ac973ced0a56fa6d882f03a7d5c7edca02cfc7b2401fab3690dbe75ab785", - "wy" : "008db06908e64b28613da7257e737f39793da8e713ba0643b92e9bb3252be7f8fe" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200043623ac973ced0a56fa6d882f03a7d5c7edca02cfc7b2401fab3690dbe75ab7858db06908e64b28613da7257e737f39793da8e713ba0643b92e9bb3252be7f8fe", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENiOslzztClb6bYgvA6fVx+3KAs/H\nskAfqzaQ2+dat4WNsGkI5ksoYT2nJX5zfzl5PajnE7oGQ7kum7MlK+f4/g==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 141, - "comment" : "u2 == 1", - "msg" : "313233343030", - "sig" : "555555550000000055555555555555553ef7a8e48d07df81a693439654210c70555555550000000055555555555555553ef7a8e48d07df81a693439654210c70", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "zwTqd-liJSPYlLk_9S3DAnsxlZUDtvo4kOXgQmP5IvE", - "y" : "6FKPt8AGs5g8i4QA5XtO1xdAwvOXVDiCEZm-3q7Ksuk" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04cf04ea77e9622523d894b93ff52dc3027b31959503b6fa3890e5e04263f922f1e8528fb7c006b3983c8b8400e57b4ed71740c2f3975438821199bedeaecab2e9", - "wx" : "00cf04ea77e9622523d894b93ff52dc3027b31959503b6fa3890e5e04263f922f1", - "wy" : "00e8528fb7c006b3983c8b8400e57b4ed71740c2f3975438821199bedeaecab2e9" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004cf04ea77e9622523d894b93ff52dc3027b31959503b6fa3890e5e04263f922f1e8528fb7c006b3983c8b8400e57b4ed71740c2f3975438821199bedeaecab2e9", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEzwTqd+liJSPYlLk/9S3DAnsxlZUD\ntvo4kOXgQmP5IvHoUo+3wAazmDyLhADle07XF0DC85dUOIIRmb7ersqy6Q==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 142, - "comment" : "u2 == n - 1", - "msg" : "313233343030", - "sig" : "555555550000000055555555555555553ef7a8e48d07df81a693439654210c70aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "23osihq1c-WSncJAd7UI1-aD1JInmWvaPp942-_3c1A", - "y" : "T0F_O8mogHXC4KrdWhMxFzDPfMdqgvEaNurwimyZogY" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04db7a2c8a1ab573e5929dc24077b508d7e683d49227996bda3e9f78dbeff773504f417f3bc9a88075c2e0aadd5a13311730cf7cc76a82f11a36eaf08a6c99a206", - "wx" : "00db7a2c8a1ab573e5929dc24077b508d7e683d49227996bda3e9f78dbeff77350", - "wy" : "4f417f3bc9a88075c2e0aadd5a13311730cf7cc76a82f11a36eaf08a6c99a206" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004db7a2c8a1ab573e5929dc24077b508d7e683d49227996bda3e9f78dbeff773504f417f3bc9a88075c2e0aadd5a13311730cf7cc76a82f11a36eaf08a6c99a206", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE23osihq1c+WSncJAd7UI1+aD1JIn\nmWvaPp942+/3c1BPQX87yaiAdcLgqt1aEzEXMM98x2qC8Ro26vCKbJmiBg==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 143, - "comment" : "edge case for u1", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffde91e1ba60fdedb76a46bcb51dc0b8b4b7e019f0a28721885fa5d3a8196623397", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "3q0Rx6WzloYvIZdNxHUvre_5lO_pu9BatBN2XqgLbh8", - "y" : "HePwZA6Kxu3Pic_1PEDiZbuUB4o0NzbfB6oDGPx_4f8" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04dead11c7a5b396862f21974dc4752fadeff994efe9bbd05ab413765ea80b6e1f1de3f0640e8ac6edcf89cff53c40e265bb94078a343736df07aa0318fc7fe1ff", - "wx" : "00dead11c7a5b396862f21974dc4752fadeff994efe9bbd05ab413765ea80b6e1f", - "wy" : "1de3f0640e8ac6edcf89cff53c40e265bb94078a343736df07aa0318fc7fe1ff" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004dead11c7a5b396862f21974dc4752fadeff994efe9bbd05ab413765ea80b6e1f1de3f0640e8ac6edcf89cff53c40e265bb94078a343736df07aa0318fc7fe1ff", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE3q0Rx6WzloYvIZdNxHUvre/5lO/p\nu9BatBN2XqgLbh8d4/BkDorG7c+Jz/U8QOJlu5QHijQ3Nt8HqgMY/H/h/w==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 144, - "comment" : "edge case for u1", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdea5843ffeb73af94313ba4831b53fe24f799e525b1e8e8c87b59b95b430ad9", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "0LxHLg18geuu06bvlsGGE7sf6m-ZQyb76A4A395nx-k", - "y" : "mGxyPqSEPUg4m5RvZK1WyDrXD_F7qFM1Zn0bufphnv0" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04d0bc472e0d7c81ebaed3a6ef96c18613bb1fea6f994326fbe80e00dfde67c7e9986c723ea4843d48389b946f64ad56c83ad70ff17ba85335667d1bb9fa619efd", - "wx" : "00d0bc472e0d7c81ebaed3a6ef96c18613bb1fea6f994326fbe80e00dfde67c7e9", - "wy" : "00986c723ea4843d48389b946f64ad56c83ad70ff17ba85335667d1bb9fa619efd" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004d0bc472e0d7c81ebaed3a6ef96c18613bb1fea6f994326fbe80e00dfde67c7e9986c723ea4843d48389b946f64ad56c83ad70ff17ba85335667d1bb9fa619efd", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE0LxHLg18geuu06bvlsGGE7sf6m+Z\nQyb76A4A395nx+mYbHI+pIQ9SDiblG9krVbIOtcP8XuoUzVmfRu5+mGe/Q==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 145, - "comment" : "edge case for u1", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd03ffcabf2f1b4d2a65190db1680d62bb994e41c5251cd73b3c3dfc5e5bafc035", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "oKRMqUfWairLc2AIucCNGrKtA3duAmQPeEldRY3VHDI", - "y" : "Yzf-XPjEYEsfHECdwthy1ClKR2JCDfQ6MKI5LkBCat0" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04a0a44ca947d66a2acb736008b9c08d1ab2ad03776e02640f78495d458dd51c326337fe5cf8c4604b1f1c409dc2d872d4294a4762420df43a30a2392e40426add", - "wx" : "00a0a44ca947d66a2acb736008b9c08d1ab2ad03776e02640f78495d458dd51c32", - "wy" : "6337fe5cf8c4604b1f1c409dc2d872d4294a4762420df43a30a2392e40426add" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004a0a44ca947d66a2acb736008b9c08d1ab2ad03776e02640f78495d458dd51c326337fe5cf8c4604b1f1c409dc2d872d4294a4762420df43a30a2392e40426add", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEoKRMqUfWairLc2AIucCNGrKtA3du\nAmQPeEldRY3VHDJjN/5c+MRgSx8cQJ3C2HLUKUpHYkIN9DowojkuQEJq3Q==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 146, - "comment" : "edge case for u1", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd4dfbc401f971cd304b33dfdb17d0fed0fe4c1a88ae648e0d2847f74977534989", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "ycIRUpDQCLRftl-tD2AjiSmMJUILd1AZ1Ctiw86Klrc", - "y" : "OHfSWoCA3ALZh8pzDwQFwsnb76xG-eYBzD8G6XE5c_0" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04c9c2115290d008b45fb65fad0f602389298c25420b775019d42b62c3ce8a96b73877d25a8080dc02d987ca730f0405c2c9dbefac46f9e601cc3f06e9713973fd", - "wx" : "00c9c2115290d008b45fb65fad0f602389298c25420b775019d42b62c3ce8a96b7", - "wy" : "3877d25a8080dc02d987ca730f0405c2c9dbefac46f9e601cc3f06e9713973fd" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004c9c2115290d008b45fb65fad0f602389298c25420b775019d42b62c3ce8a96b73877d25a8080dc02d987ca730f0405c2c9dbefac46f9e601cc3f06e9713973fd", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEycIRUpDQCLRftl+tD2AjiSmMJUIL\nd1AZ1Ctiw86Klrc4d9JagIDcAtmHynMPBAXCydvvrEb55gHMPwbpcTlz/Q==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 147, - "comment" : "edge case for u1", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbc4024761cd2ffd43dfdb17d0fed112b988977055cd3a8e54971eba9cda5ca71", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "Xsoe9MKH3dxmuLzPG4jookwAGJYvPF5--oO8Gl_2Az4", - "y" : "XnnEyywkW4xFq9zoqOTadY2SpgfDLNQH7K7yLxyTSnE" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "045eca1ef4c287dddc66b8bccf1b88e8a24c0018962f3c5e7efa83bc1a5ff6033e5e79c4cb2c245b8c45abdce8a8e4da758d92a607c32cd407ecaef22f1c934a71", - "wx" : "5eca1ef4c287dddc66b8bccf1b88e8a24c0018962f3c5e7efa83bc1a5ff6033e", - "wy" : "5e79c4cb2c245b8c45abdce8a8e4da758d92a607c32cd407ecaef22f1c934a71" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200045eca1ef4c287dddc66b8bccf1b88e8a24c0018962f3c5e7efa83bc1a5ff6033e5e79c4cb2c245b8c45abdce8a8e4da758d92a607c32cd407ecaef22f1c934a71", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEXsoe9MKH3dxmuLzPG4jookwAGJYv\nPF5++oO8Gl/2Az5eecTLLCRbjEWr3Oio5Np1jZKmB8Ms1AfsrvIvHJNKcQ==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 148, - "comment" : "edge case for u1", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd788048ed39a5ffa77bfb62fa1fda2257742bf35d128fb3459f2a0c909ee86f91", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "XKqgMOf98OSTa8erWpY1PgoB5BMMP4vyLUc-MXAppHo", - "y" : "3ratxGL3BY8qINNx6XAiVOmyAWQgBbPO2pJrQrF4vvk" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "045caaa030e7fdf0e4936bc7ab5a96353e0a01e4130c3f8bf22d473e317029a47adeb6adc462f7058f2a20d371e9702254e9b201642005b3ceda926b42b178bef9", - "wx" : "5caaa030e7fdf0e4936bc7ab5a96353e0a01e4130c3f8bf22d473e317029a47a", - "wy" : "00deb6adc462f7058f2a20d371e9702254e9b201642005b3ceda926b42b178bef9" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200045caaa030e7fdf0e4936bc7ab5a96353e0a01e4130c3f8bf22d473e317029a47adeb6adc462f7058f2a20d371e9702254e9b201642005b3ceda926b42b178bef9", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEXKqgMOf98OSTa8erWpY1PgoB5BMM\nP4vyLUc+MXAppHretq3EYvcFjyog03HpcCJU6bIBZCAFs87akmtCsXi++Q==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 149, - "comment" : "edge case for u1", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd476d9131fd381bd917d0fed112bc9e0a5924b5ed5b11167edd8b23582b3cb15e", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "wv0gusBuVVu4rAzmnrHqIPg6H8NQHIpmRpsaMfYZsJg", - "y" : "YjcFB3n1K2Fb17jXaiX8lcou0yUlx18n_8h6w5fmy68" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04c2fd20bac06e555bb8ac0ce69eb1ea20f83a1fc3501c8a66469b1a31f619b0986237050779f52b615bd7b8d76a25fc95ca2ed32525c75f27ffc87ac397e6cbaf", - "wx" : "00c2fd20bac06e555bb8ac0ce69eb1ea20f83a1fc3501c8a66469b1a31f619b098", - "wy" : "6237050779f52b615bd7b8d76a25fc95ca2ed32525c75f27ffc87ac397e6cbaf" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004c2fd20bac06e555bb8ac0ce69eb1ea20f83a1fc3501c8a66469b1a31f619b0986237050779f52b615bd7b8d76a25fc95ca2ed32525c75f27ffc87ac397e6cbaf", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEwv0gusBuVVu4rAzmnrHqIPg6H8NQ\nHIpmRpsaMfYZsJhiNwUHefUrYVvXuNdqJfyVyi7TJSXHXyf/yHrDl+bLrw==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 150, - "comment" : "edge case for u1", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd8374253e3e21bd154448d0a8f640fe46fafa8b19ce78d538f6cc0a19662d3601", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "P9ahyn93-zsLvnJsNyAQBoQm4R6mrnjOF77a5LuobO0", - "y" : "A85VFkBr-M-quHRerBzWkBitb1C1Rhhy3fxW4Ns8j_Q" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "043fd6a1ca7f77fb3b0bbe726c372010068426e11ea6ae78ce17bedae4bba86ced03ce5516406bf8cfaab8745eac1cd69018ad6f50b5461872ddfc56e0db3c8ff4", - "wx" : "3fd6a1ca7f77fb3b0bbe726c372010068426e11ea6ae78ce17bedae4bba86ced", - "wy" : "03ce5516406bf8cfaab8745eac1cd69018ad6f50b5461872ddfc56e0db3c8ff4" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200043fd6a1ca7f77fb3b0bbe726c372010068426e11ea6ae78ce17bedae4bba86ced03ce5516406bf8cfaab8745eac1cd69018ad6f50b5461872ddfc56e0db3c8ff4", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEP9ahyn93+zsLvnJsNyAQBoQm4R6m\nrnjOF77a5LuobO0DzlUWQGv4z6q4dF6sHNaQGK1vULVGGHLd/Fbg2zyP9A==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 151, - "comment" : "edge case for u1", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd357cfd3be4d01d413c5b9ede36cba5452c11ee7fe14879e749ae6a2d897a52d6", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "nLjlHielrjtiSmDW3DJzTkmJ2yDpvKPt4e33sIaRERQ", - "y" : "tMEEqzxnfks21lVuitX1I0EKGfLid6qJX8VzIrRCdUQ" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "049cb8e51e27a5ae3b624a60d6dc32734e4989db20e9bca3ede1edf7b086911114b4c104ab3c677e4b36d6556e8ad5f523410a19f2e277aa895fc57322b4427544", - "wx" : "009cb8e51e27a5ae3b624a60d6dc32734e4989db20e9bca3ede1edf7b086911114", - "wy" : "00b4c104ab3c677e4b36d6556e8ad5f523410a19f2e277aa895fc57322b4427544" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200049cb8e51e27a5ae3b624a60d6dc32734e4989db20e9bca3ede1edf7b086911114b4c104ab3c677e4b36d6556e8ad5f523410a19f2e277aa895fc57322b4427544", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEnLjlHielrjtiSmDW3DJzTkmJ2yDp\nvKPt4e33sIaRERS0wQSrPGd+SzbWVW6K1fUjQQoZ8uJ3qolfxXMitEJ1RA==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 152, - "comment" : "edge case for u1", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd29798c5c0ee287d4a5e8e6b799fd86b8df5225298e6ffc807cd2f2bc27a0a6d8", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "o-UsFW3K8QUCYgt5VbwrQLx47z1WnhIjwmJRLY9JYCo", - "y" : "SiA58xwQlwJK08yG5XMh3gMjVUY0hhZM8ZKUSXffFH8" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04a3e52c156dcaf10502620b7955bc2b40bc78ef3d569e1223c262512d8f49602a4a2039f31c1097024ad3cc86e57321de032355463486164cf192944977df147f", - "wx" : "00a3e52c156dcaf10502620b7955bc2b40bc78ef3d569e1223c262512d8f49602a", - "wy" : "4a2039f31c1097024ad3cc86e57321de032355463486164cf192944977df147f" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004a3e52c156dcaf10502620b7955bc2b40bc78ef3d569e1223c262512d8f49602a4a2039f31c1097024ad3cc86e57321de032355463486164cf192944977df147f", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEo+UsFW3K8QUCYgt5VbwrQLx47z1W\nnhIjwmJRLY9JYCpKIDnzHBCXAkrTzIblcyHeAyNVRjSGFkzxkpRJd98Ufw==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 153, - "comment" : "edge case for u1", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd0b70f22c781092452dca1a5711fa3a5a1f72add1bf52c2ff7cae4820b30078dd", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "8Zt4kocg1b7o5nD7kAEPsVw3v5G1ilFXw_PAWbJlXog", - "y" : "z3AeyWL7ShHc8nP13DV-WEaFYMfP65QtB0q9QykmBQk" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04f19b78928720d5bee8e670fb90010fb15c37bf91b58a5157c3f3c059b2655e88cf701ec962fb4a11dcf273f5dc357e58468560c7cfeb942d074abd4329260509", - "wx" : "00f19b78928720d5bee8e670fb90010fb15c37bf91b58a5157c3f3c059b2655e88", - "wy" : "00cf701ec962fb4a11dcf273f5dc357e58468560c7cfeb942d074abd4329260509" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004f19b78928720d5bee8e670fb90010fb15c37bf91b58a5157c3f3c059b2655e88cf701ec962fb4a11dcf273f5dc357e58468560c7cfeb942d074abd4329260509", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8Zt4kocg1b7o5nD7kAEPsVw3v5G1\nilFXw/PAWbJlXojPcB7JYvtKEdzyc/XcNX5YRoVgx8/rlC0HSr1DKSYFCQ==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 154, - "comment" : "edge case for u1", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd16e1e458f021248a5b9434ae23f474b43ee55ba37ea585fef95c90416600f1ba", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "g6dERZ7N-wGlz1KyegW7czdILSQvI117TLiTRVRckKg", - "y" : "wF1JM3uWSYEyh96f_pA1X9kF3188MpRYKBIfN8xQ3m4" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "0483a744459ecdfb01a5cf52b27a05bb7337482d242f235d7b4cb89345545c90a8c05d49337b9649813287de9ffe90355fd905df5f3c32945828121f37cc50de6e", - "wx" : "0083a744459ecdfb01a5cf52b27a05bb7337482d242f235d7b4cb89345545c90a8", - "wy" : "00c05d49337b9649813287de9ffe90355fd905df5f3c32945828121f37cc50de6e" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d0301070342000483a744459ecdfb01a5cf52b27a05bb7337482d242f235d7b4cb89345545c90a8c05d49337b9649813287de9ffe90355fd905df5f3c32945828121f37cc50de6e", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEg6dERZ7N+wGlz1KyegW7czdILSQv\nI117TLiTRVRckKjAXUkze5ZJgTKH3p/+kDVf2QXfXzwylFgoEh83zFDebg==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 155, - "comment" : "edge case for u1", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd2252d6856831b6cf895e4f0535eeaf0e5e5809753df848fe760ad86219016a97", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "3RPGs0xWmC3a4STwOd_SP0sZu-iM7o5SiuUeXW86Idc", - "y" : "v61MLm8mP-XrWcqXTQOfwOTDNFaS-1Mgva5L07QqRf8" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04dd13c6b34c56982ddae124f039dfd23f4b19bbe88cee8e528ae51e5d6f3a21d7bfad4c2e6f263fe5eb59ca974d039fc0e4c3345692fb5320bdae4bd3b42a45ff", - "wx" : "00dd13c6b34c56982ddae124f039dfd23f4b19bbe88cee8e528ae51e5d6f3a21d7", - "wy" : "00bfad4c2e6f263fe5eb59ca974d039fc0e4c3345692fb5320bdae4bd3b42a45ff" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004dd13c6b34c56982ddae124f039dfd23f4b19bbe88cee8e528ae51e5d6f3a21d7bfad4c2e6f263fe5eb59ca974d039fc0e4c3345692fb5320bdae4bd3b42a45ff", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE3RPGs0xWmC3a4STwOd/SP0sZu+iM\n7o5SiuUeXW86Ide/rUwubyY/5etZypdNA5/A5MM0VpL7UyC9rkvTtCpF/w==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 156, - "comment" : "edge case for u1", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd81ffe55f178da695b28c86d8b406b15dab1a9e39661a3ae017fbe390ac0972c3", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "Z-b2Wc3ehpovZfCU6U5bTfrWNrv5UZL-7tAbDz3rdGA", - "y" : "o34KUfJYt661Hf5ZL1z9VoW75YcSyNkjPGKIZDfDi6A" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "0467e6f659cdde869a2f65f094e94e5b4dfad636bbf95192feeed01b0f3deb7460a37e0a51f258b7aeb51dfe592f5cfd5685bbe58712c8d9233c62886437c38ba0", - "wx" : "67e6f659cdde869a2f65f094e94e5b4dfad636bbf95192feeed01b0f3deb7460", - "wy" : "00a37e0a51f258b7aeb51dfe592f5cfd5685bbe58712c8d9233c62886437c38ba0" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d0301070342000467e6f659cdde869a2f65f094e94e5b4dfad636bbf95192feeed01b0f3deb7460a37e0a51f258b7aeb51dfe592f5cfd5685bbe58712c8d9233c62886437c38ba0", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZ+b2Wc3ehpovZfCU6U5bTfrWNrv5\nUZL+7tAbDz3rdGCjfgpR8li3rrUd/lkvXP1WhbvlhxLI2SM8YohkN8OLoA==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 157, - "comment" : "edge case for u2", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd7fffffffaaaaaaaaffffffffffffffffe9a2538f37b28a2c513dee40fecbb71a", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "LrZBJQWuwFxlRfApkyCH5JDQVRHo7B9Zlhe7Nn-eyq8", - "y" : "gF9R78xIA0A_mxrgEkiQ8GpD_tzdsxgw9maa8pKJXLA" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "042eb6412505aec05c6545f029932087e490d05511e8ec1f599617bb367f9ecaaf805f51efcc4803403f9b1ae0124890f06a43fedcddb31830f6669af292895cb0", - "wx" : "2eb6412505aec05c6545f029932087e490d05511e8ec1f599617bb367f9ecaaf", - "wy" : "00805f51efcc4803403f9b1ae0124890f06a43fedcddb31830f6669af292895cb0" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200042eb6412505aec05c6545f029932087e490d05511e8ec1f599617bb367f9ecaaf805f51efcc4803403f9b1ae0124890f06a43fedcddb31830f6669af292895cb0", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAELrZBJQWuwFxlRfApkyCH5JDQVRHo\n7B9Zlhe7Nn+eyq+AX1HvzEgDQD+bGuASSJDwakP+3N2zGDD2ZprykolcsA==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 158, - "comment" : "edge case for u2", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdb62f26b5f2a2b26f6de86d42ad8a13da3ab3cccd0459b201de009e526adf21f2", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "hNtkWGjqs146n9gOBW4uhVQ146a2jXWlCoVGJf4NfzU", - "y" : "bSWJrGVe3JoR7z4HXt3amr-S5yFxVw73v0Oi7jkzjP4" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "0484db645868eab35e3a9fd80e056e2e855435e3a6b68d75a50a854625fe0d7f356d2589ac655edc9a11ef3e075eddda9abf92e72171570ef7bf43a2ee39338cfe", - "wx" : "0084db645868eab35e3a9fd80e056e2e855435e3a6b68d75a50a854625fe0d7f35", - "wy" : "6d2589ac655edc9a11ef3e075eddda9abf92e72171570ef7bf43a2ee39338cfe" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d0301070342000484db645868eab35e3a9fd80e056e2e855435e3a6b68d75a50a854625fe0d7f356d2589ac655edc9a11ef3e075eddda9abf92e72171570ef7bf43a2ee39338cfe", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEhNtkWGjqs146n9gOBW4uhVQ146a2\njXWlCoVGJf4NfzVtJYmsZV7cmhHvPgde3dqav5LnIXFXDve/Q6LuOTOM/g==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 159, - "comment" : "edge case for u2", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbb1d9ac949dd748cd02bbbe749bd351cd57b38bb61403d700686aa7b4c90851e", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "kbnkfFYnhmLXXAmDsiyo6mqlBZt6L_djfrKXXjhq1mM", - "y" : "SaqP8oPQ93wY1tEdwGIWX9E8PAMQZ5wUCDAqFoVOz70" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "0491b9e47c56278662d75c0983b22ca8ea6aa5059b7a2ff7637eb2975e386ad66349aa8ff283d0f77c18d6d11dc062165fd13c3c0310679c1408302a16854ecfbd", - "wx" : "0091b9e47c56278662d75c0983b22ca8ea6aa5059b7a2ff7637eb2975e386ad663", - "wy" : "49aa8ff283d0f77c18d6d11dc062165fd13c3c0310679c1408302a16854ecfbd" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d0301070342000491b9e47c56278662d75c0983b22ca8ea6aa5059b7a2ff7637eb2975e386ad66349aa8ff283d0f77c18d6d11dc062165fd13c3c0310679c1408302a16854ecfbd", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEkbnkfFYnhmLXXAmDsiyo6mqlBZt6\nL/djfrKXXjhq1mNJqo/yg9D3fBjW0R3AYhZf0Tw8AxBnnBQIMCoWhU7PvQ==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 160, - "comment" : "edge case for u2", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd66755a00638cdaec1c732513ca0234ece52545dac11f816e818f725b4f60aaf2", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "8-wvE8rwTQGStH-0xTEfttTcawqegC5TJ_fsXujkg00", - "y" : "-X4-Rot9Dbhn1uz-geKw-VMd-H79tHwTOKwyH-_lpDI" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04f3ec2f13caf04d0192b47fb4c5311fb6d4dc6b0a9e802e5327f7ec5ee8e4834df97e3e468b7d0db867d6ecfe81e2b0f9531df87efdb47c1338ac321fefe5a432", - "wx" : "00f3ec2f13caf04d0192b47fb4c5311fb6d4dc6b0a9e802e5327f7ec5ee8e4834d", - "wy" : "00f97e3e468b7d0db867d6ecfe81e2b0f9531df87efdb47c1338ac321fefe5a432" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004f3ec2f13caf04d0192b47fb4c5311fb6d4dc6b0a9e802e5327f7ec5ee8e4834df97e3e468b7d0db867d6ecfe81e2b0f9531df87efdb47c1338ac321fefe5a432", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8+wvE8rwTQGStH+0xTEfttTcawqe\ngC5TJ/fsXujkg035fj5Gi30NuGfW7P6B4rD5Ux34fv20fBM4rDIf7+WkMg==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 161, - "comment" : "edge case for u2", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd55a00c9fcdaebb6032513ca0234ecfffe98ebe492fdf02e48ca48e982beb3669", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "2SsgCu_Ktqx9r9msry-hCzGAI1uPRrRQPkaTxnD8zIg", - "y" : "XvLzrr9bMXR1M2JWdo98Ge-3NS0n5MzK3IW2uKuSLHI" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04d92b200aefcab6ac7dafd9acaf2fa10b3180235b8f46b4503e4693c670fccc885ef2f3aebf5b317475336256768f7c19efb7352d27e4cccadc85b6b8ab922c72", - "wx" : "00d92b200aefcab6ac7dafd9acaf2fa10b3180235b8f46b4503e4693c670fccc88", - "wy" : "5ef2f3aebf5b317475336256768f7c19efb7352d27e4cccadc85b6b8ab922c72" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004d92b200aefcab6ac7dafd9acaf2fa10b3180235b8f46b4503e4693c670fccc885ef2f3aebf5b317475336256768f7c19efb7352d27e4cccadc85b6b8ab922c72", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2SsgCu/Ktqx9r9msry+hCzGAI1uP\nRrRQPkaTxnD8zIhe8vOuv1sxdHUzYlZ2j3wZ77c1LSfkzMrchba4q5Iscg==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 162, - "comment" : "edge case for u2", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdab40193f9b5d76c064a27940469d9fffd31d7c925fbe05c919491d3057d66cd2", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "Cog2HrkuzKJiWzjl-Yu6u5a_F5s9dvxIFAo7zYgVI80", - "y" : "5r31YDP4SlBUA1WXN12QhmqiyWuGpBzPbt6_RymK1Ik" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "040a88361eb92ecca2625b38e5f98bbabb96bf179b3d76fc48140a3bcd881523cde6bdf56033f84a5054035597375d90866aa2c96b86a41ccf6edebf47298ad489", - "wx" : "0a88361eb92ecca2625b38e5f98bbabb96bf179b3d76fc48140a3bcd881523cd", - "wy" : "00e6bdf56033f84a5054035597375d90866aa2c96b86a41ccf6edebf47298ad489" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200040a88361eb92ecca2625b38e5f98bbabb96bf179b3d76fc48140a3bcd881523cde6bdf56033f84a5054035597375d90866aa2c96b86a41ccf6edebf47298ad489", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAECog2HrkuzKJiWzjl+Yu6u5a/F5s9\ndvxIFAo7zYgVI83mvfVgM/hKUFQDVZc3XZCGaqLJa4akHM9u3r9HKYrUiQ==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 163, - "comment" : "edge case for u2", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdca0234ebb5fdcb13ca0234ecffffffffcb0dadbbc7f549f8a26b4408d0dc8600", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "0PsXzNj6_oJ-DBr8XY2ANm4rIOfxSlY6K6UEadhDdeg", - "y" : "aGEladOeK7n1VDVVZGRt6ZrGAsxjSc-MHiNqfedjfZM" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04d0fb17ccd8fafe827e0c1afc5d8d80366e2b20e7f14a563a2ba50469d84375e868612569d39e2bb9f554355564646de99ac602cc6349cf8c1e236a7de7637d93", - "wx" : "00d0fb17ccd8fafe827e0c1afc5d8d80366e2b20e7f14a563a2ba50469d84375e8", - "wy" : "68612569d39e2bb9f554355564646de99ac602cc6349cf8c1e236a7de7637d93" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004d0fb17ccd8fafe827e0c1afc5d8d80366e2b20e7f14a563a2ba50469d84375e868612569d39e2bb9f554355564646de99ac602cc6349cf8c1e236a7de7637d93", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE0PsXzNj6/oJ+DBr8XY2ANm4rIOfx\nSlY6K6UEadhDdehoYSVp054rufVUNVVkZG3pmsYCzGNJz4weI2p952N9kw==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 164, - "comment" : "edge case for u2", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbfffffff3ea3677e082b9310572620ae19933a9e65b285598711c77298815ad3", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "g28zu8HcDT06u87w2R8R4qxBgQdsmvCiKx5DCdPtsnY", - "y" : "mrRD_2-QHjDHc4Z1gpl8K-wrDLgSDXYCNvOpW76IH3U" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04836f33bbc1dc0d3d3abbcef0d91f11e2ac4181076c9af0a22b1e4309d3edb2769ab443ff6f901e30c773867582997c2bec2b0cb8120d760236f3a95bbe881f75", - "wx" : "00836f33bbc1dc0d3d3abbcef0d91f11e2ac4181076c9af0a22b1e4309d3edb276", - "wy" : "009ab443ff6f901e30c773867582997c2bec2b0cb8120d760236f3a95bbe881f75" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004836f33bbc1dc0d3d3abbcef0d91f11e2ac4181076c9af0a22b1e4309d3edb2769ab443ff6f901e30c773867582997c2bec2b0cb8120d760236f3a95bbe881f75", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEg28zu8HcDT06u87w2R8R4qxBgQds\nmvCiKx5DCdPtsnaatEP/b5AeMMdzhnWCmXwr7CsMuBINdgI286lbvogfdQ==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 165, - "comment" : "edge case for u2", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd266666663bbbbbbbe6666666666666665b37902e023fab7c8f055d86e5cc41f4", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "kvmfvpc-1KKZcZuu5LQydBI3A03sjXK6UQPLM-Vf7rg", - "y" : "Az3Q6RE0xzQXSInz688behrAV2cokoDuenlM69bmlpc" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "0492f99fbe973ed4a299719baee4b432741237034dec8d72ba5103cb33e55feeb8033dd0e91134c734174889f3ebcf1b7a1ac05767289280ee7a794cebd6e69697", - "wx" : "0092f99fbe973ed4a299719baee4b432741237034dec8d72ba5103cb33e55feeb8", - "wy" : "033dd0e91134c734174889f3ebcf1b7a1ac05767289280ee7a794cebd6e69697" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d0301070342000492f99fbe973ed4a299719baee4b432741237034dec8d72ba5103cb33e55feeb8033dd0e91134c734174889f3ebcf1b7a1ac05767289280ee7a794cebd6e69697", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEkvmfvpc+1KKZcZuu5LQydBI3A03s\njXK6UQPLM+Vf7rgDPdDpETTHNBdIifPrzxt6GsBXZyiSgO56eUzr1uaWlw==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 166, - "comment" : "edge case for u2", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbfffffff36db6db7a492492492492492146c573f4c6dfc8d08a443e258970b09", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "01uljaMBl9N45hjsD6fi4tEs_9c-u7IEnRMLukNK8J4", - "y" : "_4OYbmh15B6kMrdYWkmzpsd8uzxHkZ-OgodMeUY1wdI" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04d35ba58da30197d378e618ec0fa7e2e2d12cffd73ebbb2049d130bba434af09eff83986e6875e41ea432b7585a49b3a6c77cbb3c47919f8e82874c794635c1d2", - "wx" : "00d35ba58da30197d378e618ec0fa7e2e2d12cffd73ebbb2049d130bba434af09e", - "wy" : "00ff83986e6875e41ea432b7585a49b3a6c77cbb3c47919f8e82874c794635c1d2" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004d35ba58da30197d378e618ec0fa7e2e2d12cffd73ebbb2049d130bba434af09eff83986e6875e41ea432b7585a49b3a6c77cbb3c47919f8e82874c794635c1d2", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE01uljaMBl9N45hjsD6fi4tEs/9c+\nu7IEnRMLukNK8J7/g5huaHXkHqQyt1haSbOmx3y7PEeRn46Ch0x5RjXB0g==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 167, - "comment" : "edge case for u2", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbfffffff2aaaaaab7fffffffffffffffc815d0e60b3e596ecb1ad3a27cfd49c4", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "hlHOSQ8bRtc_P_R1FJvikTZpczSlGdfdqwclyNB5MiQ", - "y" : "4RxlvYypLci8mugpEfC1J1HOId2QA65gkAvYJfWQzCg" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "048651ce490f1b46d73f3ff475149be29136697334a519d7ddab0725c8d0793224e11c65bd8ca92dc8bc9ae82911f0b52751ce21dd9003ae60900bd825f590cc28", - "wx" : "008651ce490f1b46d73f3ff475149be29136697334a519d7ddab0725c8d0793224", - "wy" : "00e11c65bd8ca92dc8bc9ae82911f0b52751ce21dd9003ae60900bd825f590cc28" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200048651ce490f1b46d73f3ff475149be29136697334a519d7ddab0725c8d0793224e11c65bd8ca92dc8bc9ae82911f0b52751ce21dd9003ae60900bd825f590cc28", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEhlHOSQ8bRtc/P/R1FJvikTZpczSl\nGdfdqwclyNB5MiThHGW9jKktyLya6CkR8LUnUc4h3ZADrmCQC9gl9ZDMKA==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 168, - "comment" : "edge case for u2", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd7fffffff55555555ffffffffffffffffd344a71e6f651458a27bdc81fd976e37", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "bY4bEsgxoNqHlWUP-V8QHtkh2eL3KxWxzaypgmuc_G0", - "y" : "721j4rxcCJVwOUpLyfiS1ebHpqY3sgRppYwQatSGvzc" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "046d8e1b12c831a0da8795650ff95f101ed921d9e2f72b15b1cdaca9826b9cfc6def6d63e2bc5c089570394a4bc9f892d5e6c7a6a637b20469a58c106ad486bf37", - "wx" : "6d8e1b12c831a0da8795650ff95f101ed921d9e2f72b15b1cdaca9826b9cfc6d", - "wy" : "00ef6d63e2bc5c089570394a4bc9f892d5e6c7a6a637b20469a58c106ad486bf37" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200046d8e1b12c831a0da8795650ff95f101ed921d9e2f72b15b1cdaca9826b9cfc6def6d63e2bc5c089570394a4bc9f892d5e6c7a6a637b20469a58c106ad486bf37", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEbY4bEsgxoNqHlWUP+V8QHtkh2eL3\nKxWxzaypgmuc/G3vbWPivFwIlXA5SkvJ+JLV5sempjeyBGmljBBq1Ia/Nw==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 169, - "comment" : "edge case for u2", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd3fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192aa", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "CuWAuukztO8pl8vbsJIjKMqaQQ9ieg99_yTLTZIOFUI", - "y" : "iRHn-Mw2WoqI64FCGjYczCuZ4wnY3Nmpi6g8OUnYk-M" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "040ae580bae933b4ef2997cbdbb0922328ca9a410f627a0f7dff24cb4d920e15428911e7f8cc365a8a88eb81421a361ccc2b99e309d8dcd9a98ba83c3949d893e3", - "wx" : "0ae580bae933b4ef2997cbdbb0922328ca9a410f627a0f7dff24cb4d920e1542", - "wy" : "008911e7f8cc365a8a88eb81421a361ccc2b99e309d8dcd9a98ba83c3949d893e3" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200040ae580bae933b4ef2997cbdbb0922328ca9a410f627a0f7dff24cb4d920e15428911e7f8cc365a8a88eb81421a361ccc2b99e309d8dcd9a98ba83c3949d893e3", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAECuWAuukztO8pl8vbsJIjKMqaQQ9i\neg99/yTLTZIOFUKJEef4zDZaiojrgUIaNhzMK5njCdjc2amLqDw5SdiT4w==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 170, - "comment" : "edge case for u2", - "msg" : "313233343030", - "sig" : "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd5d8ecd64a4eeba466815ddf3a4de9a8e6abd9c5db0a01eb80343553da648428f", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "W4Ev1SGq-mmDWoSczm-962mDtELSRE_nDhNMAn_EaWM", - "y" : "g4pA8qNgkukATpLY2UDPVjhVDOZyzouNThXrpUmSSek" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "045b812fd521aafa69835a849cce6fbdeb6983b442d2444fe70e134c027fc46963838a40f2a36092e9004e92d8d940cf5638550ce672ce8b8d4e15eba5499249e9", - "wx" : "5b812fd521aafa69835a849cce6fbdeb6983b442d2444fe70e134c027fc46963", - "wy" : "00838a40f2a36092e9004e92d8d940cf5638550ce672ce8b8d4e15eba5499249e9" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200045b812fd521aafa69835a849cce6fbdeb6983b442d2444fe70e134c027fc46963838a40f2a36092e9004e92d8d940cf5638550ce672ce8b8d4e15eba5499249e9", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEW4Ev1SGq+mmDWoSczm+962mDtELS\nRE/nDhNMAn/EaWODikDyo2CS6QBOktjZQM9WOFUM5nLOi41OFeulSZJJ6Q==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 171, - "comment" : "point duplication during verification", - "msg" : "313233343030", - "sig" : "6f2347cab7dd76858fe0555ac3bc99048c4aacafdfb6bcbe05ea6c42c4934569bb726660235793aa9957a61e76e00c2c435109cf9a15dd624d53f4301047856b", - "result" : "valid", - "flags" : [ - "PointDuplication" - ] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "W4Ev1SGq-mmDWoSczm-962mDtELSRE_nDhNMAn_EaWM", - "y" : "fHW_DFyfbRf_sW0nJr8wqceq8xqNMXRyseoUWrZtthY" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "045b812fd521aafa69835a849cce6fbdeb6983b442d2444fe70e134c027fc469637c75bf0c5c9f6d17ffb16d2726bf30a9c7aaf31a8d317472b1ea145ab66db616", - "wx" : "5b812fd521aafa69835a849cce6fbdeb6983b442d2444fe70e134c027fc46963", - "wy" : "7c75bf0c5c9f6d17ffb16d2726bf30a9c7aaf31a8d317472b1ea145ab66db616" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200045b812fd521aafa69835a849cce6fbdeb6983b442d2444fe70e134c027fc469637c75bf0c5c9f6d17ffb16d2726bf30a9c7aaf31a8d317472b1ea145ab66db616", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEW4Ev1SGq+mmDWoSczm+962mDtELS\nRE/nDhNMAn/EaWN8db8MXJ9tF/+xbScmvzCpx6rzGo0xdHKx6hRatm22Fg==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 172, - "comment" : "duplication bug", - "msg" : "313233343030", - "sig" : "6f2347cab7dd76858fe0555ac3bc99048c4aacafdfb6bcbe05ea6c42c4934569bb726660235793aa9957a61e76e00c2c435109cf9a15dd624d53f4301047856b", - "result" : "invalid", - "flags" : [ - "PointDuplication" - ] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "at2oK5AmGw8xn6oNh4ZlprbaSX8JyQMXYiLDSs_vcqY", - "y" : "R-b1DcxArV2bWfdgK7Ii-tcaQb9eH530lZo2TGLkiNk" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "046adda82b90261b0f319faa0d878665a6b6da497f09c903176222c34acfef72a647e6f50dcc40ad5d9b59f7602bb222fad71a41bf5e1f9df4959a364c62e488d9", - "wx" : "6adda82b90261b0f319faa0d878665a6b6da497f09c903176222c34acfef72a6", - "wy" : "47e6f50dcc40ad5d9b59f7602bb222fad71a41bf5e1f9df4959a364c62e488d9" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200046adda82b90261b0f319faa0d878665a6b6da497f09c903176222c34acfef72a647e6f50dcc40ad5d9b59f7602bb222fad71a41bf5e1f9df4959a364c62e488d9", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEat2oK5AmGw8xn6oNh4ZlprbaSX8J\nyQMXYiLDSs/vcqZH5vUNzECtXZtZ92ArsiL61xpBv14fnfSVmjZMYuSI2Q==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 173, - "comment" : "point with x-coordinate 0", - "msg" : "313233343030", - "sig" : "0000000000000000000000000000000000000000000000000000000000000001555555550000000055555555555555553ef7a8e48d07df81a693439654210c70", - "result" : "invalid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "L8oNCkeRTed-1W5-zMMnamARIMbfAGnIJcj2oByfOCA", - "y" : "ZfNFCh0XxrJJiaOb6xx97PyoOE-9wpRBjl2Aezxu194" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "042fca0d0a47914de77ed56e7eccc3276a601120c6df0069c825c8f6a01c9f382065f3450a1d17c6b24989a39beb1c7decfca8384fbdc294418e5d807b3c6ed7de", - "wx" : "2fca0d0a47914de77ed56e7eccc3276a601120c6df0069c825c8f6a01c9f3820", - "wy" : "65f3450a1d17c6b24989a39beb1c7decfca8384fbdc294418e5d807b3c6ed7de" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200042fca0d0a47914de77ed56e7eccc3276a601120c6df0069c825c8f6a01c9f382065f3450a1d17c6b24989a39beb1c7decfca8384fbdc294418e5d807b3c6ed7de", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEL8oNCkeRTed+1W5+zMMnamARIMbf\nAGnIJcj2oByfOCBl80UKHRfGskmJo5vrHH3s/Kg4T73ClEGOXYB7PG7X3g==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 174, - "comment" : "point with x-coordinate 0", - "msg" : "313233343030", - "sig" : "010000000000000000000000000000000000000000000000000000000000000000003333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aa9", - "result" : "invalid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "3YbTtfShPoURCDt4ACCBxT_0Z_EevZilGmM9t2Zl0lA", - "y" : "RdXIIAyJ8voQ2Ek0kibSHY367W_41cs-G34XR068GPc" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04dd86d3b5f4a13e8511083b78002081c53ff467f11ebd98a51a633db76665d25045d5c8200c89f2fa10d849349226d21d8dfaed6ff8d5cb3e1b7e17474ebc18f7", - "wx" : "00dd86d3b5f4a13e8511083b78002081c53ff467f11ebd98a51a633db76665d250", - "wy" : "45d5c8200c89f2fa10d849349226d21d8dfaed6ff8d5cb3e1b7e17474ebc18f7" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004dd86d3b5f4a13e8511083b78002081c53ff467f11ebd98a51a633db76665d25045d5c8200c89f2fa10d849349226d21d8dfaed6ff8d5cb3e1b7e17474ebc18f7", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE3YbTtfShPoURCDt4ACCBxT/0Z/Ee\nvZilGmM9t2Zl0lBF1cggDIny+hDYSTSSJtIdjfrtb/jVyz4bfhdHTrwY9w==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 175, - "comment" : "comparison with point at infinity ", - "msg" : "313233343030", - "sig" : "555555550000000055555555555555553ef7a8e48d07df81a693439654210c703333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aa9", - "result" : "invalid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "T-pVsyyzKsoMEsTNCr-05ksPWlFuV4wBZZGpP1oPvMU", - "y" : "19P9ELK-ZoxUeyEva7FMiPD-zTiopLLHhe075izksoA" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "044fea55b32cb32aca0c12c4cd0abfb4e64b0f5a516e578c016591a93f5a0fbcc5d7d3fd10b2be668c547b212f6bb14c88f0fecd38a8a4b2c785ed3be62ce4b280", - "wx" : "4fea55b32cb32aca0c12c4cd0abfb4e64b0f5a516e578c016591a93f5a0fbcc5", - "wy" : "00d7d3fd10b2be668c547b212f6bb14c88f0fecd38a8a4b2c785ed3be62ce4b280" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200044fea55b32cb32aca0c12c4cd0abfb4e64b0f5a516e578c016591a93f5a0fbcc5d7d3fd10b2be668c547b212f6bb14c88f0fecd38a8a4b2c785ed3be62ce4b280", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAET+pVsyyzKsoMEsTNCr+05ksPWlFu\nV4wBZZGpP1oPvMXX0/0Qsr5mjFR7IS9rsUyI8P7NOKiksseF7TvmLOSygA==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 176, - "comment" : "extreme value for k and edgecase s", - "msg" : "313233343030", - "sig" : "7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978555555550000000055555555555555553ef7a8e48d07df81a693439654210c70", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "xqdxUnAkIneSFwpvju5zW_Mrf5ivZp6tKZgC4y18MQc", - "y" : "vDtLXmWriHu9NDVys-VhkmH-Ogc-L_14QS9yaGfbWJ4" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04c6a771527024227792170a6f8eee735bf32b7f98af669ead299802e32d7c3107bc3b4b5e65ab887bbd343572b3e5619261fe3a073e2ffd78412f726867db589e", - "wx" : "00c6a771527024227792170a6f8eee735bf32b7f98af669ead299802e32d7c3107", - "wy" : "00bc3b4b5e65ab887bbd343572b3e5619261fe3a073e2ffd78412f726867db589e" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004c6a771527024227792170a6f8eee735bf32b7f98af669ead299802e32d7c3107bc3b4b5e65ab887bbd343572b3e5619261fe3a073e2ffd78412f726867db589e", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAExqdxUnAkIneSFwpvju5zW/Mrf5iv\nZp6tKZgC4y18MQe8O0teZauIe700NXKz5WGSYf46Bz4v/XhBL3JoZ9tYng==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 177, - "comment" : "extreme value for k and s^-1", - "msg" : "313233343030", - "sig" : "7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978b6db6db6249249254924924924924924625bd7a09bec4ca81bcdd9f8fd6b63cc", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "hRwrutCOVOx6mvmfSfA2RNbsbVmyB_7JjehafRW5Vu8", - "y" : "zumWAoMEUHVoS0EL6ND3SUuRqiN59gcnMZ8Q3esP6dY" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04851c2bbad08e54ec7a9af99f49f03644d6ec6d59b207fec98de85a7d15b956efcee9960283045075684b410be8d0f7494b91aa2379f60727319f10ddeb0fe9d6", - "wx" : "00851c2bbad08e54ec7a9af99f49f03644d6ec6d59b207fec98de85a7d15b956ef", - "wy" : "00cee9960283045075684b410be8d0f7494b91aa2379f60727319f10ddeb0fe9d6" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004851c2bbad08e54ec7a9af99f49f03644d6ec6d59b207fec98de85a7d15b956efcee9960283045075684b410be8d0f7494b91aa2379f60727319f10ddeb0fe9d6", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEhRwrutCOVOx6mvmfSfA2RNbsbVmy\nB/7JjehafRW5Vu/O6ZYCgwRQdWhLQQvo0PdJS5GqI3n2BycxnxDd6w/p1g==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 178, - "comment" : "extreme value for k and s^-1", - "msg" : "313233343030", - "sig" : "7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978cccccccc00000000cccccccccccccccc971f2ef152794b9d8fc7d568c9e8eaa7", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "9kF8imcFhOOIZ2lJ5T2n_FWRH_aDGNG_MGEgWssZxI8", - "y" : "jyt0PfNK0PcmdKy3UFkpeEd5zZrJFsNmnq1DAmq21D8" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04f6417c8a670584e388676949e53da7fc55911ff68318d1bf3061205acb19c48f8f2b743df34ad0f72674acb7505929784779cd9ac916c3669ead43026ab6d43f", - "wx" : "00f6417c8a670584e388676949e53da7fc55911ff68318d1bf3061205acb19c48f", - "wy" : "008f2b743df34ad0f72674acb7505929784779cd9ac916c3669ead43026ab6d43f" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004f6417c8a670584e388676949e53da7fc55911ff68318d1bf3061205acb19c48f8f2b743df34ad0f72674acb7505929784779cd9ac916c3669ead43026ab6d43f", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9kF8imcFhOOIZ2lJ5T2n/FWRH/aD\nGNG/MGEgWssZxI+PK3Q980rQ9yZ0rLdQWSl4R3nNmskWw2aerUMCarbUPw==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 179, - "comment" : "extreme value for k and s^-1", - "msg" : "313233343030", - "sig" : "7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc476699783333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aaa", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "UBQhJ3vkWl7v7GxjmTDWNgMlZa9CDPM3P1V_qn-KBkM", - "y" : "hnPWy2B24c_Nx9_nOEyOXKwI10UB8q5uicrRldCqE3E" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04501421277be45a5eefec6c639930d636032565af420cf3373f557faa7f8a06438673d6cb6076e1cfcdc7dfe7384c8e5cac08d74501f2ae6e89cad195d0aa1371", - "wx" : "501421277be45a5eefec6c639930d636032565af420cf3373f557faa7f8a0643", - "wy" : "008673d6cb6076e1cfcdc7dfe7384c8e5cac08d74501f2ae6e89cad195d0aa1371" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004501421277be45a5eefec6c639930d636032565af420cf3373f557faa7f8a06438673d6cb6076e1cfcdc7dfe7384c8e5cac08d74501f2ae6e89cad195d0aa1371", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUBQhJ3vkWl7v7GxjmTDWNgMlZa9C\nDPM3P1V/qn+KBkOGc9bLYHbhz83H3+c4TI5crAjXRQHyrm6JytGV0KoTcQ==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 180, - "comment" : "extreme value for k and s^-1", - "msg" : "313233343030", - "sig" : "7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc4766997849249248db6db6dbb6db6db6db6db6db5a8b230d0b2b51dcd7ebf0c9fef7c185", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "DZNb-f_BFaUnc19ynKikyiPuAaSJSt8ONBWshOgIuzQ", - "y" : "MZWjdi_qKe04kSvZ6mxP3nDDBQiTpDdYUM5h2C66M8U" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "040d935bf9ffc115a527735f729ca8a4ca23ee01a4894adf0e3415ac84e808bb343195a3762fea29ed38912bd9ea6c4fde70c3050893a4375850ce61d82eba33c5", - "wx" : "0d935bf9ffc115a527735f729ca8a4ca23ee01a4894adf0e3415ac84e808bb34", - "wy" : "3195a3762fea29ed38912bd9ea6c4fde70c3050893a4375850ce61d82eba33c5" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200040d935bf9ffc115a527735f729ca8a4ca23ee01a4894adf0e3415ac84e808bb343195a3762fea29ed38912bd9ea6c4fde70c3050893a4375850ce61d82eba33c5", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEDZNb+f/BFaUnc19ynKikyiPuAaSJ\nSt8ONBWshOgIuzQxlaN2L+op7TiRK9nqbE/ecMMFCJOkN1hQzmHYLrozxQ==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 181, - "comment" : "extreme value for k", - "msg" : "313233343030", - "sig" : "7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc4766997816a4502e2781e11ac82cbc9d1edd8c981584d13e18411e2f6e0478c34416e3bb", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "Xln1Bwhka-iliTVQFDCOYLZo-2cBliBsQedI5k5NyiE", - "y" : "XeN_7lyXvK9xRNW0WZgvUu7q-98Dqsuv7zjiE2JKAd4" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "045e59f50708646be8a589355014308e60b668fb670196206c41e748e64e4dca215de37fee5c97bcaf7144d5b459982f52eeeafbdf03aacbafef38e213624a01de", - "wx" : "5e59f50708646be8a589355014308e60b668fb670196206c41e748e64e4dca21", - "wy" : "5de37fee5c97bcaf7144d5b459982f52eeeafbdf03aacbafef38e213624a01de" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200045e59f50708646be8a589355014308e60b668fb670196206c41e748e64e4dca215de37fee5c97bcaf7144d5b459982f52eeeafbdf03aacbafef38e213624a01de", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEXln1Bwhka+iliTVQFDCOYLZo+2cB\nliBsQedI5k5NyiFd43/uXJe8r3FE1bRZmC9S7ur73wOqy6/vOOITYkoB3g==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 182, - "comment" : "extreme value for k and edgecase s", - "msg" : "313233343030", - "sig" : "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296555555550000000055555555555555553ef7a8e48d07df81a693439654210c70", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "Fp-3lzJYQ_r_L3pbVEXani_WIm9--Q7wv-kkEEsC244", - "y" : "e7uN5mLHubHPmyL3ouWCvUbVgdaIeO-yuGGxMdih1mc" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04169fb797325843faff2f7a5b5445da9e2fd6226f7ef90ef0bfe924104b02db8e7bbb8de662c7b9b1cf9b22f7a2e582bd46d581d68878efb2b861b131d8a1d667", - "wx" : "169fb797325843faff2f7a5b5445da9e2fd6226f7ef90ef0bfe924104b02db8e", - "wy" : "7bbb8de662c7b9b1cf9b22f7a2e582bd46d581d68878efb2b861b131d8a1d667" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004169fb797325843faff2f7a5b5445da9e2fd6226f7ef90ef0bfe924104b02db8e7bbb8de662c7b9b1cf9b22f7a2e582bd46d581d68878efb2b861b131d8a1d667", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFp+3lzJYQ/r/L3pbVEXani/WIm9+\n+Q7wv+kkEEsC2457u43mYse5sc+bIvei5YK9RtWB1oh477K4YbEx2KHWZw==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 183, - "comment" : "extreme value for k and s^-1", - "msg" : "313233343030", - "sig" : "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296b6db6db6249249254924924924924924625bd7a09bec4ca81bcdd9f8fd6b63cc", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "JxzYnAABQwlrYtTp5MqIWu8vcCPRiv_a-Le1SJgUh1Q", - "y" : "ChxulU4yEIQ1tV-jhbD3ZIGmCbkUnMtLArLKR_6OTaU" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04271cd89c000143096b62d4e9e4ca885aef2f7023d18affdaf8b7b548981487540a1c6e954e32108435b55fa385b0f76481a609b9149ccb4b02b2ca47fe8e4da5", - "wx" : "271cd89c000143096b62d4e9e4ca885aef2f7023d18affdaf8b7b54898148754", - "wy" : "0a1c6e954e32108435b55fa385b0f76481a609b9149ccb4b02b2ca47fe8e4da5" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004271cd89c000143096b62d4e9e4ca885aef2f7023d18affdaf8b7b548981487540a1c6e954e32108435b55fa385b0f76481a609b9149ccb4b02b2ca47fe8e4da5", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEJxzYnAABQwlrYtTp5MqIWu8vcCPR\niv/a+Le1SJgUh1QKHG6VTjIQhDW1X6OFsPdkgaYJuRScy0sCsspH/o5NpQ==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 184, - "comment" : "extreme value for k and s^-1", - "msg" : "313233343030", - "sig" : "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296cccccccc00000000cccccccccccccccc971f2ef152794b9d8fc7d568c9e8eaa7", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "PQvH7Y8J0st920brwe15mrFWOpq4S_UkWHoiCv5JnBI", - "y" : "4i3Ds8EDgkpPN42WrbCkCKvxnOfWiqYkT3jLIW-j-N8" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "043d0bc7ed8f09d2cb7ddb46ebc1ed799ab1563a9ab84bf524587a220afe499c12e22dc3b3c103824a4f378d96adb0a408abf19ce7d68aa6244f78cb216fa3f8df", - "wx" : "3d0bc7ed8f09d2cb7ddb46ebc1ed799ab1563a9ab84bf524587a220afe499c12", - "wy" : "00e22dc3b3c103824a4f378d96adb0a408abf19ce7d68aa6244f78cb216fa3f8df" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200043d0bc7ed8f09d2cb7ddb46ebc1ed799ab1563a9ab84bf524587a220afe499c12e22dc3b3c103824a4f378d96adb0a408abf19ce7d68aa6244f78cb216fa3f8df", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEPQvH7Y8J0st920brwe15mrFWOpq4\nS/UkWHoiCv5JnBLiLcOzwQOCSk83jZatsKQIq/Gc59aKpiRPeMshb6P43w==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 185, - "comment" : "extreme value for k and s^-1", - "msg" : "313233343030", - "sig" : "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2963333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aaa", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "psiFreGkxWb5uwENBml0q7KBeX-nASiMchvL0jZjqbc", - "y" : "LkJLaQlXFo0ZOmCW_HeisASpx9Rn4Afh8gWEWPmK8xY" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04a6c885ade1a4c566f9bb010d066974abb281797fa701288c721bcbd23663a9b72e424b690957168d193a6096fc77a2b004a9c7d467e007e1f2058458f98af316", - "wx" : "00a6c885ade1a4c566f9bb010d066974abb281797fa701288c721bcbd23663a9b7", - "wy" : "2e424b690957168d193a6096fc77a2b004a9c7d467e007e1f2058458f98af316" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004a6c885ade1a4c566f9bb010d066974abb281797fa701288c721bcbd23663a9b72e424b690957168d193a6096fc77a2b004a9c7d467e007e1f2058458f98af316", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEpsiFreGkxWb5uwENBml0q7KBeX+n\nASiMchvL0jZjqbcuQktpCVcWjRk6YJb8d6KwBKnH1GfgB+HyBYRY+YrzFg==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 186, - "comment" : "extreme value for k and s^-1", - "msg" : "313233343030", - "sig" : "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29649249248db6db6dbb6db6db6db6db6db5a8b230d0b2b51dcd7ebf0c9fef7c185", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "jTwsLDt2W6gonmrDgSVyolv3XfYth6tzMMO9utnr-lw", - "y" : "TGhFRC1mk1sjhXjUOuxU98qhYh0a8kHUYy4LeAxCP10" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "048d3c2c2c3b765ba8289e6ac3812572a25bf75df62d87ab7330c3bdbad9ebfa5c4c6845442d66935b238578d43aec54f7caa1621d1af241d4632e0b780c423f5d", - "wx" : "008d3c2c2c3b765ba8289e6ac3812572a25bf75df62d87ab7330c3bdbad9ebfa5c", - "wy" : "4c6845442d66935b238578d43aec54f7caa1621d1af241d4632e0b780c423f5d" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200048d3c2c2c3b765ba8289e6ac3812572a25bf75df62d87ab7330c3bdbad9ebfa5c4c6845442d66935b238578d43aec54f7caa1621d1af241d4632e0b780c423f5d", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEjTwsLDt2W6gonmrDgSVyolv3XfYt\nh6tzMMO9utnr+lxMaEVELWaTWyOFeNQ67FT3yqFiHRryQdRjLgt4DEI/XQ==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 187, - "comment" : "extreme value for k", - "msg" : "313233343030", - "sig" : "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29616a4502e2781e11ac82cbc9d1edd8c981584d13e18411e2f6e0478c34416e3bb", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "axfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5RdiYwpY", - "y" : "T-NC4v4af5uO5-tKfA-eFivOM1drMV7Oy7ZAaDe_UfU" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", - "wx" : "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", - "wy" : "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEaxfR8uEsQkf4vOblY6RA8ncDfYEt\n6zOg9KE5RdiYwpZP40Li/hp/m47n60p8D54WK84zV2sxXs7LtkBoN79R9Q==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 188, - "comment" : "testing point duplication", - "msg" : "313233343030", - "sig" : "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c2", - "result" : "invalid", - "flags" : [] - }, - { - "tcId" : 189, - "comment" : "testing point duplication", - "msg" : "313233343030", - "sig" : "44a5ad0ad0636d9f12bc9e0a6bdd5e1cbcb012ea7bf091fcec15b0c43202d52e249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c2", - "result" : "invalid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "axfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5RdiYwpY", - "y" : "sBy9HAHlgGVxGBS1g_Bh6dQxzKmUzqExNEm_l8hArgo" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296b01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae0a", - "wx" : "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", - "wy" : "00b01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae0a" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296b01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae0a", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEaxfR8uEsQkf4vOblY6RA8ncDfYEt\n6zOg9KE5RdiYwpawHL0cAeWAZXEYFLWD8GHp1DHMqZTOoTE0Sb+XyECuCg==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 190, - "comment" : "testing point duplication", - "msg" : "313233343030", - "sig" : "bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c2", - "result" : "invalid", - "flags" : [] - }, - { - "tcId" : 191, - "comment" : "testing point duplication", - "msg" : "313233343030", - "sig" : "44a5ad0ad0636d9f12bc9e0a6bdd5e1cbcb012ea7bf091fcec15b0c43202d52e249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c2", - "result" : "invalid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "BKrsc2NXJvIT-4qeZNo7hjLkFJWpRNAEW1IuunJA-tU", - "y" : "h9kxV5iqo6W6AXdXh87QXqr3tOCfyB1tGqVG6DZdUl0" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "0404aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad587d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d", - "wx" : "04aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad5", - "wy" : "0087d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d0301070342000404aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad587d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEBKrsc2NXJvIT+4qeZNo7hjLkFJWp\nRNAEW1IuunJA+tWH2TFXmKqjpboBd1eHztBeqve04J/IHW0apUboNl1SXQ==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 192, - "comment" : "pseudorandom signature", - "msg" : "", - "sig" : "b292a619339f6e567a305c951c0dcbcc42d16e47f219f9e98e76e09d8770b34a0177e60492c5a8242f76f07bfe3661bde59ec2a17ce5bd2dab2abebdf89a62e2", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 193, - "comment" : "pseudorandom signature", - "msg" : "4d7367", - "sig" : "530bd6b0c9af2d69ba897f6b5fb59695cfbf33afe66dbadcf5b8d2a2a6538e23d85e489cb7a161fd55ededcedbf4cc0c0987e3e3f0f242cae934c72caa3f43e9", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 194, - "comment" : "pseudorandom signature", - "msg" : "313233343030", - "sig" : "a8ea150cb80125d7381c4c1f1da8e9de2711f9917060406a73d7904519e51388f3ab9fa68bd47973a73b2d40480c2ba50c22c9d76ec217257288293285449b86", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 195, - "comment" : "pseudorandom signature", - "msg" : "0000000000000000000000000000000000000000", - "sig" : "986e65933ef2ed4ee5aada139f52b70539aaf63f00a91f29c69178490d57fb713dafedfb8da6189d372308cbf1489bbbdabf0c0217d1c0ff0f701aaa7a694b9c", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "TzN8z9Z3JqgF5PFgCuKEnfOAfsoRc4Ajn72BaQAAAAA", - "y" : "7Z3qEkzIw5ZBZBHpiMMPQn61BK9DoxRs1d9-pgZm1oU" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "044f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685", - "wx" : "4f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000", - "wy" : "00ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200044f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAETzN8z9Z3JqgF5PFgCuKEnfOAfsoR\nc4Ajn72BaQAAAADtneoSTMjDlkFkEemIww9CfrUEr0OjFGzV336mBmbWhQ==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 196, - "comment" : "x-coordinate of the public key has many trailing 0's", - "msg" : "4d657373616765", - "sig" : "d434e262a49eab7781e353a3565e482550dd0fd5defa013c7f29745eff3569f19b0c0a93f267fb6052fd8077be769c2b98953195d7bc10de844218305c6ba17a", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 197, - "comment" : "x-coordinate of the public key has many trailing 0's", - "msg" : "4d657373616765", - "sig" : "0fe774355c04d060f76d79fd7a772e421463489221bf0a33add0be9b1979110b500dcba1c69a8fbd43fa4f57f743ce124ca8b91a1f325f3fac6181175df55737", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 198, - "comment" : "x-coordinate of the public key has many trailing 0's", - "msg" : "4d657373616765", - "sig" : "bb40bf217bed3fb3950c7d39f03d36dc8e3b2cd79693f125bfd06595ee1135e3541bf3532351ebb032710bdb6a1bf1bfc89a1e291ac692b3fa4780745bb55677", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "PPA9YU2JOc_UmaB4c_rCgWGPBrj_h-gBXD9JcmUASTU", - "y" : "hPoXTXkccr8s44gKiWDdKnx6EzioL4Wp5Zzb3oAAAAA" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "043cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f49726500493584fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000", - "wx" : "3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935", - "wy" : "0084fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200043cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f49726500493584fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEPPA9YU2JOc/UmaB4c/rCgWGPBrj/\nh+gBXD9JcmUASTWE+hdNeRxyvyzjiAqJYN0qfHoTOKgvhanlnNvegAAAAA==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 199, - "comment" : "y-coordinate of the public key has many trailing 0's", - "msg" : "4d657373616765", - "sig" : "664eb7ee6db84a34df3c86ea31389a5405badd5ca99231ff556d3e75a233e73a59f3c752e52eca46137642490a51560ce0badc678754b8f72e51a2901426a1bd", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 200, - "comment" : "y-coordinate of the public key has many trailing 0's", - "msg" : "4d657373616765", - "sig" : "4cd0429bbabd2827009d6fcd843d4ce39c3e42e2d1631fd001985a79d1fd8b439638bf12dd682f60be7ef1d0e0d98f08b7bca77a1a2b869ae466189d2acdabe3", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 201, - "comment" : "y-coordinate of the public key has many trailing 0's", - "msg" : "4d657373616765", - "sig" : "e56c6ea2d1b017091c44d8b6cb62b9f460e3ce9aed5e5fd41e8added97c56c04a308ec31f281e955be20b457e463440b4fcf2b80258078207fc1378180f89b55", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "PPA9YU2JOc_UmaB4c_rCgWGPBrj_h-gBXD9JcmUASTU", - "y" : "ewXosYbjjUHTHHf1dp8i1YOF7MhX0HpWGmMkIX____8" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "043cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f4972650049357b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff", - "wx" : "3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935", - "wy" : "7b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200043cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f4972650049357b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEPPA9YU2JOc/UmaB4c/rCgWGPBrj/\nh+gBXD9JcmUASTV7BeixhuONQdMcd/V2nyLVg4XsyFfQelYaYyQhf////w==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 202, - "comment" : "y-coordinate of the public key has many trailing 1's", - "msg" : "4d657373616765", - "sig" : "1158a08d291500b4cabed3346d891eee57c176356a2624fb011f8fbbf3466830228a8c486a736006e082325b85290c5bc91f378b75d487dda46798c18f285519", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 203, - "comment" : "y-coordinate of the public key has many trailing 1's", - "msg" : "4d657373616765", - "sig" : "b1db9289649f59410ea36b0c0fc8d6aa2687b29176939dd23e0dde56d309fa9d3e1535e4280559015b0dbd987366dcf43a6d1af5c23c7d584e1c3f48a1251336", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 204, - "comment" : "y-coordinate of the public key has many trailing 1's", - "msg" : "4d657373616765", - "sig" : "b7b16e762286cb96446aa8d4e6e7578b0a341a79f2dd1a220ac6f0ca4e24ed86ddc60a700a139b04661c547d07bbb0721780146df799ccf55e55234ecb8f12bc", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "KCnDH6ouQA40TtlLyj_NBUWVbrz-itD236X_jv____8", - "y" : "oBqvrwAOUlhYVa-nZ2reKEETCZBS31fn6zvTfr65Ii4" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "042829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffffa01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e", - "wx" : "2829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffff", - "wy" : "00a01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d030107034200042829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffffa01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEKCnDH6ouQA40TtlLyj/NBUWVbrz+\nitD236X/jv////+gGq+vAA5SWFhVr6dnat4oQRMJkFLfV+frO9N+vrkiLg==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 205, - "comment" : "x-coordinate of the public key has many trailing 1's", - "msg" : "4d657373616765", - "sig" : "d82a7c2717261187c8e00d8df963ff35d796edad36bc6e6bd1c91c670d9105b43dcabddaf8fcaa61f4603e7cbac0f3c0351ecd5988efb23f680d07debd139929", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 206, - "comment" : "x-coordinate of the public key has many trailing 1's", - "msg" : "4d657373616765", - "sig" : "5eb9c8845de68eb13d5befe719f462d77787802baff30ce96a5cba063254af782c026ae9be2e2a5e7ca0ff9bbd92fb6e44972186228ee9a62b87ddbe2ef66fb5", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 207, - "comment" : "x-coordinate of the public key has many trailing 1's", - "msg" : "4d657373616765", - "sig" : "96843dd03c22abd2f3b782b170239f90f277921becc117d0404a8e4e36230c28f2be378f526f74a543f67165976de9ed9a31214eb4d7e6db19e1ede123dd991d", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "____-UgIHmoEWN2PnnOPJmX_kFmtaqwHCDGMTKmnpPU", - "y" : "Woq8ui3ahHQxHuVBSblzyuDA-4lVetC_eOZSmhZjvXM" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f55a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73", - "wx" : "00fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f5", - "wy" : "5a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f55a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE////+UgIHmoEWN2PnnOPJmX/kFmt\naqwHCDGMTKmnpPVairy6LdqEdDEe5UFJuXPK4MD7iVV60L945lKaFmO9cw==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 208, - "comment" : "x-coordinate of the public key is large", - "msg" : "4d657373616765", - "sig" : "766456dce1857c906f9996af729339464d27e9d98edc2d0e3b760297067421f6402385ecadae0d8081dccaf5d19037ec4e55376eced699e93646bfbbf19d0b41", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 209, - "comment" : "x-coordinate of the public key is large", - "msg" : "4d657373616765", - "sig" : "c605c4b2edeab20419e6518a11b2dbc2b97ed8b07cced0b19c34f777de7b9fd9edf0f612c5f46e03c719647bc8af1b29b2cde2eda700fb1cff5e159d47326dba", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 210, - "comment" : "x-coordinate of the public key is large", - "msg" : "4d657373616765", - "sig" : "d48b68e6cabfe03cf6141c9ac54141f210e64485d9929ad7b732bfe3b7eb8a84feedae50c61bd00e19dc26f9b7e2265e4508c389109ad2f208f0772315b6c941", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "AAAAA_oV-WOUnV8DpvXH-G-eABXusjrrv_EXOTe6dI4", - "y" : "EJmHIHDo6HxVX6E2Wcyl1_rc_LACPqiJVIykivK6fnE" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "0400000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71", - "wx" : "03fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e", - "wy" : "1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d0301070342000400000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAAAAA/oV+WOUnV8DpvXH+G+eABXu\nsjrrv/EXOTe6dI4QmYcgcOjofFVfoTZZzKXX+tz8sAI+qIlUjKSK8rp+cQ==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 211, - "comment" : "x-coordinate of the public key is small", - "msg" : "4d657373616765", - "sig" : "b7c81457d4aeb6aa65957098569f0479710ad7f6595d5874c35a93d12a5dd4c7b7961a0b652878c2d568069a432ca18a1a9199f2ca574dad4b9e3a05c0a1cdb3", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 212, - "comment" : "x-coordinate of the public key is small", - "msg" : "4d657373616765", - "sig" : "6b01332ddb6edfa9a30a1321d5858e1ee3cf97e263e669f8de5e9652e76ff3f75939545fced457309a6a04ace2bd0f70139c8f7d86b02cb1cc58f9e69e96cd5a", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 213, - "comment" : "x-coordinate of the public key is small", - "msg" : "4d657373616765", - "sig" : "efdb884720eaeadc349f9fc356b6c0344101cd2fd8436b7d0e6a4fb93f106361f24bee6ad5dc05f7613975473aadf3aacba9e77de7d69b6ce48cb60d8113385d", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "vLspFMefBF6qbsu8YSgWs75dLWeWcH2BJen4UcGK8BU", - "y" : "AAAAABNSu0oPoupMzrmrY91oSt5aESe88wCmmKcZO8I" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2", - "wx" : "00bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015", - "wy" : "1352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEvLspFMefBF6qbsu8YSgWs75dLWeW\ncH2BJen4UcGK8BUAAAAAE1K7Sg+i6kzOuatj3WhK3loRJ7zzAKaYpxk7wg==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 214, - "comment" : "y-coordinate of the public key is small", - "msg" : "4d657373616765", - "sig" : "31230428405560dcb88fb5a646836aea9b23a23dd973dcbe8014c87b8b20eb070f9344d6e812ce166646747694a41b0aaf97374e19f3c5fb8bd7ae3d9bd0beff", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 215, - "comment" : "y-coordinate of the public key is small", - "msg" : "4d657373616765", - "sig" : "caa797da65b320ab0d5c470cda0b36b294359c7db9841d679174db34c4855743cf543a62f23e212745391aaf7505f345123d2685ee3b941d3de6d9b36242e5a0", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 216, - "comment" : "y-coordinate of the public key is small", - "msg" : "4d657373616765", - "sig" : "7e5f0ab5d900d3d3d7867657e5d6d36519bc54084536e7d21c336ed8001859459450c07f201faec94b82dfb322e5ac676688294aad35aa72e727ff0b19b646aa", - "result" : "valid", - "flags" : [] - } - ] - }, - { - "jwk" : { - "crv" : "P-256", - "kid" : "none", - "kty" : "EC", - "x" : "vLspFMefBF6qbsu8YSgWs75dLWeWcH2BJen4UcGK8BU", - "y" : "_____uytRLbwXRWzMUZUnCKXtSKl7thDDP9ZZ1jmxD0" - }, - "key" : { - "curve" : "secp256r1", - "keySize" : 256, - "type" : "EcPublicKey", - "uncompressed" : "04bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d", - "wx" : "00bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015", - "wy" : "00fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d" - }, - "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d", - "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEvLspFMefBF6qbsu8YSgWs75dLWeW\ncH2BJen4UcGK8BX////+7K1EtvBdFbMxRlScIpe1IqXu2EMM/1lnWObEPQ==\n-----END PUBLIC KEY-----", - "sha" : "SHA-256", - "type" : "EcdsaP1363Verify", - "tests" : [ - { - "tcId" : 217, - "comment" : "y-coordinate of the public key is large", - "msg" : "4d657373616765", - "sig" : "d7d70c581ae9e3f66dc6a480bf037ae23f8a1e4a2136fe4b03aa69f0ca25b35689c460f8a5a5c2bbba962c8a3ee833a413e85658e62a59e2af41d9127cc47224", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 218, - "comment" : "y-coordinate of the public key is large", - "msg" : "4d657373616765", - "sig" : "341c1b9ff3c83dd5e0dfa0bf68bcdf4bb7aa20c625975e5eeee34bb396266b3472b69f061b750fd5121b22b11366fad549c634e77765a017902a67099e0a4469", - "result" : "valid", - "flags" : [] - }, - { - "tcId" : 219, - "comment" : "y-coordinate of the public key is large", - "msg" : "4d657373616765", - "sig" : "70bebe684cdcb5ca72a42f0d873879359bd1781a591809947628d313a3814f67aec03aca8f5587a4d535fa31027bbe9cc0e464b1c3577f4c2dcde6b2094798a9", - "result" : "valid", - "flags" : [] - } - ] - } - ] -} diff --git a/lib/openzeppelin-contracts/test/utils/introspection/ERC165.test.js b/lib/openzeppelin-contracts/test/utils/introspection/ERC165.test.js deleted file mode 100644 index 8117c69..0000000 --- a/lib/openzeppelin-contracts/test/utils/introspection/ERC165.test.js +++ /dev/null @@ -1,18 +0,0 @@ -const { ethers } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { shouldSupportInterfaces } = require('./SupportsInterface.behavior'); - -async function fixture() { - return { - mock: await ethers.deployContract('$ERC165'), - }; -} - -describe('ERC165', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - shouldSupportInterfaces(); -}); diff --git a/lib/openzeppelin-contracts/test/utils/introspection/ERC165Checker.test.js b/lib/openzeppelin-contracts/test/utils/introspection/ERC165Checker.test.js deleted file mode 100644 index 1bbe8a5..0000000 --- a/lib/openzeppelin-contracts/test/utils/introspection/ERC165Checker.test.js +++ /dev/null @@ -1,245 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -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'; - -async function fixture() { - return { mock: await ethers.deployContract('$ERC165Checker') }; -} - -describe('ERC165Checker', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('ERC165 missing return data', function () { - before(async function () { - this.target = await ethers.deployContract('ERC165MissingData'); - }); - - it('does not support ERC165', async function () { - expect(await this.mock.$supportsERC165(this.target)).to.be.false; - }); - - it('does not support mock interface via supportsInterface', async function () { - expect(await this.mock.$supportsInterface(this.target, DUMMY_ID)).to.be.false; - }); - - it('does not support mock interface via supportsAllInterfaces', async function () { - expect(await this.mock.$supportsAllInterfaces(this.target, [DUMMY_ID])).to.be.false; - }); - - it('does not support mock interface via getSupportedInterfaces', async function () { - expect(await this.mock.$getSupportedInterfaces(this.target, [DUMMY_ID])).to.deep.equal([false]); - }); - - it('does not support mock interface via supportsERC165InterfaceUnchecked', async function () { - expect(await this.mock.$supportsERC165InterfaceUnchecked(this.target, DUMMY_ID)).to.be.false; - }); - }); - - describe('ERC165 malicious return data', function () { - beforeEach(async function () { - this.target = await ethers.deployContract('ERC165MaliciousData'); - }); - - it('does not support ERC165', async function () { - expect(await this.mock.$supportsERC165(this.target)).to.be.false; - }); - - it('does not support mock interface via supportsInterface', async function () { - expect(await this.mock.$supportsInterface(this.target, DUMMY_ID)).to.be.false; - }); - - it('does not support mock interface via supportsAllInterfaces', async function () { - expect(await this.mock.$supportsAllInterfaces(this.target, [DUMMY_ID])).to.be.false; - }); - - it('does not support mock interface via getSupportedInterfaces', async function () { - expect(await this.mock.$getSupportedInterfaces(this.target, [DUMMY_ID])).to.deep.equal([false]); - }); - - it('does not support mock interface via supportsERC165InterfaceUnchecked', async function () { - expect(await this.mock.$supportsERC165InterfaceUnchecked(this.target, DUMMY_ID)).to.be.true; - }); - }); - - describe('ERC165 not supported', function () { - beforeEach(async function () { - this.target = await ethers.deployContract('ERC165NotSupported'); - }); - - it('does not support ERC165', async function () { - expect(await this.mock.$supportsERC165(this.target)).to.be.false; - }); - - it('does not support mock interface via supportsInterface', async function () { - expect(await this.mock.$supportsInterface(this.target, DUMMY_ID)).to.be.false; - }); - - it('does not support mock interface via supportsAllInterfaces', async function () { - expect(await this.mock.$supportsAllInterfaces(this.target, [DUMMY_ID])).to.be.false; - }); - - it('does not support mock interface via getSupportedInterfaces', async function () { - expect(await this.mock.$getSupportedInterfaces(this.target, [DUMMY_ID])).to.deep.equal([false]); - }); - - it('does not support mock interface via supportsERC165InterfaceUnchecked', async function () { - expect(await this.mock.$supportsERC165InterfaceUnchecked(this.target, DUMMY_ID)).to.be.false; - }); - }); - - describe('ERC165 supported', function () { - beforeEach(async function () { - this.target = await ethers.deployContract('ERC165InterfacesSupported', [[]]); - }); - - it('supports ERC165', async function () { - expect(await this.mock.$supportsERC165(this.target)).to.be.true; - }); - - it('does not support mock interface via supportsInterface', async function () { - expect(await this.mock.$supportsInterface(this.target, DUMMY_ID)).to.be.false; - }); - - it('does not support mock interface via supportsAllInterfaces', async function () { - expect(await this.mock.$supportsAllInterfaces(this.target, [DUMMY_ID])).to.be.false; - }); - - it('does not support mock interface via getSupportedInterfaces', async function () { - expect(await this.mock.$getSupportedInterfaces(this.target, [DUMMY_ID])).to.deep.equal([false]); - }); - - it('does not support mock interface via supportsERC165InterfaceUnchecked', async function () { - expect(await this.mock.$supportsERC165InterfaceUnchecked(this.target, DUMMY_ID)).to.be.false; - }); - }); - - describe('ERC165 and single interface supported', function () { - beforeEach(async function () { - this.target = await ethers.deployContract('ERC165InterfacesSupported', [[DUMMY_ID]]); - }); - - it('supports ERC165', async function () { - expect(await this.mock.$supportsERC165(this.target)).to.be.true; - }); - - it('supports mock interface via supportsInterface', async function () { - expect(await this.mock.$supportsInterface(this.target, DUMMY_ID)).to.be.true; - }); - - it('supports mock interface via supportsAllInterfaces', async function () { - expect(await this.mock.$supportsAllInterfaces(this.target, [DUMMY_ID])).to.be.true; - }); - - it('supports mock interface via getSupportedInterfaces', async function () { - expect(await this.mock.$getSupportedInterfaces(this.target, [DUMMY_ID])).to.deep.equal([true]); - }); - - it('supports mock interface via supportsERC165InterfaceUnchecked', async function () { - expect(await this.mock.$supportsERC165InterfaceUnchecked(this.target, DUMMY_ID)).to.be.true; - }); - }); - - describe('ERC165 and many interfaces supported', function () { - const supportedInterfaces = [DUMMY_ID, DUMMY_ID_2, DUMMY_ID_3]; - beforeEach(async function () { - this.target = await ethers.deployContract('ERC165InterfacesSupported', [supportedInterfaces]); - }); - - it('supports ERC165', async function () { - expect(await this.mock.$supportsERC165(this.target)).to.be.true; - }); - - it('supports each interfaceId via supportsInterface', async function () { - for (const interfaceId of supportedInterfaces) { - expect(await this.mock.$supportsInterface(this.target, interfaceId)).to.be.true; - } - }); - - it('supports all interfaceIds via supportsAllInterfaces', async function () { - expect(await this.mock.$supportsAllInterfaces(this.target, supportedInterfaces)).to.be.true; - }); - - it('supports none of the interfaces queried via supportsAllInterfaces', async function () { - const interfaceIdsToTest = [DUMMY_UNSUPPORTED_ID, DUMMY_UNSUPPORTED_ID_2]; - - expect(await this.mock.$supportsAllInterfaces(this.target, interfaceIdsToTest)).to.be.false; - }); - - it('supports not all of the interfaces queried via supportsAllInterfaces', async function () { - const interfaceIdsToTest = [...supportedInterfaces, DUMMY_UNSUPPORTED_ID]; - expect(await this.mock.$supportsAllInterfaces(this.target, interfaceIdsToTest)).to.be.false; - }); - - it('supports all interfaceIds via getSupportedInterfaces', async function () { - expect(await this.mock.$getSupportedInterfaces(this.target, supportedInterfaces)).to.deep.equal( - supportedInterfaces.map(i => supportedInterfaces.includes(i)), - ); - }); - - it('supports none of the interfaces queried via getSupportedInterfaces', async function () { - const interfaceIdsToTest = [DUMMY_UNSUPPORTED_ID, DUMMY_UNSUPPORTED_ID_2]; - - expect(await this.mock.$getSupportedInterfaces(this.target, interfaceIdsToTest)).to.deep.equal( - interfaceIdsToTest.map(i => supportedInterfaces.includes(i)), - ); - }); - - it('supports not all of the interfaces queried via getSupportedInterfaces', async function () { - const interfaceIdsToTest = [...supportedInterfaces, DUMMY_UNSUPPORTED_ID]; - - expect(await this.mock.$getSupportedInterfaces(this.target, interfaceIdsToTest)).to.deep.equal( - interfaceIdsToTest.map(i => supportedInterfaces.includes(i)), - ); - }); - - it('supports each interfaceId via supportsERC165InterfaceUnchecked', async function () { - for (const interfaceId of supportedInterfaces) { - expect(await this.mock.$supportsERC165InterfaceUnchecked(this.target, interfaceId)).to.be.true; - } - }); - }); - - describe('account address does not support ERC165', function () { - it('does not support ERC165', async function () { - expect(await this.mock.$supportsERC165(DUMMY_ACCOUNT)).to.be.false; - }); - - it('does not support mock interface via supportsInterface', async function () { - expect(await this.mock.$supportsInterface(DUMMY_ACCOUNT, DUMMY_ID)).to.be.false; - }); - - it('does not support mock interface via supportsAllInterfaces', async function () { - expect(await this.mock.$supportsAllInterfaces(DUMMY_ACCOUNT, [DUMMY_ID])).to.be.false; - }); - - it('does not support mock interface via getSupportedInterfaces', async function () { - expect(await this.mock.$getSupportedInterfaces(DUMMY_ACCOUNT, [DUMMY_ID])).to.deep.equal([false]); - }); - - it('does not support mock interface via supportsERC165InterfaceUnchecked', async function () { - expect(await this.mock.$supportsERC165InterfaceUnchecked(DUMMY_ACCOUNT, DUMMY_ID)).to.be.false; - }); - }); - - it('Return bomb resistance', async function () { - this.target = await ethers.deployContract('ERC165ReturnBombMock'); - - const { gasUsed: gasUsed1 } = await this.mock.$supportsInterface.send(this.target, DUMMY_ID).then(tx => tx.wait()); - expect(gasUsed1).to.be.lessThan(120_000n); // 3*30k + 21k + some margin - - const { gasUsed: gasUsed2 } = await this.mock.$getSupportedInterfaces - .send(this.target, [DUMMY_ID, DUMMY_ID_2, DUMMY_ID_3, DUMMY_UNSUPPORTED_ID, DUMMY_UNSUPPORTED_ID_2]) - .then(tx => tx.wait()); - - expect(gasUsed2).to.be.lessThan(250_000n); // (2+5)*30k + 21k + some margin - }); -}); diff --git a/lib/openzeppelin-contracts/test/utils/introspection/SupportsInterface.behavior.js b/lib/openzeppelin-contracts/test/utils/introspection/SupportsInterface.behavior.js deleted file mode 100644 index c2bd1a4..0000000 --- a/lib/openzeppelin-contracts/test/utils/introspection/SupportsInterface.behavior.js +++ /dev/null @@ -1,145 +0,0 @@ -const { expect } = require('chai'); -const { interfaceId } = require('../../helpers/methods'); -const { mapValues } = require('../../helpers/iterate'); - -const INVALID_ID = '0xffffffff'; -const SIGNATURES = { - 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)', - ], - ERC1155MetadataURI: ['uri(uint256)'], - ERC1155Receiver: [ - 'onERC1155Received(address,address,uint256,uint256,bytes)', - 'onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)', - ], - ERC1363: [ - 'transferAndCall(address,uint256)', - 'transferAndCall(address,uint256,bytes)', - 'transferFromAndCall(address,address,uint256)', - 'transferFromAndCall(address,address,uint256,bytes)', - 'approveAndCall(address,uint256)', - 'approveAndCall(address,uint256,bytes)', - ], - AccessControl: [ - 'hasRole(bytes32,address)', - 'getRoleAdmin(bytes32)', - 'grantRole(bytes32,address)', - 'revokeRole(bytes32,address)', - 'renounceRole(bytes32,address)', - ], - AccessControlEnumerable: ['getRoleMember(bytes32,uint256)', 'getRoleMemberCount(bytes32)'], - AccessControlDefaultAdminRules: [ - 'defaultAdminDelay()', - 'pendingDefaultAdminDelay()', - 'defaultAdmin()', - 'pendingDefaultAdmin()', - 'defaultAdminDelayIncreaseWait()', - 'changeDefaultAdminDelay(uint48)', - 'rollbackDefaultAdminDelay()', - 'beginDefaultAdminTransfer(address)', - 'acceptDefaultAdminTransfer()', - 'cancelDefaultAdminTransfer()', - ], - Governor: [ - 'name()', - 'version()', - 'COUNTING_MODE()', - 'hashProposal(address[],uint256[],bytes[],bytes32)', - 'state(uint256)', - 'proposalThreshold()', - 'proposalSnapshot(uint256)', - 'proposalDeadline(uint256)', - 'proposalProposer(uint256)', - 'proposalEta(uint256)', - 'proposalNeedsQueuing(uint256)', - 'votingDelay()', - 'votingPeriod()', - 'quorum(uint256)', - 'getVotes(address,uint256)', - 'getVotesWithParams(address,uint256,bytes)', - 'hasVoted(uint256,address)', - 'propose(address[],uint256[],bytes[],string)', - 'queue(address[],uint256[],bytes[],bytes32)', - 'execute(address[],uint256[],bytes[],bytes32)', - 'cancel(address[],uint256[],bytes[],bytes32)', - 'castVote(uint256,uint8)', - 'castVoteWithReason(uint256,uint8,string)', - 'castVoteWithReasonAndParams(uint256,uint8,string,bytes)', - 'castVoteBySig(uint256,uint8,address,bytes)', - 'castVoteWithReasonAndParamsBySig(uint256,uint8,address,string,bytes,bytes)', - ], - ERC2981: ['royaltyInfo(uint256,uint256)'], -}; - -const INTERFACE_IDS = mapValues(SIGNATURES, interfaceId); - -function shouldSupportInterfaces(interfaces = []) { - interfaces.unshift('ERC165'); - - describe('ERC165', function () { - beforeEach(function () { - this.contractUnderTest = this.mock || this.token; - }); - - describe('when the interfaceId is supported', function () { - it('uses less than 30k gas', async function () { - for (const k of interfaces) { - const interface = INTERFACE_IDS[k] ?? k; - expect(await this.contractUnderTest.supportsInterface.estimateGas(interface)).to.lte(30_000n); - } - }); - - it('returns true', async function () { - for (const k of interfaces) { - const interfaceId = INTERFACE_IDS[k] ?? k; - expect(await this.contractUnderTest.supportsInterface(interfaceId), `does not support ${k}`).to.be.true; - } - }); - }); - - describe('when the interfaceId is not supported', function () { - it('uses less than 30k', async function () { - expect(await this.contractUnderTest.supportsInterface.estimateGas(INVALID_ID)).to.lte(30_000n); - }); - - it('returns false', async function () { - expect(await this.contractUnderTest.supportsInterface(INVALID_ID), `supports ${INVALID_ID}`).to.be.false; - }); - }); - - it('all interface functions are in ABI', async function () { - for (const k of interfaces) { - // skip interfaces for which we don't have a function list - if (SIGNATURES[k] === undefined) continue; - - // Check the presence of each function in the contract's interface - for (const fnSig of SIGNATURES[k]) { - expect(this.contractUnderTest.interface.hasFunction(fnSig), `did not find ${fnSig}`).to.be.true; - } - } - }); - }); -} - -module.exports = { - shouldSupportInterfaces, -}; diff --git a/lib/openzeppelin-contracts/test/utils/math/Math.t.sol b/lib/openzeppelin-contracts/test/utils/math/Math.t.sol deleted file mode 100644 index 3d4932e..0000000 --- a/lib/openzeppelin-contracts/test/utils/math/Math.t.sol +++ /dev/null @@ -1,311 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {Test, stdError} from "forge-std/Test.sol"; - -import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; - -contract MathTest is Test { - function testSymbolicTernary(bool f, uint256 a, uint256 b) public { - assertEq(Math.ternary(f, a, b), f ? a : b); - } - - // MIN & MAX - function testSymbolicMinMax(uint256 a, uint256 b) public { - assertEq(Math.min(a, b), a < b ? a : b); - assertEq(Math.max(a, b), a > b ? a : b); - } - - // CEILDIV - function testCeilDiv(uint256 a, uint256 b) public { - vm.assume(b > 0); - - uint256 result = Math.ceilDiv(a, b); - - if (result == 0) { - assertEq(a, 0); - } else { - uint256 expect = a / b; - if (expect * b < a) { - expect += 1; - } - assertEq(result, expect); - } - } - - // 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(Math.unsignedRoundsUp(rounding)); - assertTrue(_squareSmaller(result - 1, input)); - } - // square of result is smaller than input - else if (_squareSmaller(result, input)) { - assertFalse(Math.unsignedRoundsUp(rounding)); - assertTrue(_squareBigger(result + 1, input)); - } - // input is perfect square - else { - assertEq(result * result, input); - } - } - - function _squareBigger(uint256 value, uint256 ref) private pure returns (bool) { - (bool noOverflow, uint256 square) = Math.tryMul(value, value); - return !noOverflow || square > ref; - } - - function _squareSmaller(uint256 value, uint256 ref) private pure returns (bool) { - return value * value < ref; - } - - // INV - function testInvMod(uint256 value, uint256 p) public { - _testInvMod(value, p, true); - } - - function testInvMod2(uint256 seed) public { - uint256 p = 2; // prime - _testInvMod(bound(seed, 1, p - 1), p, false); - } - - function testInvMod17(uint256 seed) public { - uint256 p = 17; // prime - _testInvMod(bound(seed, 1, p - 1), p, false); - } - - function testInvMod65537(uint256 seed) public { - uint256 p = 65537; // prime - _testInvMod(bound(seed, 1, p - 1), p, false); - } - - function testInvModP256(uint256 seed) public { - uint256 p = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff; // prime - _testInvMod(bound(seed, 1, p - 1), p, false); - } - - function _testInvMod(uint256 value, uint256 p, bool allowZero) private { - uint256 inverse = Math.invMod(value, p); - if (inverse != 0) { - assertEq(mulmod(value, inverse, p), 1); - assertLt(inverse, p); - } else { - assertTrue(allowZero); - } - } - - // 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(Math.unsignedRoundsUp(rounding)); - assertTrue(_powerOf2Smaller(result - 1, input)); - } else if (_powerOf2Smaller(result, input)) { - assertFalse(Math.unsignedRoundsUp(rounding)); - assertTrue(_powerOf2Bigger(result + 1, input)); - } else { - assertEq(2 ** result, 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(Math.unsignedRoundsUp(rounding)); - assertTrue(_powerOf10Smaller(result - 1, input)); - } else if (_powerOf10Smaller(result, input)) { - assertFalse(Math.unsignedRoundsUp(rounding)); - assertTrue(_powerOf10Bigger(result + 1, input)); - } else { - assertEq(10 ** result, 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(Math.unsignedRoundsUp(rounding)); - assertTrue(_powerOf256Smaller(result - 1, input)); - } else if (_powerOf256Smaller(result, input)) { - assertFalse(Math.unsignedRoundsUp(rounding)); - assertTrue(_powerOf256Bigger(result + 1, input)); - } else { - assertEq(256 ** result, 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; - } - - // MULDIV - function testMulDiv(uint256 x, uint256 y, uint256 d) public { - // Full precision for x * y - (uint256 xyHi, uint256 xyLo) = _mulHighLow(x, y); - - // Assume result won't overflow (see {testMulDivDomain}) - // This also checks that `d` is positive - vm.assume(xyHi < d); - - // Perform muldiv - uint256 q = Math.mulDiv(x, y, d); - - // Full precision for q * d - (uint256 qdHi, uint256 qdLo) = _mulHighLow(q, d); - // Add remainder of x * y / d (computed as rem = (x * y % d)) - (uint256 qdRemLo, uint256 c) = _addCarry(qdLo, mulmod(x, y, d)); - uint256 qdRemHi = qdHi + c; - - // Full precision check that x * y = q * d + rem - assertEq(xyHi, qdRemHi); - assertEq(xyLo, qdRemLo); - } - - function testMulDivDomain(uint256 x, uint256 y, uint256 d) public { - (uint256 xyHi, ) = _mulHighLow(x, y); - - // Violate {testMulDiv} assumption (covers d is 0 and result overflow) - vm.assume(xyHi >= d); - - // we are outside the scope of {testMulDiv}, we expect muldiv to revert - vm.expectRevert(d == 0 ? stdError.divisionError : stdError.arithmeticError); - Math.mulDiv(x, y, d); - } - - // MOD EXP - function testModExp(uint256 b, uint256 e, uint256 m) public { - if (m == 0) { - vm.expectRevert(stdError.divisionError); - } - uint256 result = Math.modExp(b, e, m); - assertLt(result, m); - assertEq(result, _nativeModExp(b, e, m)); - } - - function testTryModExp(uint256 b, uint256 e, uint256 m) public { - (bool success, uint256 result) = Math.tryModExp(b, e, m); - assertEq(success, m != 0); - if (success) { - assertLt(result, m); - assertEq(result, _nativeModExp(b, e, m)); - } else { - assertEq(result, 0); - } - } - - function testModExpMemory(uint256 b, uint256 e, uint256 m) public { - if (m == 0) { - vm.expectRevert(stdError.divisionError); - } - bytes memory result = Math.modExp(abi.encodePacked(b), abi.encodePacked(e), abi.encodePacked(m)); - assertEq(result.length, 0x20); - uint256 res = abi.decode(result, (uint256)); - assertLt(res, m); - assertEq(res, _nativeModExp(b, e, m)); - } - - function testTryModExpMemory(uint256 b, uint256 e, uint256 m) public { - (bool success, bytes memory result) = Math.tryModExp( - abi.encodePacked(b), - abi.encodePacked(e), - abi.encodePacked(m) - ); - if (success) { - assertEq(result.length, 0x20); // m is a uint256, so abi.encodePacked(m).length is 0x20 - uint256 res = abi.decode(result, (uint256)); - assertLt(res, m); - assertEq(res, _nativeModExp(b, e, m)); - } else { - assertEq(result.length, 0); - } - } - - function _nativeModExp(uint256 b, uint256 e, uint256 m) private pure returns (uint256) { - if (m == 1) return 0; - uint256 r = 1; - while (e > 0) { - if (e % 2 > 0) { - r = mulmod(r, b, m); - } - b = mulmod(b, b, m); - e >>= 1; - } - return r; - } - - // Helpers - function _asRounding(uint8 r) private pure returns (Math.Rounding) { - vm.assume(r < uint8(type(Math.Rounding).max)); - return Math.Rounding(r); - } - - function _mulHighLow(uint256 x, uint256 y) private pure returns (uint256 high, uint256 low) { - (uint256 x0, uint256 x1) = (x & type(uint128).max, x >> 128); - (uint256 y0, uint256 y1) = (y & type(uint128).max, y >> 128); - - // Karatsuba algorithm - // https://en.wikipedia.org/wiki/Karatsuba_algorithm - uint256 z2 = x1 * y1; - uint256 z1a = x1 * y0; - uint256 z1b = x0 * y1; - uint256 z0 = x0 * y0; - - uint256 carry = ((z1a & type(uint128).max) + (z1b & type(uint128).max) + (z0 >> 128)) >> 128; - - high = z2 + (z1a >> 128) + (z1b >> 128) + carry; - - unchecked { - low = x * y; - } - } - - function _addCarry(uint256 x, uint256 y) private pure returns (uint256 res, uint256 carry) { - unchecked { - res = x + y; - } - carry = res < x ? 1 : 0; - } -} diff --git a/lib/openzeppelin-contracts/test/utils/math/Math.test.js b/lib/openzeppelin-contracts/test/utils/math/Math.test.js deleted file mode 100644 index f38f2f3..0000000 --- a/lib/openzeppelin-contracts/test/utils/math/Math.test.js +++ /dev/null @@ -1,562 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); - -const { Rounding } = require('../../helpers/enums'); -const { min, max, modExp } = require('../../helpers/math'); -const { generators } = require('../../helpers/random'); -const { product, range } = require('../../helpers/iterate'); - -const RoundingDown = [Rounding.Floor, Rounding.Trunc]; -const RoundingUp = [Rounding.Ceil, Rounding.Expand]; - -const bytes = (value, width = undefined) => ethers.Typed.bytes(ethers.toBeHex(value, width)); -const uint256 = value => ethers.Typed.uint256(value); -bytes.zero = '0x'; -uint256.zero = 0n; - -async function testCommutative(fn, lhs, rhs, expected, ...extra) { - expect(await fn(lhs, rhs, ...extra)).to.deep.equal(expected); - expect(await fn(rhs, lhs, ...extra)).to.deep.equal(expected); -} - -async function fixture() { - const mock = await ethers.deployContract('$Math'); - - // disambiguation, we use the version with explicit rounding - mock.$mulDiv = mock['$mulDiv(uint256,uint256,uint256,uint8)']; - mock.$sqrt = mock['$sqrt(uint256,uint8)']; - mock.$log2 = mock['$log2(uint256,uint8)']; - mock.$log10 = mock['$log10(uint256,uint8)']; - mock.$log256 = mock['$log256(uint256,uint8)']; - - return { mock }; -} - -describe('Math', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('tryAdd', function () { - it('adds correctly', async function () { - const a = 5678n; - const b = 1234n; - await testCommutative(this.mock.$tryAdd, a, b, [true, a + b]); - }); - - it('reverts on addition overflow', async function () { - const a = ethers.MaxUint256; - const b = 1n; - await testCommutative(this.mock.$tryAdd, a, b, [false, 0n]); - }); - }); - - describe('trySub', function () { - it('subtracts correctly', async function () { - const a = 5678n; - const b = 1234n; - expect(await this.mock.$trySub(a, b)).to.deep.equal([true, a - b]); - }); - - it('reverts if subtraction result would be negative', async function () { - const a = 1234n; - const b = 5678n; - expect(await this.mock.$trySub(a, b)).to.deep.equal([false, 0n]); - }); - }); - - describe('tryMul', function () { - it('multiplies correctly', async function () { - const a = 1234n; - const b = 5678n; - await testCommutative(this.mock.$tryMul, a, b, [true, a * b]); - }); - - it('multiplies by zero correctly', async function () { - const a = 0n; - const b = 5678n; - await testCommutative(this.mock.$tryMul, a, b, [true, a * b]); - }); - - it('reverts on multiplication overflow', async function () { - const a = ethers.MaxUint256; - const b = 2n; - await testCommutative(this.mock.$tryMul, a, b, [false, 0n]); - }); - }); - - describe('tryDiv', function () { - it('divides correctly', async function () { - const a = 5678n; - const b = 5678n; - expect(await this.mock.$tryDiv(a, b)).to.deep.equal([true, a / b]); - }); - - it('divides zero correctly', async function () { - const a = 0n; - const b = 5678n; - expect(await this.mock.$tryDiv(a, b)).to.deep.equal([true, a / b]); - }); - - it('returns complete number result on non-even division', async function () { - const a = 7000n; - const b = 5678n; - expect(await this.mock.$tryDiv(a, b)).to.deep.equal([true, a / b]); - }); - - it('reverts on division by zero', async function () { - const a = 5678n; - const b = 0n; - expect(await this.mock.$tryDiv(a, b)).to.deep.equal([false, 0n]); - }); - }); - - describe('tryMod', function () { - describe('modulos correctly', function () { - it('when the dividend is smaller than the divisor', async function () { - const a = 284n; - const b = 5678n; - expect(await this.mock.$tryMod(a, b)).to.deep.equal([true, a % b]); - }); - - it('when the dividend is equal to the divisor', async function () { - const a = 5678n; - const b = 5678n; - expect(await this.mock.$tryMod(a, b)).to.deep.equal([true, a % b]); - }); - - it('when the dividend is larger than the divisor', async function () { - const a = 7000n; - const b = 5678n; - expect(await this.mock.$tryMod(a, b)).to.deep.equal([true, a % b]); - }); - - it('when the dividend is a multiple of the divisor', async function () { - const a = 17034n; // 17034 == 5678 * 3 - const b = 5678n; - expect(await this.mock.$tryMod(a, b)).to.deep.equal([true, a % b]); - }); - }); - - it('reverts with a 0 divisor', async function () { - const a = 5678n; - const b = 0n; - expect(await this.mock.$tryMod(a, b)).to.deep.equal([false, 0n]); - }); - }); - - describe('max', function () { - it('is correctly detected in both position', async function () { - await testCommutative(this.mock.$max, 1234n, 5678n, max(1234n, 5678n)); - }); - }); - - describe('min', function () { - it('is correctly detected in both position', async function () { - await testCommutative(this.mock.$min, 1234n, 5678n, min(1234n, 5678n)); - }); - }); - - describe('average', function () { - it('is correctly calculated with two odd numbers', async function () { - const a = 57417n; - const b = 95431n; - expect(await this.mock.$average(a, b)).to.equal((a + b) / 2n); - }); - - it('is correctly calculated with two even numbers', async function () { - const a = 42304n; - const b = 84346n; - expect(await this.mock.$average(a, b)).to.equal((a + b) / 2n); - }); - - it('is correctly calculated with one even and one odd number', async function () { - const a = 57417n; - const b = 84346n; - expect(await this.mock.$average(a, b)).to.equal((a + b) / 2n); - }); - - it('is correctly calculated with two max uint256 numbers', async function () { - const a = ethers.MaxUint256; - expect(await this.mock.$average(a, a)).to.equal(a); - }); - }); - - describe('ceilDiv', function () { - it('reverts on zero division', async function () { - const a = 2n; - const b = 0n; - // It's unspecified because it's a low level 0 division error - await expect(this.mock.$ceilDiv(a, b)).to.be.revertedWithPanic(PANIC_CODES.DIVISION_BY_ZERO); - }); - - it('does not round up a zero result', async function () { - const a = 0n; - const b = 2n; - const r = 0n; - expect(await this.mock.$ceilDiv(a, b)).to.equal(r); - }); - - it('does not round up on exact division', async function () { - const a = 10n; - const b = 5n; - const r = 2n; - expect(await this.mock.$ceilDiv(a, b)).to.equal(r); - }); - - it('rounds up on division with remainders', async function () { - const a = 42n; - const b = 13n; - const r = 4n; - expect(await this.mock.$ceilDiv(a, b)).to.equal(r); - }); - - it('does not overflow', async function () { - const a = ethers.MaxUint256; - const b = 2n; - const r = 1n << 255n; - expect(await this.mock.$ceilDiv(a, b)).to.equal(r); - }); - - it('correctly computes max uint256 divided by 1', async function () { - const a = ethers.MaxUint256; - const b = 1n; - const r = ethers.MaxUint256; - expect(await this.mock.$ceilDiv(a, b)).to.equal(r); - }); - }); - - describe('mulDiv', function () { - it('divide by 0', async function () { - const a = 1n; - const b = 1n; - const c = 0n; - await expect(this.mock.$mulDiv(a, b, c, Rounding.Floor)).to.be.revertedWithPanic(PANIC_CODES.DIVISION_BY_ZERO); - }); - - it('reverts with result higher than 2 ^ 256', async function () { - const a = 5n; - const b = ethers.MaxUint256; - const c = 2n; - await expect(this.mock.$mulDiv(a, b, c, Rounding.Floor)).to.be.revertedWithPanic( - PANIC_CODES.ARITHMETIC_UNDER_OR_OVERFLOW, - ); - }); - - describe('does round down', function () { - it('small values', async function () { - for (const rounding of RoundingDown) { - expect(await this.mock.$mulDiv(3n, 4n, 5n, rounding)).to.equal(2n); - expect(await this.mock.$mulDiv(3n, 5n, 5n, rounding)).to.equal(3n); - } - }); - - it('large values', async function () { - for (const rounding of RoundingDown) { - expect(await this.mock.$mulDiv(42n, ethers.MaxUint256 - 1n, ethers.MaxUint256, rounding)).to.equal(41n); - - expect(await this.mock.$mulDiv(17n, ethers.MaxUint256, ethers.MaxUint256, rounding)).to.equal(17n); - - expect( - await this.mock.$mulDiv(ethers.MaxUint256 - 1n, ethers.MaxUint256 - 1n, ethers.MaxUint256, rounding), - ).to.equal(ethers.MaxUint256 - 2n); - - expect( - await this.mock.$mulDiv(ethers.MaxUint256, ethers.MaxUint256 - 1n, ethers.MaxUint256, rounding), - ).to.equal(ethers.MaxUint256 - 1n); - - expect(await this.mock.$mulDiv(ethers.MaxUint256, ethers.MaxUint256, ethers.MaxUint256, rounding)).to.equal( - ethers.MaxUint256, - ); - } - }); - }); - - describe('does round up', function () { - it('small values', async function () { - for (const rounding of RoundingUp) { - expect(await this.mock.$mulDiv(3n, 4n, 5n, rounding)).to.equal(3n); - expect(await this.mock.$mulDiv(3n, 5n, 5n, rounding)).to.equal(3n); - } - }); - - it('large values', async function () { - for (const rounding of RoundingUp) { - expect(await this.mock.$mulDiv(42n, ethers.MaxUint256 - 1n, ethers.MaxUint256, rounding)).to.equal(42n); - - expect(await this.mock.$mulDiv(17n, ethers.MaxUint256, ethers.MaxUint256, rounding)).to.equal(17n); - - expect( - await this.mock.$mulDiv(ethers.MaxUint256 - 1n, ethers.MaxUint256 - 1n, ethers.MaxUint256, rounding), - ).to.equal(ethers.MaxUint256 - 1n); - - expect( - await this.mock.$mulDiv(ethers.MaxUint256, ethers.MaxUint256 - 1n, ethers.MaxUint256, rounding), - ).to.equal(ethers.MaxUint256 - 1n); - - expect(await this.mock.$mulDiv(ethers.MaxUint256, ethers.MaxUint256, ethers.MaxUint256, rounding)).to.equal( - ethers.MaxUint256, - ); - } - }); - }); - }); - - describe('invMod', function () { - for (const factors of [ - [0n], - [1n], - [2n], - [17n], - [65537n], - [0xffffffff00000001000000000000000000000000ffffffffffffffffffffffffn], - [3n, 5n], - [3n, 7n], - [47n, 53n], - ]) { - const p = factors.reduce((acc, f) => acc * f, 1n); - - describe(`using p=${p} which is ${p > 1 && factors.length > 1 ? 'not ' : ''}a prime`, function () { - it('trying to inverse 0 returns 0', async function () { - expect(await this.mock.$invMod(0, p)).to.equal(0n); - expect(await this.mock.$invMod(p, p)).to.equal(0n); // p is 0 mod p - }); - - if (p != 0) { - for (const value of Array.from({ length: 16 }, generators.uint256)) { - const isInversible = factors.every(f => value % f); - it(`trying to inverse ${value}`, async function () { - const result = await this.mock.$invMod(value, p); - if (isInversible) { - expect((value * result) % p).to.equal(1n); - } else { - expect(result).to.equal(0n); - } - }); - } - } - }); - } - }); - - describe('modExp', function () { - for (const [name, type] of Object.entries({ uint256, bytes })) { - describe(`with ${name} inputs`, function () { - it('is correctly calculating modulus', async function () { - const b = 3n; - const e = 200n; - const m = 50n; - - expect(await this.mock.$modExp(type(b), type(e), type(m))).to.equal(type(b ** e % m).value); - }); - - it('is correctly reverting when modulus is zero', async function () { - const b = 3n; - const e = 200n; - const m = 0n; - - await expect(this.mock.$modExp(type(b), type(e), type(m))).to.be.revertedWithPanic( - PANIC_CODES.DIVISION_BY_ZERO, - ); - }); - }); - } - - describe('with large bytes inputs', function () { - for (const [[b, log2b], [e, log2e], [m, log2m]] of product( - range(320, 512, 64).map(e => [2n ** BigInt(e) + 1n, e]), - range(320, 512, 64).map(e => [2n ** BigInt(e) + 1n, e]), - range(320, 512, 64).map(e => [2n ** BigInt(e) + 1n, e]), - )) { - it(`calculates b ** e % m (b=2**${log2b}+1) (e=2**${log2e}+1) (m=2**${log2m}+1)`, async function () { - const mLength = ethers.dataLength(ethers.toBeHex(m)); - - expect(await this.mock.$modExp(bytes(b), bytes(e), bytes(m))).to.equal(bytes(modExp(b, e, m), mLength).value); - }); - } - }); - }); - - describe('tryModExp', function () { - for (const [name, type] of Object.entries({ uint256, bytes })) { - describe(`with ${name} inputs`, function () { - it('is correctly calculating modulus', async function () { - const b = 3n; - const e = 200n; - const m = 50n; - - expect(await this.mock.$tryModExp(type(b), type(e), type(m))).to.deep.equal([true, type(b ** e % m).value]); - }); - - it('is correctly reverting when modulus is zero', async function () { - const b = 3n; - const e = 200n; - const m = 0n; - - expect(await this.mock.$tryModExp(type(b), type(e), type(m))).to.deep.equal([false, type.zero]); - }); - }); - } - - describe('with large bytes inputs', function () { - for (const [[b, log2b], [e, log2e], [m, log2m]] of product( - range(320, 513, 64).map(e => [2n ** BigInt(e) + 1n, e]), - range(320, 513, 64).map(e => [2n ** BigInt(e) + 1n, e]), - range(320, 513, 64).map(e => [2n ** BigInt(e) + 1n, e]), - )) { - it(`calculates b ** e % m (b=2**${log2b}+1) (e=2**${log2e}+1) (m=2**${log2m}+1)`, async function () { - const mLength = ethers.dataLength(ethers.toBeHex(m)); - - expect(await this.mock.$tryModExp(bytes(b), bytes(e), bytes(m))).to.deep.equal([ - true, - bytes(modExp(b, e, m), mLength).value, - ]); - }); - } - }); - }); - - describe('sqrt', function () { - it('rounds down', async function () { - for (const rounding of RoundingDown) { - expect(await this.mock.$sqrt(0n, rounding)).to.equal(0n); - expect(await this.mock.$sqrt(1n, rounding)).to.equal(1n); - expect(await this.mock.$sqrt(2n, rounding)).to.equal(1n); - expect(await this.mock.$sqrt(3n, rounding)).to.equal(1n); - expect(await this.mock.$sqrt(4n, rounding)).to.equal(2n); - expect(await this.mock.$sqrt(144n, rounding)).to.equal(12n); - expect(await this.mock.$sqrt(999999n, rounding)).to.equal(999n); - expect(await this.mock.$sqrt(1000000n, rounding)).to.equal(1000n); - expect(await this.mock.$sqrt(1000001n, rounding)).to.equal(1000n); - expect(await this.mock.$sqrt(1002000n, rounding)).to.equal(1000n); - expect(await this.mock.$sqrt(1002001n, rounding)).to.equal(1001n); - expect(await this.mock.$sqrt(ethers.MaxUint256, rounding)).to.equal(340282366920938463463374607431768211455n); - } - }); - - it('rounds up', async function () { - for (const rounding of RoundingUp) { - expect(await this.mock.$sqrt(0n, rounding)).to.equal(0n); - expect(await this.mock.$sqrt(1n, rounding)).to.equal(1n); - expect(await this.mock.$sqrt(2n, rounding)).to.equal(2n); - expect(await this.mock.$sqrt(3n, rounding)).to.equal(2n); - expect(await this.mock.$sqrt(4n, rounding)).to.equal(2n); - expect(await this.mock.$sqrt(144n, rounding)).to.equal(12n); - expect(await this.mock.$sqrt(999999n, rounding)).to.equal(1000n); - expect(await this.mock.$sqrt(1000000n, rounding)).to.equal(1000n); - expect(await this.mock.$sqrt(1000001n, rounding)).to.equal(1001n); - expect(await this.mock.$sqrt(1002000n, rounding)).to.equal(1001n); - expect(await this.mock.$sqrt(1002001n, rounding)).to.equal(1001n); - expect(await this.mock.$sqrt(ethers.MaxUint256, rounding)).to.equal(340282366920938463463374607431768211456n); - } - }); - }); - - describe('log', function () { - describe('log2', function () { - it('rounds down', async function () { - for (const rounding of RoundingDown) { - expect(await this.mock.$log2(0n, rounding)).to.equal(0n); - expect(await this.mock.$log2(1n, rounding)).to.equal(0n); - expect(await this.mock.$log2(2n, rounding)).to.equal(1n); - expect(await this.mock.$log2(3n, rounding)).to.equal(1n); - expect(await this.mock.$log2(4n, rounding)).to.equal(2n); - expect(await this.mock.$log2(5n, rounding)).to.equal(2n); - expect(await this.mock.$log2(6n, rounding)).to.equal(2n); - expect(await this.mock.$log2(7n, rounding)).to.equal(2n); - expect(await this.mock.$log2(8n, rounding)).to.equal(3n); - expect(await this.mock.$log2(9n, rounding)).to.equal(3n); - expect(await this.mock.$log2(ethers.MaxUint256, rounding)).to.equal(255n); - } - }); - - it('rounds up', async function () { - for (const rounding of RoundingUp) { - expect(await this.mock.$log2(0n, rounding)).to.equal(0n); - expect(await this.mock.$log2(1n, rounding)).to.equal(0n); - expect(await this.mock.$log2(2n, rounding)).to.equal(1n); - expect(await this.mock.$log2(3n, rounding)).to.equal(2n); - expect(await this.mock.$log2(4n, rounding)).to.equal(2n); - expect(await this.mock.$log2(5n, rounding)).to.equal(3n); - expect(await this.mock.$log2(6n, rounding)).to.equal(3n); - expect(await this.mock.$log2(7n, rounding)).to.equal(3n); - expect(await this.mock.$log2(8n, rounding)).to.equal(3n); - expect(await this.mock.$log2(9n, rounding)).to.equal(4n); - expect(await this.mock.$log2(ethers.MaxUint256, rounding)).to.equal(256n); - } - }); - }); - - describe('log10', function () { - it('rounds down', async function () { - for (const rounding of RoundingDown) { - expect(await this.mock.$log10(0n, rounding)).to.equal(0n); - expect(await this.mock.$log10(1n, rounding)).to.equal(0n); - expect(await this.mock.$log10(2n, rounding)).to.equal(0n); - expect(await this.mock.$log10(9n, rounding)).to.equal(0n); - expect(await this.mock.$log10(10n, rounding)).to.equal(1n); - expect(await this.mock.$log10(11n, rounding)).to.equal(1n); - expect(await this.mock.$log10(99n, rounding)).to.equal(1n); - expect(await this.mock.$log10(100n, rounding)).to.equal(2n); - expect(await this.mock.$log10(101n, rounding)).to.equal(2n); - expect(await this.mock.$log10(999n, rounding)).to.equal(2n); - expect(await this.mock.$log10(1000n, rounding)).to.equal(3n); - expect(await this.mock.$log10(1001n, rounding)).to.equal(3n); - expect(await this.mock.$log10(ethers.MaxUint256, rounding)).to.equal(77n); - } - }); - - it('rounds up', async function () { - for (const rounding of RoundingUp) { - expect(await this.mock.$log10(0n, rounding)).to.equal(0n); - expect(await this.mock.$log10(1n, rounding)).to.equal(0n); - expect(await this.mock.$log10(2n, rounding)).to.equal(1n); - expect(await this.mock.$log10(9n, rounding)).to.equal(1n); - expect(await this.mock.$log10(10n, rounding)).to.equal(1n); - expect(await this.mock.$log10(11n, rounding)).to.equal(2n); - expect(await this.mock.$log10(99n, rounding)).to.equal(2n); - expect(await this.mock.$log10(100n, rounding)).to.equal(2n); - expect(await this.mock.$log10(101n, rounding)).to.equal(3n); - expect(await this.mock.$log10(999n, rounding)).to.equal(3n); - expect(await this.mock.$log10(1000n, rounding)).to.equal(3n); - expect(await this.mock.$log10(1001n, rounding)).to.equal(4n); - expect(await this.mock.$log10(ethers.MaxUint256, rounding)).to.equal(78n); - } - }); - }); - - describe('log256', function () { - it('rounds down', async function () { - for (const rounding of RoundingDown) { - expect(await this.mock.$log256(0n, rounding)).to.equal(0n); - expect(await this.mock.$log256(1n, rounding)).to.equal(0n); - expect(await this.mock.$log256(2n, rounding)).to.equal(0n); - expect(await this.mock.$log256(255n, rounding)).to.equal(0n); - expect(await this.mock.$log256(256n, rounding)).to.equal(1n); - expect(await this.mock.$log256(257n, rounding)).to.equal(1n); - expect(await this.mock.$log256(65535n, rounding)).to.equal(1n); - expect(await this.mock.$log256(65536n, rounding)).to.equal(2n); - expect(await this.mock.$log256(65537n, rounding)).to.equal(2n); - expect(await this.mock.$log256(ethers.MaxUint256, rounding)).to.equal(31n); - } - }); - - it('rounds up', async function () { - for (const rounding of RoundingUp) { - expect(await this.mock.$log256(0n, rounding)).to.equal(0n); - expect(await this.mock.$log256(1n, rounding)).to.equal(0n); - expect(await this.mock.$log256(2n, rounding)).to.equal(1n); - expect(await this.mock.$log256(255n, rounding)).to.equal(1n); - expect(await this.mock.$log256(256n, rounding)).to.equal(1n); - expect(await this.mock.$log256(257n, rounding)).to.equal(2n); - expect(await this.mock.$log256(65535n, rounding)).to.equal(2n); - expect(await this.mock.$log256(65536n, rounding)).to.equal(2n); - expect(await this.mock.$log256(65537n, rounding)).to.equal(3n); - expect(await this.mock.$log256(ethers.MaxUint256, rounding)).to.equal(32n); - } - }); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/utils/math/SafeCast.test.js b/lib/openzeppelin-contracts/test/utils/math/SafeCast.test.js deleted file mode 100644 index ab62406..0000000 --- a/lib/openzeppelin-contracts/test/utils/math/SafeCast.test.js +++ /dev/null @@ -1,159 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { range } = require('../../helpers/iterate'); - -async function fixture() { - const mock = await ethers.deployContract('$SafeCast'); - return { mock }; -} - -describe('SafeCast', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - for (const bits of range(8, 256, 8).map(ethers.toBigInt)) { - const maxValue = 2n ** bits - 1n; - - describe(`toUint${bits}`, () => { - it('downcasts 0', async function () { - expect(await this.mock[`$toUint${bits}`](0n)).is.equal(0n); - }); - - it('downcasts 1', async function () { - expect(await this.mock[`$toUint${bits}`](1n)).is.equal(1n); - }); - - it(`downcasts 2^${bits} - 1 (${maxValue})`, async function () { - expect(await this.mock[`$toUint${bits}`](maxValue)).is.equal(maxValue); - }); - - it(`reverts when downcasting 2^${bits} (${maxValue + 1n})`, async function () { - await expect(this.mock[`$toUint${bits}`](maxValue + 1n)) - .to.be.revertedWithCustomError(this.mock, 'SafeCastOverflowedUintDowncast') - .withArgs(bits, maxValue + 1n); - }); - - it(`reverts when downcasting 2^${bits} + 1 (${maxValue + 2n})`, async function () { - await expect(this.mock[`$toUint${bits}`](maxValue + 2n)) - .to.be.revertedWithCustomError(this.mock, 'SafeCastOverflowedUintDowncast') - .withArgs(bits, maxValue + 2n); - }); - }); - } - - describe('toUint256', () => { - it('casts 0', async function () { - expect(await this.mock.$toUint256(0n)).is.equal(0n); - }); - - it('casts 1', async function () { - expect(await this.mock.$toUint256(1n)).is.equal(1n); - }); - - it(`casts INT256_MAX (${ethers.MaxInt256})`, async function () { - expect(await this.mock.$toUint256(ethers.MaxInt256)).is.equal(ethers.MaxInt256); - }); - - it('reverts when casting -1', async function () { - await expect(this.mock.$toUint256(-1n)) - .to.be.revertedWithCustomError(this.mock, 'SafeCastOverflowedIntToUint') - .withArgs(-1n); - }); - - it(`reverts when casting INT256_MIN (${ethers.MinInt256})`, async function () { - await expect(this.mock.$toUint256(ethers.MinInt256)) - .to.be.revertedWithCustomError(this.mock, 'SafeCastOverflowedIntToUint') - .withArgs(ethers.MinInt256); - }); - }); - - for (const bits of range(8, 256, 8).map(ethers.toBigInt)) { - const minValue = -(2n ** (bits - 1n)); - const maxValue = 2n ** (bits - 1n) - 1n; - - describe(`toInt${bits}`, () => { - it('downcasts 0', async function () { - expect(await this.mock[`$toInt${bits}`](0n)).is.equal(0n); - }); - - it('downcasts 1', async function () { - expect(await this.mock[`$toInt${bits}`](1n)).is.equal(1n); - }); - - it('downcasts -1', async function () { - expect(await this.mock[`$toInt${bits}`](-1n)).is.equal(-1n); - }); - - it(`downcasts -2^${bits - 1n} (${minValue})`, async function () { - expect(await this.mock[`$toInt${bits}`](minValue)).is.equal(minValue); - }); - - it(`downcasts 2^${bits - 1n} - 1 (${maxValue})`, async function () { - expect(await this.mock[`$toInt${bits}`](maxValue)).is.equal(maxValue); - }); - - it(`reverts when downcasting -2^${bits - 1n} - 1 (${minValue - 1n})`, async function () { - await expect(this.mock[`$toInt${bits}`](minValue - 1n)) - .to.be.revertedWithCustomError(this.mock, 'SafeCastOverflowedIntDowncast') - .withArgs(bits, minValue - 1n); - }); - - it(`reverts when downcasting -2^${bits - 1n} - 2 (${minValue - 2n})`, async function () { - await expect(this.mock[`$toInt${bits}`](minValue - 2n)) - .to.be.revertedWithCustomError(this.mock, 'SafeCastOverflowedIntDowncast') - .withArgs(bits, minValue - 2n); - }); - - it(`reverts when downcasting 2^${bits - 1n} (${maxValue + 1n})`, async function () { - await expect(this.mock[`$toInt${bits}`](maxValue + 1n)) - .to.be.revertedWithCustomError(this.mock, 'SafeCastOverflowedIntDowncast') - .withArgs(bits, maxValue + 1n); - }); - - it(`reverts when downcasting 2^${bits - 1n} + 1 (${maxValue + 2n})`, async function () { - await expect(this.mock[`$toInt${bits}`](maxValue + 2n)) - .to.be.revertedWithCustomError(this.mock, 'SafeCastOverflowedIntDowncast') - .withArgs(bits, maxValue + 2n); - }); - }); - } - - describe('toInt256', () => { - it('casts 0', async function () { - expect(await this.mock.$toInt256(0)).is.equal(0n); - }); - - it('casts 1', async function () { - expect(await this.mock.$toInt256(1)).is.equal(1n); - }); - - it(`casts INT256_MAX (${ethers.MaxInt256})`, async function () { - expect(await this.mock.$toInt256(ethers.MaxInt256)).is.equal(ethers.MaxInt256); - }); - - it(`reverts when casting INT256_MAX + 1 (${ethers.MaxInt256 + 1n})`, async function () { - await expect(this.mock.$toInt256(ethers.MaxInt256 + 1n)) - .to.be.revertedWithCustomError(this.mock, 'SafeCastOverflowedUintToInt') - .withArgs(ethers.MaxInt256 + 1n); - }); - - it(`reverts when casting UINT256_MAX (${ethers.MaxUint256})`, async function () { - await expect(this.mock.$toInt256(ethers.MaxUint256)) - .to.be.revertedWithCustomError(this.mock, 'SafeCastOverflowedUintToInt') - .withArgs(ethers.MaxUint256); - }); - }); - - describe('toUint (bool)', function () { - it('toUint(false) should be 0', async function () { - expect(await this.mock.$toUint(false)).to.equal(0n); - }); - - it('toUint(true) should be 1', async function () { - expect(await this.mock.$toUint(true)).to.equal(1n); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/utils/math/SignedMath.t.sol b/lib/openzeppelin-contracts/test/utils/math/SignedMath.t.sol deleted file mode 100644 index bbad109..0000000 --- a/lib/openzeppelin-contracts/test/utils/math/SignedMath.t.sol +++ /dev/null @@ -1,80 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.20; - -import {Test} from "forge-std/Test.sol"; - -import {Math} from "../../../contracts/utils/math/Math.sol"; -import {SignedMath} from "../../../contracts/utils/math/SignedMath.sol"; - -contract SignedMathTest is Test { - function testSymbolicTernary(bool f, int256 a, int256 b) public { - assertEq(SignedMath.ternary(f, a, b), f ? a : b); - } - - // MIN & MAX - function testSymbolicMinMax(int256 a, int256 b) public { - assertEq(SignedMath.min(a, b), a < b ? a : b); - assertEq(SignedMath.max(a, b), a > b ? a : b); - } - - // MIN - function testSymbolicMin(int256 a, int256 b) public { - int256 result = SignedMath.min(a, b); - - assertLe(result, a); - assertLe(result, b); - assertTrue(result == a || result == b); - } - - // MAX - function testSymbolicMax(int256 a, int256 b) public { - int256 result = SignedMath.max(a, b); - - assertGe(result, a); - assertGe(result, b); - assertTrue(result == a || result == b); - } - - // AVERAGE - // 1. simple test, not full int256 range - function testAverage1(int256 a, int256 b) public { - a = bound(a, type(int256).min / 2, type(int256).max / 2); - b = bound(b, type(int256).min / 2, type(int256).max / 2); - - int256 result = SignedMath.average(a, b); - - assertEq(result, (a + b) / 2); - } - - // 2. more complex test, full int256 range - function testAverage2(int256 a, int256 b) public { - (int256 result, int256 min, int256 max) = ( - SignedMath.average(a, b), - SignedMath.min(a, b), - SignedMath.max(a, b) - ); - - // average must be between `a` and `b` - assertGe(result, min); - assertLe(result, max); - - unchecked { - // must be unchecked in order to support `a = type(int256).min, b = type(int256).max` - uint256 deltaLower = uint256(result - min); - uint256 deltaUpper = uint256(max - result); - uint256 remainder = uint256((a & 1) ^ (b & 1)); - assertEq(remainder, Math.max(deltaLower, deltaUpper) - Math.min(deltaLower, deltaUpper)); - } - } - - // ABS - function testSymbolicAbs(int256 a) public { - uint256 result = SignedMath.abs(a); - - unchecked { - // must be unchecked in order to support `n = type(int256).min` - assertEq(result, a < 0 ? uint256(-a) : uint256(a)); - } - } -} diff --git a/lib/openzeppelin-contracts/test/utils/math/SignedMath.test.js b/lib/openzeppelin-contracts/test/utils/math/SignedMath.test.js deleted file mode 100644 index 877f3b4..0000000 --- a/lib/openzeppelin-contracts/test/utils/math/SignedMath.test.js +++ /dev/null @@ -1,53 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { min, max } = require('../../helpers/math'); - -async function testCommutative(fn, lhs, rhs, expected, ...extra) { - expect(await fn(lhs, rhs, ...extra)).to.deep.equal(expected); - expect(await fn(rhs, lhs, ...extra)).to.deep.equal(expected); -} - -async function fixture() { - const mock = await ethers.deployContract('$SignedMath'); - return { mock }; -} - -describe('SignedMath', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('max', function () { - it('is correctly detected in both position', async function () { - await testCommutative(this.mock.$max, -1234n, 5678n, max(-1234n, 5678n)); - }); - }); - - describe('min', function () { - it('is correctly detected in both position', async function () { - await testCommutative(this.mock.$min, -1234n, 5678n, min(-1234n, 5678n)); - }); - }); - - describe('average', function () { - it('is correctly calculated with various input', async function () { - for (const x of [ethers.MinInt256, -57417n, -42304n, -4n, -3n, 0n, 3n, 4n, 42304n, 57417n, ethers.MaxInt256]) { - for (const y of [ethers.MinInt256, -57417n, -42304n, -5n, -2n, 0n, 2n, 5n, 42304n, 57417n, ethers.MaxInt256]) { - expect(await this.mock.$average(x, y)).to.equal((x + y) / 2n); - } - } - }); - }); - - describe('abs', function () { - const abs = x => (x < 0n ? -x : x); - - for (const n of [ethers.MinInt256, ethers.MinInt256 + 1n, -1n, 0n, 1n, ethers.MaxInt256 - 1n, ethers.MaxInt256]) { - it(`correctly computes the absolute value of ${n}`, async function () { - expect(await this.mock.$abs(n)).to.equal(abs(n)); - }); - } - }); -}); diff --git a/lib/openzeppelin-contracts/test/utils/structs/BitMap.test.js b/lib/openzeppelin-contracts/test/utils/structs/BitMap.test.js deleted file mode 100644 index 5662ab1..0000000 --- a/lib/openzeppelin-contracts/test/utils/structs/BitMap.test.js +++ /dev/null @@ -1,149 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -async function fixture() { - const bitmap = await ethers.deployContract('$BitMaps'); - return { bitmap }; -} - -describe('BitMap', function () { - const keyA = 7891n; - const keyB = 451n; - const keyC = 9592328n; - - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - it('starts empty', async function () { - expect(await this.bitmap.$get(0, keyA)).to.be.false; - expect(await this.bitmap.$get(0, keyB)).to.be.false; - expect(await this.bitmap.$get(0, keyC)).to.be.false; - }); - - describe('setTo', function () { - it('set a key to true', async function () { - await this.bitmap.$setTo(0, keyA, true); - expect(await this.bitmap.$get(0, keyA)).to.be.true; - expect(await this.bitmap.$get(0, keyB)).to.be.false; - expect(await this.bitmap.$get(0, keyC)).to.be.false; - }); - - it('set a key to false', async function () { - await this.bitmap.$setTo(0, keyA, true); - await this.bitmap.$setTo(0, keyA, false); - expect(await this.bitmap.$get(0, keyA)).to.be.false; - expect(await this.bitmap.$get(0, keyB)).to.be.false; - expect(await this.bitmap.$get(0, keyC)).to.be.false; - }); - - it('set several consecutive keys', async function () { - await this.bitmap.$setTo(0, keyA + 0n, true); - await this.bitmap.$setTo(0, keyA + 1n, true); - await this.bitmap.$setTo(0, keyA + 2n, true); - await this.bitmap.$setTo(0, keyA + 3n, true); - await this.bitmap.$setTo(0, keyA + 4n, true); - await this.bitmap.$setTo(0, keyA + 2n, false); - await this.bitmap.$setTo(0, keyA + 4n, false); - expect(await this.bitmap.$get(0, keyA + 0n)).to.be.true; - expect(await this.bitmap.$get(0, keyA + 1n)).to.be.true; - expect(await this.bitmap.$get(0, keyA + 2n)).to.be.false; - expect(await this.bitmap.$get(0, keyA + 3n)).to.be.true; - expect(await this.bitmap.$get(0, keyA + 4n)).to.be.false; - }); - }); - - describe('set', function () { - it('adds a key', async function () { - await this.bitmap.$set(0, keyA); - expect(await this.bitmap.$get(0, keyA)).to.be.true; - expect(await this.bitmap.$get(0, keyB)).to.be.false; - expect(await this.bitmap.$get(0, keyC)).to.be.false; - }); - - it('adds several keys', async function () { - await this.bitmap.$set(0, keyA); - await this.bitmap.$set(0, keyB); - expect(await this.bitmap.$get(0, keyA)).to.be.true; - expect(await this.bitmap.$get(0, keyB)).to.be.true; - expect(await this.bitmap.$get(0, keyC)).to.be.false; - }); - - it('adds several consecutive keys', async function () { - await this.bitmap.$set(0, keyA + 0n); - await this.bitmap.$set(0, keyA + 1n); - await this.bitmap.$set(0, keyA + 3n); - expect(await this.bitmap.$get(0, keyA + 0n)).to.be.true; - expect(await this.bitmap.$get(0, keyA + 1n)).to.be.true; - expect(await this.bitmap.$get(0, keyA + 2n)).to.be.false; - expect(await this.bitmap.$get(0, keyA + 3n)).to.be.true; - expect(await this.bitmap.$get(0, keyA + 4n)).to.be.false; - }); - }); - - describe('unset', function () { - it('removes added keys', async function () { - await this.bitmap.$set(0, keyA); - await this.bitmap.$set(0, keyB); - await this.bitmap.$unset(0, keyA); - expect(await this.bitmap.$get(0, keyA)).to.be.false; - expect(await this.bitmap.$get(0, keyB)).to.be.true; - expect(await this.bitmap.$get(0, keyC)).to.be.false; - }); - - it('removes consecutive added keys', async function () { - await this.bitmap.$set(0, keyA + 0n); - await this.bitmap.$set(0, keyA + 1n); - await this.bitmap.$set(0, keyA + 3n); - await this.bitmap.$unset(0, keyA + 1n); - expect(await this.bitmap.$get(0, keyA + 0n)).to.be.true; - expect(await this.bitmap.$get(0, keyA + 1n)).to.be.false; - expect(await this.bitmap.$get(0, keyA + 2n)).to.be.false; - expect(await this.bitmap.$get(0, keyA + 3n)).to.be.true; - expect(await this.bitmap.$get(0, keyA + 4n)).to.be.false; - }); - - it('adds and removes multiple keys', async function () { - // [] - - await this.bitmap.$set(0, keyA); - await this.bitmap.$set(0, keyC); - - // [A, C] - - await this.bitmap.$unset(0, keyA); - await this.bitmap.$unset(0, keyB); - - // [C] - - await this.bitmap.$set(0, keyB); - - // [C, B] - - await this.bitmap.$set(0, keyA); - await this.bitmap.$unset(0, keyC); - - // [A, B] - - await this.bitmap.$set(0, keyA); - await this.bitmap.$set(0, keyB); - - // [A, B] - - await this.bitmap.$set(0, keyC); - await this.bitmap.$unset(0, keyA); - - // [B, C] - - await this.bitmap.$set(0, keyA); - await this.bitmap.$unset(0, keyB); - - // [A, C] - - expect(await this.bitmap.$get(0, keyA)).to.be.true; - expect(await this.bitmap.$get(0, keyB)).to.be.false; - expect(await this.bitmap.$get(0, keyC)).to.be.true; - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/utils/structs/Checkpoints.t.sol b/lib/openzeppelin-contracts/test/utils/structs/Checkpoints.t.sol deleted file mode 100644 index 1f4b344..0000000 --- a/lib/openzeppelin-contracts/test/utils/structs/Checkpoints.t.sol +++ /dev/null @@ -1,332 +0,0 @@ -// SPDX-License-Identifier: MIT -// This file was procedurally generated from scripts/generate/templates/Checkpoints.t.js. - -pragma solidity ^0.8.20; - -import {Test} from "forge-std/Test.sol"; -import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; -import {Checkpoints} from "@openzeppelin/contracts/utils/structs/Checkpoints.sol"; - -contract CheckpointsTrace224Test is Test { - using Checkpoints for Checkpoints.Trace224; - - // Maximum gap between keys used during the fuzzing tests: the `_prepareKeys` function with make sure that - // key#n+1 is in the [key#n, key#n + _KEY_MAX_GAP] range. - uint8 internal constant _KEY_MAX_GAP = 64; - - Checkpoints.Trace224 internal _ckpts; - - // helpers - function _boundUint32(uint32 x, uint32 min, uint32 max) internal pure returns (uint32) { - return SafeCast.toUint32(bound(uint256(x), uint256(min), uint256(max))); - } - - function _prepareKeys(uint32[] memory keys, uint32 maxSpread) internal pure { - uint32 lastKey = 0; - for (uint256 i = 0; i < keys.length; ++i) { - uint32 key = _boundUint32(keys[i], lastKey, lastKey + maxSpread); - keys[i] = key; - lastKey = key; - } - } - - function _assertLatestCheckpoint(bool exist, uint32 key, uint224 value) internal { - (bool _exist, uint32 _key, uint224 _value) = _ckpts.latestCheckpoint(); - assertEq(_exist, exist); - assertEq(_key, key); - assertEq(_value, value); - } - - // tests - function testPush(uint32[] memory keys, uint224[] memory values, uint32 pastKey) public { - vm.assume(values.length > 0 && values.length <= keys.length); - _prepareKeys(keys, _KEY_MAX_GAP); - - // initial state - assertEq(_ckpts.length(), 0); - assertEq(_ckpts.latest(), 0); - _assertLatestCheckpoint(false, 0, 0); - - uint256 duplicates = 0; - for (uint256 i = 0; i < keys.length; ++i) { - uint32 key = keys[i]; - uint224 value = values[i % values.length]; - if (i > 0 && key == keys[i - 1]) ++duplicates; - - // push - _ckpts.push(key, value); - - // check length & latest - assertEq(_ckpts.length(), i + 1 - duplicates); - assertEq(_ckpts.latest(), value); - _assertLatestCheckpoint(true, key, value); - } - - if (keys.length > 0) { - uint32 lastKey = keys[keys.length - 1]; - if (lastKey > 0) { - pastKey = _boundUint32(pastKey, 0, lastKey - 1); - - vm.expectRevert(); - this.push(pastKey, values[keys.length % values.length]); - } - } - } - - // used to test reverts - function push(uint32 key, uint224 value) external { - _ckpts.push(key, value); - } - - function testLookup(uint32[] memory keys, uint224[] memory values, uint32 lookup) public { - vm.assume(values.length > 0 && values.length <= keys.length); - _prepareKeys(keys, _KEY_MAX_GAP); - - uint32 lastKey = keys.length == 0 ? 0 : keys[keys.length - 1]; - lookup = _boundUint32(lookup, 0, lastKey + _KEY_MAX_GAP); - - uint224 upper = 0; - uint224 lower = 0; - uint32 lowerKey = type(uint32).max; - for (uint256 i = 0; i < keys.length; ++i) { - uint32 key = keys[i]; - uint224 value = values[i % values.length]; - - // push - _ckpts.push(key, value); - - // track expected result of lookups - if (key <= lookup) { - upper = value; - } - // find the first key that is not smaller than the lookup key - if (key >= lookup && (i == 0 || keys[i - 1] < lookup)) { - lowerKey = key; - } - if (key == lowerKey) { - lower = value; - } - } - - // check lookup - assertEq(_ckpts.lowerLookup(lookup), lower); - assertEq(_ckpts.upperLookup(lookup), upper); - assertEq(_ckpts.upperLookupRecent(lookup), upper); - } -} - -contract CheckpointsTrace208Test is Test { - using Checkpoints for Checkpoints.Trace208; - - // Maximum gap between keys used during the fuzzing tests: the `_prepareKeys` function with make sure that - // key#n+1 is in the [key#n, key#n + _KEY_MAX_GAP] range. - uint8 internal constant _KEY_MAX_GAP = 64; - - Checkpoints.Trace208 internal _ckpts; - - // helpers - function _boundUint48(uint48 x, uint48 min, uint48 max) internal pure returns (uint48) { - return SafeCast.toUint48(bound(uint256(x), uint256(min), uint256(max))); - } - - function _prepareKeys(uint48[] memory keys, uint48 maxSpread) internal pure { - uint48 lastKey = 0; - for (uint256 i = 0; i < keys.length; ++i) { - uint48 key = _boundUint48(keys[i], lastKey, lastKey + maxSpread); - keys[i] = key; - lastKey = key; - } - } - - function _assertLatestCheckpoint(bool exist, uint48 key, uint208 value) internal { - (bool _exist, uint48 _key, uint208 _value) = _ckpts.latestCheckpoint(); - assertEq(_exist, exist); - assertEq(_key, key); - assertEq(_value, value); - } - - // tests - function testPush(uint48[] memory keys, uint208[] memory values, uint48 pastKey) public { - vm.assume(values.length > 0 && values.length <= keys.length); - _prepareKeys(keys, _KEY_MAX_GAP); - - // initial state - assertEq(_ckpts.length(), 0); - assertEq(_ckpts.latest(), 0); - _assertLatestCheckpoint(false, 0, 0); - - uint256 duplicates = 0; - for (uint256 i = 0; i < keys.length; ++i) { - uint48 key = keys[i]; - uint208 value = values[i % values.length]; - if (i > 0 && key == keys[i - 1]) ++duplicates; - - // push - _ckpts.push(key, value); - - // check length & latest - assertEq(_ckpts.length(), i + 1 - duplicates); - assertEq(_ckpts.latest(), value); - _assertLatestCheckpoint(true, key, value); - } - - if (keys.length > 0) { - uint48 lastKey = keys[keys.length - 1]; - if (lastKey > 0) { - pastKey = _boundUint48(pastKey, 0, lastKey - 1); - - vm.expectRevert(); - this.push(pastKey, values[keys.length % values.length]); - } - } - } - - // used to test reverts - function push(uint48 key, uint208 value) external { - _ckpts.push(key, value); - } - - function testLookup(uint48[] memory keys, uint208[] memory values, uint48 lookup) public { - vm.assume(values.length > 0 && values.length <= keys.length); - _prepareKeys(keys, _KEY_MAX_GAP); - - uint48 lastKey = keys.length == 0 ? 0 : keys[keys.length - 1]; - lookup = _boundUint48(lookup, 0, lastKey + _KEY_MAX_GAP); - - uint208 upper = 0; - uint208 lower = 0; - uint48 lowerKey = type(uint48).max; - for (uint256 i = 0; i < keys.length; ++i) { - uint48 key = keys[i]; - uint208 value = values[i % values.length]; - - // push - _ckpts.push(key, value); - - // track expected result of lookups - if (key <= lookup) { - upper = value; - } - // find the first key that is not smaller than the lookup key - if (key >= lookup && (i == 0 || keys[i - 1] < lookup)) { - lowerKey = key; - } - if (key == lowerKey) { - lower = value; - } - } - - // check lookup - assertEq(_ckpts.lowerLookup(lookup), lower); - assertEq(_ckpts.upperLookup(lookup), upper); - assertEq(_ckpts.upperLookupRecent(lookup), upper); - } -} - -contract CheckpointsTrace160Test is Test { - using Checkpoints for Checkpoints.Trace160; - - // Maximum gap between keys used during the fuzzing tests: the `_prepareKeys` function with make sure that - // key#n+1 is in the [key#n, key#n + _KEY_MAX_GAP] range. - uint8 internal constant _KEY_MAX_GAP = 64; - - Checkpoints.Trace160 internal _ckpts; - - // helpers - function _boundUint96(uint96 x, uint96 min, uint96 max) internal pure returns (uint96) { - return SafeCast.toUint96(bound(uint256(x), uint256(min), uint256(max))); - } - - function _prepareKeys(uint96[] memory keys, uint96 maxSpread) internal pure { - uint96 lastKey = 0; - for (uint256 i = 0; i < keys.length; ++i) { - uint96 key = _boundUint96(keys[i], lastKey, lastKey + maxSpread); - keys[i] = key; - lastKey = key; - } - } - - function _assertLatestCheckpoint(bool exist, uint96 key, uint160 value) internal { - (bool _exist, uint96 _key, uint160 _value) = _ckpts.latestCheckpoint(); - assertEq(_exist, exist); - assertEq(_key, key); - assertEq(_value, value); - } - - // tests - function testPush(uint96[] memory keys, uint160[] memory values, uint96 pastKey) public { - vm.assume(values.length > 0 && values.length <= keys.length); - _prepareKeys(keys, _KEY_MAX_GAP); - - // initial state - assertEq(_ckpts.length(), 0); - assertEq(_ckpts.latest(), 0); - _assertLatestCheckpoint(false, 0, 0); - - uint256 duplicates = 0; - for (uint256 i = 0; i < keys.length; ++i) { - uint96 key = keys[i]; - uint160 value = values[i % values.length]; - if (i > 0 && key == keys[i - 1]) ++duplicates; - - // push - _ckpts.push(key, value); - - // check length & latest - assertEq(_ckpts.length(), i + 1 - duplicates); - assertEq(_ckpts.latest(), value); - _assertLatestCheckpoint(true, key, value); - } - - if (keys.length > 0) { - uint96 lastKey = keys[keys.length - 1]; - if (lastKey > 0) { - pastKey = _boundUint96(pastKey, 0, lastKey - 1); - - vm.expectRevert(); - this.push(pastKey, values[keys.length % values.length]); - } - } - } - - // used to test reverts - function push(uint96 key, uint160 value) external { - _ckpts.push(key, value); - } - - function testLookup(uint96[] memory keys, uint160[] memory values, uint96 lookup) public { - vm.assume(values.length > 0 && values.length <= keys.length); - _prepareKeys(keys, _KEY_MAX_GAP); - - uint96 lastKey = keys.length == 0 ? 0 : keys[keys.length - 1]; - lookup = _boundUint96(lookup, 0, lastKey + _KEY_MAX_GAP); - - uint160 upper = 0; - uint160 lower = 0; - uint96 lowerKey = type(uint96).max; - for (uint256 i = 0; i < keys.length; ++i) { - uint96 key = keys[i]; - uint160 value = values[i % values.length]; - - // push - _ckpts.push(key, value); - - // track expected result of lookups - if (key <= lookup) { - upper = value; - } - // find the first key that is not smaller than the lookup key - if (key >= lookup && (i == 0 || keys[i - 1] < lookup)) { - lowerKey = key; - } - if (key == lowerKey) { - lower = value; - } - } - - // check lookup - assertEq(_ckpts.lowerLookup(lookup), lower); - assertEq(_ckpts.upperLookup(lookup), upper); - assertEq(_ckpts.upperLookupRecent(lookup), upper); - } -} diff --git a/lib/openzeppelin-contracts/test/utils/structs/Checkpoints.test.js b/lib/openzeppelin-contracts/test/utils/structs/Checkpoints.test.js deleted file mode 100644 index fd22544..0000000 --- a/lib/openzeppelin-contracts/test/utils/structs/Checkpoints.test.js +++ /dev/null @@ -1,146 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { VALUE_SIZES } = require('../../../scripts/generate/templates/Checkpoints.opts'); - -describe('Checkpoints', function () { - for (const length of VALUE_SIZES) { - describe(`Trace${length}`, function () { - const fixture = async () => { - const mock = await ethers.deployContract('$Checkpoints'); - const methods = { - at: (...args) => mock.getFunction(`$at_Checkpoints_Trace${length}`)(0, ...args), - latest: (...args) => mock.getFunction(`$latest_Checkpoints_Trace${length}`)(0, ...args), - latestCheckpoint: (...args) => mock.getFunction(`$latestCheckpoint_Checkpoints_Trace${length}`)(0, ...args), - length: (...args) => mock.getFunction(`$length_Checkpoints_Trace${length}`)(0, ...args), - push: (...args) => mock.getFunction(`$push(uint256,uint${256 - length},uint${length})`)(0, ...args), - lowerLookup: (...args) => mock.getFunction(`$lowerLookup(uint256,uint${256 - length})`)(0, ...args), - upperLookup: (...args) => mock.getFunction(`$upperLookup(uint256,uint${256 - length})`)(0, ...args), - upperLookupRecent: (...args) => - mock.getFunction(`$upperLookupRecent(uint256,uint${256 - length})`)(0, ...args), - }; - - return { mock, methods }; - }; - - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('without checkpoints', function () { - it('at zero reverts', async function () { - // Reverts with array out of bound access, which is unspecified - await expect(this.methods.at(0)).to.be.reverted; - }); - - it('returns zero as latest value', async function () { - expect(await this.methods.latest()).to.equal(0n); - - const ckpt = await this.methods.latestCheckpoint(); - expect(ckpt[0]).to.be.false; - expect(ckpt[1]).to.equal(0n); - expect(ckpt[2]).to.equal(0n); - }); - - it('lookup returns 0', async function () { - expect(await this.methods.lowerLookup(0)).to.equal(0n); - expect(await this.methods.upperLookup(0)).to.equal(0n); - expect(await this.methods.upperLookupRecent(0)).to.equal(0n); - }); - }); - - describe('with checkpoints', function () { - beforeEach('pushing checkpoints', async function () { - this.checkpoints = [ - { key: 2n, value: 17n }, - { key: 3n, value: 42n }, - { key: 5n, value: 101n }, - { key: 7n, value: 23n }, - { key: 11n, value: 99n }, - ]; - for (const { key, value } of this.checkpoints) { - await this.methods.push(key, value); - } - }); - - it('at keys', async function () { - for (const [index, { key, value }] of this.checkpoints.entries()) { - const at = await this.methods.at(index); - expect(at._value).to.equal(value); - expect(at._key).to.equal(key); - } - }); - - it('length', async function () { - expect(await this.methods.length()).to.equal(this.checkpoints.length); - }); - - it('returns latest value', async function () { - const latest = this.checkpoints.at(-1); - expect(await this.methods.latest()).to.equal(latest.value); - expect(await this.methods.latestCheckpoint()).to.deep.equal([true, latest.key, latest.value]); - }); - - it('cannot push values in the past', async function () { - await expect(this.methods.push(this.checkpoints.at(-1).key - 1n, 0n)).to.be.revertedWithCustomError( - this.mock, - 'CheckpointUnorderedInsertion', - ); - }); - - it('can update last value', async function () { - const newValue = 42n; - - // check length before the update - expect(await this.methods.length()).to.equal(this.checkpoints.length); - - // update last key - await this.methods.push(this.checkpoints.at(-1).key, newValue); - expect(await this.methods.latest()).to.equal(newValue); - - // check that length did not change - expect(await this.methods.length()).to.equal(this.checkpoints.length); - }); - - it('lower lookup', async function () { - for (let i = 0; i < 14; ++i) { - const value = this.checkpoints.find(x => i <= x.key)?.value || 0n; - - expect(await this.methods.lowerLookup(i)).to.equal(value); - } - }); - - it('upper lookup & upperLookupRecent', async function () { - for (let i = 0; i < 14; ++i) { - const value = this.checkpoints.findLast(x => i >= x.key)?.value || 0n; - - expect(await this.methods.upperLookup(i)).to.equal(value); - expect(await this.methods.upperLookupRecent(i)).to.equal(value); - } - }); - - it('upperLookupRecent with more than 5 checkpoints', async function () { - const moreCheckpoints = [ - { key: 12n, value: 22n }, - { key: 13n, value: 131n }, - { key: 17n, value: 45n }, - { key: 19n, value: 31452n }, - { key: 21n, value: 0n }, - ]; - const allCheckpoints = [].concat(this.checkpoints, moreCheckpoints); - - for (const { key, value } of moreCheckpoints) { - await this.methods.push(key, value); - } - - for (let i = 0; i < 25; ++i) { - const value = allCheckpoints.findLast(x => i >= x.key)?.value || 0n; - expect(await this.methods.upperLookup(i)).to.equal(value); - expect(await this.methods.upperLookupRecent(i)).to.equal(value); - } - }); - }); - }); - } -}); diff --git a/lib/openzeppelin-contracts/test/utils/structs/CircularBuffer.test.js b/lib/openzeppelin-contracts/test/utils/structs/CircularBuffer.test.js deleted file mode 100644 index c3d61aa..0000000 --- a/lib/openzeppelin-contracts/test/utils/structs/CircularBuffer.test.js +++ /dev/null @@ -1,79 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); - -const { generators } = require('../../helpers/random'); - -const LENGTH = 4; - -async function fixture() { - const mock = await ethers.deployContract('$CircularBuffer'); - await mock.$setup(0, LENGTH); - return { mock }; -} - -describe('CircularBuffer', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - it('starts empty', async function () { - expect(await this.mock.$count(0)).to.equal(0n); - expect(await this.mock.$length(0)).to.equal(LENGTH); - expect(await this.mock.$includes(0, ethers.ZeroHash)).to.be.false; - await expect(this.mock.$last(0, 0)).to.be.revertedWithPanic(PANIC_CODES.ARRAY_ACCESS_OUT_OF_BOUNDS); - }); - - it('push', async function () { - const values = Array.from({ length: LENGTH + 3 }, generators.bytes32); - - for (const [i, value] of values.map((v, i) => [i, v])) { - // push value - await this.mock.$push(0, value); - - // view of the values - const pushed = values.slice(0, i + 1); - const stored = pushed.slice(-LENGTH); - const dropped = pushed.slice(0, -LENGTH); - - // check count - expect(await this.mock.$length(0)).to.equal(LENGTH); - expect(await this.mock.$count(0)).to.equal(stored.length); - - // check last - for (const j in stored) { - expect(await this.mock.$last(0, j)).to.equal(stored.at(-j - 1)); - } - await expect(this.mock.$last(0, stored.length + 1)).to.be.revertedWithPanic( - PANIC_CODES.ARRAY_ACCESS_OUT_OF_BOUNDS, - ); - - // check included and non-included values - for (const v of stored) { - expect(await this.mock.$includes(0, v)).to.be.true; - } - for (const v of dropped) { - expect(await this.mock.$includes(0, v)).to.be.false; - } - expect(await this.mock.$includes(0, ethers.ZeroHash)).to.be.false; - } - }); - - it('clear', async function () { - const value = generators.bytes32(); - await this.mock.$push(0, value); - - expect(await this.mock.$count(0)).to.equal(1n); - expect(await this.mock.$length(0)).to.equal(LENGTH); - expect(await this.mock.$includes(0, value)).to.be.true; - await this.mock.$last(0, 0); // not revert - - await this.mock.$clear(0); - - expect(await this.mock.$count(0)).to.equal(0n); - expect(await this.mock.$length(0)).to.equal(LENGTH); - expect(await this.mock.$includes(0, value)).to.be.false; - await expect(this.mock.$last(0, 0)).to.be.revertedWithPanic(PANIC_CODES.ARRAY_ACCESS_OUT_OF_BOUNDS); - }); -}); diff --git a/lib/openzeppelin-contracts/test/utils/structs/DoubleEndedQueue.test.js b/lib/openzeppelin-contracts/test/utils/structs/DoubleEndedQueue.test.js deleted file mode 100644 index 3615dfb..0000000 --- a/lib/openzeppelin-contracts/test/utils/structs/DoubleEndedQueue.test.js +++ /dev/null @@ -1,102 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); - -async function fixture() { - const mock = await ethers.deployContract('$DoubleEndedQueue'); - - /** Rebuild the content of the deque as a JS array. */ - const getContent = () => - mock.$length(0).then(length => Promise.all(Array.from({ length: Number(length) }, (_, i) => mock.$at(0, i)))); - - return { mock, getContent }; -} - -describe('DoubleEndedQueue', function () { - const coder = ethers.AbiCoder.defaultAbiCoder(); - const bytesA = coder.encode(['uint256'], [0xdeadbeef]); - const bytesB = coder.encode(['uint256'], [0x0123456789]); - const bytesC = coder.encode(['uint256'], [0x42424242]); - const bytesD = coder.encode(['uint256'], [0x171717]); - - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('when empty', function () { - it('getters', async function () { - expect(await this.mock.$empty(0)).to.be.true; - expect(await this.getContent()).to.have.ordered.members([]); - }); - - it('reverts on accesses', async function () { - await expect(this.mock.$popBack(0)).to.be.revertedWithPanic(PANIC_CODES.POP_ON_EMPTY_ARRAY); - await expect(this.mock.$popFront(0)).to.be.revertedWithPanic(PANIC_CODES.POP_ON_EMPTY_ARRAY); - await expect(this.mock.$back(0)).to.be.revertedWithPanic(PANIC_CODES.ARRAY_ACCESS_OUT_OF_BOUNDS); - await expect(this.mock.$front(0)).to.be.revertedWithPanic(PANIC_CODES.ARRAY_ACCESS_OUT_OF_BOUNDS); - }); - }); - - describe('when not empty', function () { - beforeEach(async function () { - await this.mock.$pushBack(0, bytesB); - await this.mock.$pushFront(0, bytesA); - await this.mock.$pushBack(0, bytesC); - this.content = [bytesA, bytesB, bytesC]; - }); - - it('getters', async function () { - expect(await this.mock.$empty(0)).to.be.false; - expect(await this.mock.$length(0)).to.equal(this.content.length); - expect(await this.mock.$front(0)).to.equal(this.content[0]); - expect(await this.mock.$back(0)).to.equal(this.content[this.content.length - 1]); - expect(await this.getContent()).to.have.ordered.members(this.content); - }); - - it('out of bounds access', async function () { - await expect(this.mock.$at(0, this.content.length)).to.be.revertedWithPanic( - PANIC_CODES.ARRAY_ACCESS_OUT_OF_BOUNDS, - ); - }); - - describe('push', function () { - it('front', async function () { - await this.mock.$pushFront(0, bytesD); - this.content.unshift(bytesD); // add element at the beginning - - expect(await this.getContent()).to.have.ordered.members(this.content); - }); - - it('back', async function () { - await this.mock.$pushBack(0, bytesD); - this.content.push(bytesD); // add element at the end - - expect(await this.getContent()).to.have.ordered.members(this.content); - }); - }); - - describe('pop', function () { - it('front', async function () { - const value = this.content.shift(); // remove first element - await expect(this.mock.$popFront(0)).to.emit(this.mock, 'return$popFront').withArgs(value); - - expect(await this.getContent()).to.have.ordered.members(this.content); - }); - - it('back', async function () { - const value = this.content.pop(); // remove last element - await expect(this.mock.$popBack(0)).to.emit(this.mock, 'return$popBack').withArgs(value); - - expect(await this.getContent()).to.have.ordered.members(this.content); - }); - }); - - it('clear', async function () { - await this.mock.$clear(0); - - expect(await this.mock.$empty(0)).to.be.true; - expect(await this.getContent()).to.have.ordered.members([]); - }); - }); -}); diff --git a/lib/openzeppelin-contracts/test/utils/structs/EnumerableMap.behavior.js b/lib/openzeppelin-contracts/test/utils/structs/EnumerableMap.behavior.js deleted file mode 100644 index 37da417..0000000 --- a/lib/openzeppelin-contracts/test/utils/structs/EnumerableMap.behavior.js +++ /dev/null @@ -1,151 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); - -const zip = (array1, array2) => array1.map((item, index) => [item, array2[index]]); - -function shouldBehaveLikeMap() { - async function expectMembersMatch(methods, keys, values) { - expect(keys.length).to.equal(values.length); - expect(await methods.length()).to.equal(keys.length); - expect([...(await methods.keys())]).to.have.members(keys); - - for (const [key, value] of zip(keys, values)) { - expect(await methods.contains(key)).to.be.true; - expect(await methods.get(key)).to.equal(value); - } - - expect(await Promise.all(keys.map((_, index) => methods.at(index)))).to.have.deep.members(zip(keys, values)); - } - - it('starts empty', async function () { - expect(await this.methods.contains(this.keyA)).to.be.false; - - await expectMembersMatch(this.methods, [], []); - }); - - describe('set', function () { - it('adds a key', async function () { - await expect(this.methods.set(this.keyA, this.valueA)).to.emit(this.mock, this.events.setReturn).withArgs(true); - - await expectMembersMatch(this.methods, [this.keyA], [this.valueA]); - }); - - it('adds several keys', async function () { - await this.methods.set(this.keyA, this.valueA); - await this.methods.set(this.keyB, this.valueB); - - await expectMembersMatch(this.methods, [this.keyA, this.keyB], [this.valueA, this.valueB]); - expect(await this.methods.contains(this.keyC)).to.be.false; - }); - - it('returns false when adding keys already in the set', async function () { - await this.methods.set(this.keyA, this.valueA); - - await expect(this.methods.set(this.keyA, this.valueA)).to.emit(this.mock, this.events.setReturn).withArgs(false); - - await expectMembersMatch(this.methods, [this.keyA], [this.valueA]); - }); - - it('updates values for keys already in the set', async function () { - await this.methods.set(this.keyA, this.valueA); - await this.methods.set(this.keyA, this.valueB); - - await expectMembersMatch(this.methods, [this.keyA], [this.valueB]); - }); - }); - - describe('remove', function () { - it('removes added keys', async function () { - await this.methods.set(this.keyA, this.valueA); - - await expect(this.methods.remove(this.keyA)).to.emit(this.mock, this.events.removeReturn).withArgs(true); - - expect(await this.methods.contains(this.keyA)).to.be.false; - await expectMembersMatch(this.methods, [], []); - }); - - it('returns false when removing keys not in the set', async function () { - await expect(await this.methods.remove(this.keyA)) - .to.emit(this.mock, this.events.removeReturn) - .withArgs(false); - - expect(await this.methods.contains(this.keyA)).to.be.false; - }); - - it('adds and removes multiple keys', async function () { - // [] - - await this.methods.set(this.keyA, this.valueA); - await this.methods.set(this.keyC, this.valueC); - - // [A, C] - - await this.methods.remove(this.keyA); - await this.methods.remove(this.keyB); - - // [C] - - await this.methods.set(this.keyB, this.valueB); - - // [C, B] - - await this.methods.set(this.keyA, this.valueA); - await this.methods.remove(this.keyC); - - // [A, B] - - await this.methods.set(this.keyA, this.valueA); - await this.methods.set(this.keyB, this.valueB); - - // [A, B] - - await this.methods.set(this.keyC, this.valueC); - await this.methods.remove(this.keyA); - - // [B, C] - - await this.methods.set(this.keyA, this.valueA); - await this.methods.remove(this.keyB); - - // [A, C] - - await expectMembersMatch(this.methods, [this.keyA, this.keyC], [this.valueA, this.valueC]); - - expect(await this.methods.contains(this.keyA)).to.be.true; - expect(await this.methods.contains(this.keyB)).to.be.false; - expect(await this.methods.contains(this.keyC)).to.be.true; - }); - }); - - describe('read', function () { - beforeEach(async function () { - await this.methods.set(this.keyA, this.valueA); - }); - - describe('get', function () { - it('existing value', async function () { - expect(await this.methods.get(this.keyA)).to.equal(this.valueA); - }); - - it('missing value', async function () { - await expect(this.methods.get(this.keyB)) - .to.be.revertedWithCustomError(this.mock, 'EnumerableMapNonexistentKey') - .withArgs(ethers.AbiCoder.defaultAbiCoder().encode([this.keyType], [this.keyB])); - }); - }); - - describe('tryGet', function () { - it('existing value', async function () { - expect(await this.methods.tryGet(this.keyA)).to.have.ordered.members([true, this.valueA]); - }); - - it('missing value', async function () { - expect(await this.methods.tryGet(this.keyB)).to.have.ordered.members([false, this.zeroValue]); - }); - }); - }); -} - -module.exports = { - shouldBehaveLikeMap, -}; diff --git a/lib/openzeppelin-contracts/test/utils/structs/EnumerableMap.test.js b/lib/openzeppelin-contracts/test/utils/structs/EnumerableMap.test.js deleted file mode 100644 index 5362e87..0000000 --- a/lib/openzeppelin-contracts/test/utils/structs/EnumerableMap.test.js +++ /dev/null @@ -1,65 +0,0 @@ -const { ethers } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { mapValues } = require('../../helpers/iterate'); -const { generators } = require('../../helpers/random'); -const { TYPES, formatType } = require('../../../scripts/generate/templates/EnumerableMap.opts'); - -const { shouldBehaveLikeMap } = require('./EnumerableMap.behavior'); - -// Add Bytes32ToBytes32Map that must be tested but is not part of the generated types. -TYPES.unshift(formatType('bytes32', 'bytes32')); - -async function fixture() { - const mock = await ethers.deployContract('$EnumerableMap'); - const env = Object.fromEntries( - TYPES.map(({ name, keyType, valueType }) => [ - name, - { - keyType, - keys: Array.from({ length: 3 }, generators[keyType]), - values: Array.from({ length: 3 }, generators[valueType]), - zeroValue: generators[valueType].zero, - methods: mapValues( - { - set: `$set(uint256,${keyType},${valueType})`, - get: `$get_EnumerableMap_${name}(uint256,${keyType})`, - tryGet: `$tryGet_EnumerableMap_${name}(uint256,${keyType})`, - remove: `$remove_EnumerableMap_${name}(uint256,${keyType})`, - length: `$length_EnumerableMap_${name}(uint256)`, - at: `$at_EnumerableMap_${name}(uint256,uint256)`, - contains: `$contains_EnumerableMap_${name}(uint256,${keyType})`, - keys: `$keys_EnumerableMap_${name}(uint256)`, - }, - fnSig => - (...args) => - mock.getFunction(fnSig)(0, ...args), - ), - events: { - setReturn: `return$set_EnumerableMap_${name}_${keyType}_${valueType}`, - removeReturn: `return$remove_EnumerableMap_${name}_${keyType}`, - }, - }, - ]), - ); - - return { mock, env }; -} - -describe('EnumerableMap', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - for (const { name } of TYPES) { - describe(name, function () { - beforeEach(async function () { - Object.assign(this, this.env[name]); - [this.keyA, this.keyB, this.keyC] = this.keys; - [this.valueA, this.valueB, this.valueC] = this.values; - }); - - shouldBehaveLikeMap(); - }); - } -}); diff --git a/lib/openzeppelin-contracts/test/utils/structs/EnumerableSet.behavior.js b/lib/openzeppelin-contracts/test/utils/structs/EnumerableSet.behavior.js deleted file mode 100644 index d3d4f26..0000000 --- a/lib/openzeppelin-contracts/test/utils/structs/EnumerableSet.behavior.js +++ /dev/null @@ -1,116 +0,0 @@ -const { expect } = require('chai'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); - -function shouldBehaveLikeSet() { - async function expectMembersMatch(methods, values) { - expect(await methods.length()).to.equal(values.length); - for (const value of values) expect(await methods.contains(value)).to.be.true; - - expect(await Promise.all(values.map((_, index) => methods.at(index)))).to.have.deep.members(values); - expect([...(await methods.values())]).to.have.deep.members(values); - } - - it('starts empty', async function () { - expect(await this.methods.contains(this.valueA)).to.be.false; - - await expectMembersMatch(this.methods, []); - }); - - describe('add', function () { - it('adds a value', async function () { - await expect(this.methods.add(this.valueA)).to.emit(this.mock, this.events.addReturn).withArgs(true); - - await expectMembersMatch(this.methods, [this.valueA]); - }); - - it('adds several values', async function () { - await this.methods.add(this.valueA); - await this.methods.add(this.valueB); - - await expectMembersMatch(this.methods, [this.valueA, this.valueB]); - expect(await this.methods.contains(this.valueC)).to.be.false; - }); - - it('returns false when adding values already in the set', async function () { - await this.methods.add(this.valueA); - - await expect(this.methods.add(this.valueA)).to.emit(this.mock, this.events.addReturn).withArgs(false); - - await expectMembersMatch(this.methods, [this.valueA]); - }); - }); - - describe('at', function () { - it('reverts when retrieving non-existent elements', async function () { - await expect(this.methods.at(0)).to.be.revertedWithPanic(PANIC_CODES.ARRAY_ACCESS_OUT_OF_BOUNDS); - }); - - it('retrieves existing element', async function () { - await this.methods.add(this.valueA); - expect(await this.methods.at(0)).to.equal(this.valueA); - }); - }); - - describe('remove', function () { - it('removes added values', async function () { - await this.methods.add(this.valueA); - - await expect(this.methods.remove(this.valueA)).to.emit(this.mock, this.events.removeReturn).withArgs(true); - - expect(await this.methods.contains(this.valueA)).to.be.false; - await expectMembersMatch(this.methods, []); - }); - - it('returns false when removing values not in the set', async function () { - await expect(this.methods.remove(this.valueA)).to.emit(this.mock, this.events.removeReturn).withArgs(false); - - expect(await this.methods.contains(this.valueA)).to.be.false; - }); - - it('adds and removes multiple values', async function () { - // [] - - await this.methods.add(this.valueA); - await this.methods.add(this.valueC); - - // [A, C] - - await this.methods.remove(this.valueA); - await this.methods.remove(this.valueB); - - // [C] - - await this.methods.add(this.valueB); - - // [C, B] - - await this.methods.add(this.valueA); - await this.methods.remove(this.valueC); - - // [A, B] - - await this.methods.add(this.valueA); - await this.methods.add(this.valueB); - - // [A, B] - - await this.methods.add(this.valueC); - await this.methods.remove(this.valueA); - - // [B, C] - - await this.methods.add(this.valueA); - await this.methods.remove(this.valueB); - - // [A, C] - - await expectMembersMatch(this.methods, [this.valueA, this.valueC]); - - expect(await this.methods.contains(this.valueB)).to.be.false; - }); - }); -} - -module.exports = { - shouldBehaveLikeSet, -}; diff --git a/lib/openzeppelin-contracts/test/utils/structs/EnumerableSet.test.js b/lib/openzeppelin-contracts/test/utils/structs/EnumerableSet.test.js deleted file mode 100644 index 66d6660..0000000 --- a/lib/openzeppelin-contracts/test/utils/structs/EnumerableSet.test.js +++ /dev/null @@ -1,61 +0,0 @@ -const { ethers } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { mapValues } = require('../../helpers/iterate'); -const { generators } = require('../../helpers/random'); -const { TYPES } = require('../../../scripts/generate/templates/EnumerableSet.opts'); - -const { shouldBehaveLikeSet } = require('./EnumerableSet.behavior'); - -const getMethods = (mock, fnSigs) => { - return mapValues( - fnSigs, - fnSig => - (...args) => - mock.getFunction(fnSig)(0, ...args), - ); -}; - -async function fixture() { - const mock = await ethers.deployContract('$EnumerableSet'); - - const env = Object.fromEntries( - TYPES.map(({ name, type }) => [ - type, - { - values: Array.from({ length: 3 }, generators[type]), - methods: getMethods(mock, { - add: `$add(uint256,${type})`, - remove: `$remove(uint256,${type})`, - contains: `$contains(uint256,${type})`, - length: `$length_EnumerableSet_${name}(uint256)`, - at: `$at_EnumerableSet_${name}(uint256,uint256)`, - values: `$values_EnumerableSet_${name}(uint256)`, - }), - events: { - addReturn: `return$add_EnumerableSet_${name}_${type}`, - removeReturn: `return$remove_EnumerableSet_${name}_${type}`, - }, - }, - ]), - ); - - return { mock, env }; -} - -describe('EnumerableSet', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - for (const { type } of TYPES) { - describe(type, function () { - beforeEach(function () { - Object.assign(this, this.env[type]); - [this.valueA, this.valueB, this.valueC] = this.values; - }); - - shouldBehaveLikeSet(); - }); - } -}); diff --git a/lib/openzeppelin-contracts/test/utils/structs/MerkleTree.test.js b/lib/openzeppelin-contracts/test/utils/structs/MerkleTree.test.js deleted file mode 100644 index 2603ac2..0000000 --- a/lib/openzeppelin-contracts/test/utils/structs/MerkleTree.test.js +++ /dev/null @@ -1,100 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); -const { StandardMerkleTree } = require('@openzeppelin/merkle-tree'); - -const { generators } = require('../../helpers/random'); - -const makeTree = (leafs = [ethers.ZeroHash]) => - StandardMerkleTree.of( - leafs.map(leaf => [leaf]), - ['bytes32'], - { sortLeaves: false }, - ); - -const hashLeaf = leaf => makeTree().leafHash([leaf]); - -const DEPTH = 4n; // 16 slots -const ZERO = hashLeaf(ethers.ZeroHash); - -async function fixture() { - const mock = await ethers.deployContract('MerkleTreeMock'); - await mock.setup(DEPTH, ZERO); - return { mock }; -} - -describe('MerkleTree', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - it('sets initial values at setup', async function () { - const merkleTree = makeTree(Array.from({ length: 2 ** Number(DEPTH) }, () => ethers.ZeroHash)); - - expect(await this.mock.root()).to.equal(merkleTree.root); - expect(await this.mock.depth()).to.equal(DEPTH); - expect(await this.mock.nextLeafIndex()).to.equal(0n); - }); - - describe('push', function () { - it('tree is correctly updated', async function () { - const leafs = Array.from({ length: 2 ** Number(DEPTH) }, () => ethers.ZeroHash); - - // for each leaf slot - for (const i in leafs) { - // generate random leaf and hash it - const hashedLeaf = hashLeaf((leafs[i] = generators.bytes32())); - - // update leaf list and rebuild tree. - const tree = makeTree(leafs); - - // push value to tree - await expect(this.mock.push(hashedLeaf)).to.emit(this.mock, 'LeafInserted').withArgs(hashedLeaf, i, tree.root); - - // check tree - expect(await this.mock.root()).to.equal(tree.root); - expect(await this.mock.nextLeafIndex()).to.equal(BigInt(i) + 1n); - } - }); - - it('revert when tree is full', async function () { - await Promise.all(Array.from({ length: 2 ** Number(DEPTH) }).map(() => this.mock.push(ethers.ZeroHash))); - - await expect(this.mock.push(ethers.ZeroHash)).to.be.revertedWithPanic(PANIC_CODES.TOO_MUCH_MEMORY_ALLOCATED); - }); - }); - - it('reset', async function () { - // empty tree - const zeroLeafs = Array.from({ length: 2 ** Number(DEPTH) }, () => ethers.ZeroHash); - const zeroTree = makeTree(zeroLeafs); - - // tree with one element - const leafs = Array.from({ length: 2 ** Number(DEPTH) }, () => ethers.ZeroHash); - const hashedLeaf = hashLeaf((leafs[0] = generators.bytes32())); // fill first leaf and hash it - const tree = makeTree(leafs); - - // root should be that of a zero tree - expect(await this.mock.root()).to.equal(zeroTree.root); - expect(await this.mock.nextLeafIndex()).to.equal(0n); - - // push leaf and check root - await expect(this.mock.push(hashedLeaf)).to.emit(this.mock, 'LeafInserted').withArgs(hashedLeaf, 0, tree.root); - - expect(await this.mock.root()).to.equal(tree.root); - expect(await this.mock.nextLeafIndex()).to.equal(1n); - - // reset tree - await this.mock.setup(DEPTH, ZERO); - - expect(await this.mock.root()).to.equal(zeroTree.root); - expect(await this.mock.nextLeafIndex()).to.equal(0n); - - // re-push leaf and check root - await expect(this.mock.push(hashedLeaf)).to.emit(this.mock, 'LeafInserted').withArgs(hashedLeaf, 0, tree.root); - - expect(await this.mock.root()).to.equal(tree.root); - expect(await this.mock.nextLeafIndex()).to.equal(1n); - }); -}); diff --git a/lib/openzeppelin-contracts/test/utils/types/Time.test.js b/lib/openzeppelin-contracts/test/utils/types/Time.test.js deleted file mode 100644 index 3ab6fef..0000000 --- a/lib/openzeppelin-contracts/test/utils/types/Time.test.js +++ /dev/null @@ -1,135 +0,0 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { product } = require('../../helpers/iterate'); -const { max } = require('../../helpers/math'); -const time = require('../../helpers/time'); - -const MAX_UINT32 = 1n << (32n - 1n); -const MAX_UINT48 = 1n << (48n - 1n); -const SOME_VALUES = [0n, 1n, 2n, 15n, 16n, 17n, 42n]; - -const asUint = (value, size) => { - value = ethers.toBigInt(value); - size = ethers.toBigInt(size); - expect(value).to.be.greaterThanOrEqual(0n, `value is not a valid uint${size}`); - expect(value).to.be.lessThan(1n << size, `value is not a valid uint${size}`); - return value; -}; - -const unpackDelay = delay => ({ - valueBefore: (asUint(delay, 112) >> 32n) % (1n << 32n), - valueAfter: (asUint(delay, 112) >> 0n) % (1n << 32n), - effect: (asUint(delay, 112) >> 64n) % (1n << 48n), -}); - -const packDelay = ({ valueBefore, valueAfter = 0n, effect = 0n }) => - (asUint(valueAfter, 32) << 0n) + (asUint(valueBefore, 32) << 32n) + (asUint(effect, 48) << 64n); - -const effectSamplesForTimepoint = timepoint => [ - 0n, - timepoint, - ...product([-1n, 1n], [1n, 2n, 17n, 42n]) - .map(([sign, shift]) => timepoint + sign * shift) - .filter(effect => effect > 0n && effect <= MAX_UINT48), - MAX_UINT48, -]; - -async function fixture() { - const mock = await ethers.deployContract('$Time'); - return { mock }; -} - -describe('Time', function () { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); - - describe('clocks', function () { - it('timestamp', async function () { - expect(await this.mock.$timestamp()).to.equal(await time.clock.timestamp()); - }); - - it('block number', async function () { - expect(await this.mock.$blockNumber()).to.equal(await time.clock.blocknumber()); - }); - }); - - describe('Delay', function () { - describe('packing and unpacking', function () { - const valueBefore = 17n; - const valueAfter = 42n; - const effect = 69n; - const delay = 1272825341158973505578n; - - it('pack', async function () { - expect(await this.mock.$pack(valueBefore, valueAfter, effect)).to.equal(delay); - expect(packDelay({ valueBefore, valueAfter, effect })).to.equal(delay); - }); - - it('unpack', async function () { - expect(await this.mock.$unpack(delay)).to.deep.equal([valueBefore, valueAfter, effect]); - - expect(unpackDelay(delay)).to.deep.equal({ - valueBefore, - valueAfter, - effect, - }); - }); - }); - - it('toDelay', async function () { - for (const value of [...SOME_VALUES, MAX_UINT32]) { - expect(await this.mock.$toDelay(value).then(unpackDelay)).to.deep.equal({ - valueBefore: 0n, - valueAfter: value, - effect: 0n, - }); - } - }); - - it('get & getFull', async function () { - const timepoint = await time.clock.timestamp(); - const valueBefore = 24194n; - const valueAfter = 4214143n; - - for (const effect of effectSamplesForTimepoint(timepoint)) { - const isPast = effect <= timepoint; - const delay = packDelay({ valueBefore, valueAfter, effect }); - - expect(await this.mock.$get(delay)).to.equal(isPast ? valueAfter : valueBefore); - expect(await this.mock.$getFull(delay)).to.deep.equal([ - isPast ? valueAfter : valueBefore, - isPast ? 0n : valueAfter, - isPast ? 0n : effect, - ]); - } - }); - - it('withUpdate', async function () { - const timepoint = await time.clock.timestamp(); - const valueBefore = 24194n; - const valueAfter = 4214143n; - const newvalueAfter = 94716n; - - for (const effect of effectSamplesForTimepoint(timepoint)) - for (const minSetback of [...SOME_VALUES, MAX_UINT32]) { - const isPast = effect <= timepoint; - const expectedvalueBefore = isPast ? valueAfter : valueBefore; - const expectedSetback = max(minSetback, expectedvalueBefore - newvalueAfter, 0n); - - expect( - await this.mock.$withUpdate(packDelay({ valueBefore, valueAfter, effect }), newvalueAfter, minSetback), - ).to.deep.equal([ - packDelay({ - valueBefore: expectedvalueBefore, - valueAfter: newvalueAfter, - effect: timepoint + expectedSetback, - }), - timepoint + expectedSetback, - ]); - } - }); - }); -}); diff --git a/lib/v2-core/.gitattributes b/lib/v2-core/.gitattributes deleted file mode 100644 index 7cc88f0..0000000 --- a/lib/v2-core/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -*.sol linguist-language=Solidity \ No newline at end of file diff --git a/lib/v2-core/.github/stale.yml b/lib/v2-core/.github/stale.yml deleted file mode 100644 index 91b9bf5..0000000 --- a/lib/v2-core/.github/stale.yml +++ /dev/null @@ -1,25 +0,0 @@ -# Configuration for probot-stale - https://github.com/probot/stale - -issues: - # Number of days of inactivity before an Issue or Pull Request becomes stale - daysUntilStale: 7 - - # Number of days of inactivity before an Issue or Pull Request with the stale label is closed. - # Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. - daysUntilClose: 7 - - # Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) - onlyLabels: - - question - - autoclose - - # Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable - exemptLabels: - - p0 - - bug - - # Comment to post when marking as stale. Set to `false` to disable - markComment: > - This issue has been automatically marked as stale because it has not had - recent activity. It will be closed if no further activity occurs. Thank you - for your contributions. diff --git a/lib/v2-core/.github/workflows/CI.yml b/lib/v2-core/.github/workflows/CI.yml deleted file mode 100644 index 2e62171..0000000 --- a/lib/v2-core/.github/workflows/CI.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: CI - -on: - push: - branches: - - master - pull_request: - -jobs: - test: - strategy: - matrix: - node: ['10.x', '12.x'] - os: [ubuntu-latest] - - runs-on: ${{ matrix.os }} - - steps: - - uses: actions/checkout@v1 - - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node }} - - - run: npm install -g yarn - - - id: yarn-cache - run: echo "::set-output name=dir::$(yarn cache dir)" - - uses: actions/cache@v1 - with: - path: ${{ steps.yarn-cache.outputs.dir }} - key: ${{ matrix.os }}-yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ matrix.os }}-yarn- - - - run: yarn - - run: yarn lint - - run: yarn test diff --git a/lib/v2-core/.gitignore b/lib/v2-core/.gitignore deleted file mode 100644 index b38db2f..0000000 --- a/lib/v2-core/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules/ -build/ diff --git a/lib/v2-core/.mocharc.json b/lib/v2-core/.mocharc.json deleted file mode 100644 index 1a5fee6..0000000 --- a/lib/v2-core/.mocharc.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extension": ["ts"], - "spec": "./test/**/*.spec.ts", - "require": "ts-node/register", - "timeout": 12000 -} diff --git a/lib/v2-core/.prettierrc b/lib/v2-core/.prettierrc deleted file mode 100644 index 31ba22d..0000000 --- a/lib/v2-core/.prettierrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "semi": false, - "singleQuote": true, - "printWidth": 120 -} diff --git a/lib/v2-core/.waffle.json b/lib/v2-core/.waffle.json deleted file mode 100644 index 29868df..0000000 --- a/lib/v2-core/.waffle.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "compilerVersion": "./node_modules/solc", - "outputType": "all", - "compilerOptions": { - "outputSelection": { - "*": { - "*": [ - "evm.bytecode.object", - "evm.deployedBytecode.object", - "abi", - "evm.bytecode.sourceMap", - "evm.deployedBytecode.sourceMap", - "metadata" - ], - "": ["ast"] - } - }, - "evmVersion": "istanbul", - "optimizer": { - "enabled": true, - "runs": 999999 - } - } -} diff --git a/lib/v2-core/CITATION.cff b/lib/v2-core/CITATION.cff deleted file mode 100644 index 50625d8..0000000 --- a/lib/v2-core/CITATION.cff +++ /dev/null @@ -1,15 +0,0 @@ -cff-version: 1.2.0 -message: "If you use this software, please cite it as below." -authors: -- family-names: "Zinsmeister" - given-names: "Noah" -- family-names: "Adams" - given-names: "Hayden" -- family-names: "Robinson" - given-names: "Dan" -- family-names: "Salem" - given-names: "Moody" -title: "v2-core" -version: 1.0.1 -date-released: 2019-05-03 -url: "https://github.com/Uniswap/v2-core" diff --git a/lib/v2-core/LICENSE b/lib/v2-core/LICENSE deleted file mode 100644 index f288702..0000000 --- a/lib/v2-core/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/v2-core/README.md b/lib/v2-core/README.md deleted file mode 100644 index 1d72187..0000000 --- a/lib/v2-core/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# Uniswap V2 - -[![Actions Status](https://github.com/Uniswap/uniswap-v2-core/workflows/CI/badge.svg)](https://github.com/Uniswap/uniswap-v2-core/actions) -[![Version](https://img.shields.io/npm/v/@uniswap/v2-core)](https://www.npmjs.com/package/@uniswap/v2-core) - -In-depth documentation on Uniswap V2 is available at [uniswap.org](https://uniswap.org/docs). - -The built contract artifacts can be browsed via [unpkg.com](https://unpkg.com/browse/@uniswap/v2-core@latest/). - -# Local Development - -The following assumes the use of `node@>=10`. - -## Install Dependencies - -`yarn` - -## Compile Contracts - -`yarn compile` - -## Run Tests - -`yarn test` diff --git a/lib/v2-core/contracts/UniswapV2ERC20.sol b/lib/v2-core/contracts/UniswapV2ERC20.sol deleted file mode 100644 index 404a8be..0000000 --- a/lib/v2-core/contracts/UniswapV2ERC20.sol +++ /dev/null @@ -1,94 +0,0 @@ -pragma solidity =0.5.16; - -import './interfaces/IUniswapV2ERC20.sol'; -import './libraries/SafeMath.sol'; - -contract UniswapV2ERC20 is IUniswapV2ERC20 { - using SafeMath for uint; - - string public constant name = 'Uniswap V2'; - string public constant symbol = 'UNI-V2'; - uint8 public constant decimals = 18; - uint public totalSupply; - mapping(address => uint) public balanceOf; - mapping(address => mapping(address => uint)) public allowance; - - bytes32 public DOMAIN_SEPARATOR; - // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); - bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; - mapping(address => uint) public nonces; - - event Approval(address indexed owner, address indexed spender, uint value); - event Transfer(address indexed from, address indexed to, uint value); - - constructor() public { - uint chainId; - assembly { - chainId := chainid - } - DOMAIN_SEPARATOR = keccak256( - abi.encode( - keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'), - keccak256(bytes(name)), - keccak256(bytes('1')), - chainId, - address(this) - ) - ); - } - - function _mint(address to, uint value) internal { - totalSupply = totalSupply.add(value); - balanceOf[to] = balanceOf[to].add(value); - emit Transfer(address(0), to, value); - } - - function _burn(address from, uint value) internal { - balanceOf[from] = balanceOf[from].sub(value); - totalSupply = totalSupply.sub(value); - emit Transfer(from, address(0), value); - } - - function _approve(address owner, address spender, uint value) private { - allowance[owner][spender] = value; - emit Approval(owner, spender, value); - } - - function _transfer(address from, address to, uint value) private { - balanceOf[from] = balanceOf[from].sub(value); - balanceOf[to] = balanceOf[to].add(value); - emit Transfer(from, to, value); - } - - function approve(address spender, uint value) external returns (bool) { - _approve(msg.sender, spender, value); - return true; - } - - function transfer(address to, uint value) external returns (bool) { - _transfer(msg.sender, to, value); - return true; - } - - function transferFrom(address from, address to, uint value) external returns (bool) { - if (allowance[from][msg.sender] != uint(-1)) { - allowance[from][msg.sender] = allowance[from][msg.sender].sub(value); - } - _transfer(from, to, value); - return true; - } - - function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external { - require(deadline >= block.timestamp, 'UniswapV2: EXPIRED'); - bytes32 digest = keccak256( - abi.encodePacked( - '\x19\x01', - DOMAIN_SEPARATOR, - keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline)) - ) - ); - address recoveredAddress = ecrecover(digest, v, r, s); - require(recoveredAddress != address(0) && recoveredAddress == owner, 'UniswapV2: INVALID_SIGNATURE'); - _approve(owner, spender, value); - } -} diff --git a/lib/v2-core/contracts/UniswapV2Factory.sol b/lib/v2-core/contracts/UniswapV2Factory.sol deleted file mode 100644 index a66ad82..0000000 --- a/lib/v2-core/contracts/UniswapV2Factory.sol +++ /dev/null @@ -1,49 +0,0 @@ -pragma solidity =0.5.16; - -import './interfaces/IUniswapV2Factory.sol'; -import './UniswapV2Pair.sol'; - -contract UniswapV2Factory is IUniswapV2Factory { - address public feeTo; - address public feeToSetter; - - mapping(address => mapping(address => address)) public getPair; - address[] public allPairs; - - event PairCreated(address indexed token0, address indexed token1, address pair, uint); - - constructor(address _feeToSetter) public { - feeToSetter = _feeToSetter; - } - - function allPairsLength() external view returns (uint) { - return allPairs.length; - } - - function createPair(address tokenA, address tokenB) external returns (address pair) { - require(tokenA != tokenB, 'UniswapV2: IDENTICAL_ADDRESSES'); - (address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); - require(token0 != address(0), 'UniswapV2: ZERO_ADDRESS'); - require(getPair[token0][token1] == address(0), 'UniswapV2: PAIR_EXISTS'); // single check is sufficient - bytes memory bytecode = type(UniswapV2Pair).creationCode; - bytes32 salt = keccak256(abi.encodePacked(token0, token1)); - assembly { - pair := create2(0, add(bytecode, 32), mload(bytecode), salt) - } - IUniswapV2Pair(pair).initialize(token0, token1); - getPair[token0][token1] = pair; - getPair[token1][token0] = pair; // populate mapping in the reverse direction - allPairs.push(pair); - emit PairCreated(token0, token1, pair, allPairs.length); - } - - function setFeeTo(address _feeTo) external { - require(msg.sender == feeToSetter, 'UniswapV2: FORBIDDEN'); - feeTo = _feeTo; - } - - function setFeeToSetter(address _feeToSetter) external { - require(msg.sender == feeToSetter, 'UniswapV2: FORBIDDEN'); - feeToSetter = _feeToSetter; - } -} diff --git a/lib/v2-core/contracts/UniswapV2Pair.sol b/lib/v2-core/contracts/UniswapV2Pair.sol deleted file mode 100644 index f87a1db..0000000 --- a/lib/v2-core/contracts/UniswapV2Pair.sol +++ /dev/null @@ -1,201 +0,0 @@ -pragma solidity =0.5.16; - -import './interfaces/IUniswapV2Pair.sol'; -import './UniswapV2ERC20.sol'; -import './libraries/Math.sol'; -import './libraries/UQ112x112.sol'; -import './interfaces/IERC20.sol'; -import './interfaces/IUniswapV2Factory.sol'; -import './interfaces/IUniswapV2Callee.sol'; - -contract UniswapV2Pair is IUniswapV2Pair, UniswapV2ERC20 { - using SafeMath for uint; - using UQ112x112 for uint224; - - uint public constant MINIMUM_LIQUIDITY = 10**3; - bytes4 private constant SELECTOR = bytes4(keccak256(bytes('transfer(address,uint256)'))); - - address public factory; - address public token0; - address public token1; - - uint112 private reserve0; // uses single storage slot, accessible via getReserves - uint112 private reserve1; // uses single storage slot, accessible via getReserves - uint32 private blockTimestampLast; // uses single storage slot, accessible via getReserves - - uint public price0CumulativeLast; - uint public price1CumulativeLast; - uint public kLast; // reserve0 * reserve1, as of immediately after the most recent liquidity event - - uint private unlocked = 1; - modifier lock() { - require(unlocked == 1, 'UniswapV2: LOCKED'); - unlocked = 0; - _; - unlocked = 1; - } - - function getReserves() public view returns (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) { - _reserve0 = reserve0; - _reserve1 = reserve1; - _blockTimestampLast = blockTimestampLast; - } - - function _safeTransfer(address token, address to, uint value) private { - (bool success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR, to, value)); - require(success && (data.length == 0 || abi.decode(data, (bool))), 'UniswapV2: TRANSFER_FAILED'); - } - - event Mint(address indexed sender, uint amount0, uint amount1); - event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); - event Swap( - address indexed sender, - uint amount0In, - uint amount1In, - uint amount0Out, - uint amount1Out, - address indexed to - ); - event Sync(uint112 reserve0, uint112 reserve1); - - constructor() public { - factory = msg.sender; - } - - // called once by the factory at time of deployment - function initialize(address _token0, address _token1) external { - require(msg.sender == factory, 'UniswapV2: FORBIDDEN'); // sufficient check - token0 = _token0; - token1 = _token1; - } - - // update reserves and, on the first call per block, price accumulators - function _update(uint balance0, uint balance1, uint112 _reserve0, uint112 _reserve1) private { - require(balance0 <= uint112(-1) && balance1 <= uint112(-1), 'UniswapV2: OVERFLOW'); - uint32 blockTimestamp = uint32(block.timestamp % 2**32); - uint32 timeElapsed = blockTimestamp - blockTimestampLast; // overflow is desired - if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) { - // * never overflows, and + overflow is desired - price0CumulativeLast += uint(UQ112x112.encode(_reserve1).uqdiv(_reserve0)) * timeElapsed; - price1CumulativeLast += uint(UQ112x112.encode(_reserve0).uqdiv(_reserve1)) * timeElapsed; - } - reserve0 = uint112(balance0); - reserve1 = uint112(balance1); - blockTimestampLast = blockTimestamp; - emit Sync(reserve0, reserve1); - } - - // if fee is on, mint liquidity equivalent to 1/6th of the growth in sqrt(k) - function _mintFee(uint112 _reserve0, uint112 _reserve1) private returns (bool feeOn) { - address feeTo = IUniswapV2Factory(factory).feeTo(); - feeOn = feeTo != address(0); - uint _kLast = kLast; // gas savings - if (feeOn) { - if (_kLast != 0) { - uint rootK = Math.sqrt(uint(_reserve0).mul(_reserve1)); - uint rootKLast = Math.sqrt(_kLast); - if (rootK > rootKLast) { - uint numerator = totalSupply.mul(rootK.sub(rootKLast)); - uint denominator = rootK.mul(5).add(rootKLast); - uint liquidity = numerator / denominator; - if (liquidity > 0) _mint(feeTo, liquidity); - } - } - } else if (_kLast != 0) { - kLast = 0; - } - } - - // this low-level function should be called from a contract which performs important safety checks - function mint(address to) external lock returns (uint liquidity) { - (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings - uint balance0 = IERC20(token0).balanceOf(address(this)); - uint balance1 = IERC20(token1).balanceOf(address(this)); - uint amount0 = balance0.sub(_reserve0); - uint amount1 = balance1.sub(_reserve1); - - bool feeOn = _mintFee(_reserve0, _reserve1); - uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee - if (_totalSupply == 0) { - liquidity = Math.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY); - _mint(address(0), MINIMUM_LIQUIDITY); // permanently lock the first MINIMUM_LIQUIDITY tokens - } else { - liquidity = Math.min(amount0.mul(_totalSupply) / _reserve0, amount1.mul(_totalSupply) / _reserve1); - } - require(liquidity > 0, 'UniswapV2: INSUFFICIENT_LIQUIDITY_MINTED'); - _mint(to, liquidity); - - _update(balance0, balance1, _reserve0, _reserve1); - if (feeOn) kLast = uint(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date - emit Mint(msg.sender, amount0, amount1); - } - - // this low-level function should be called from a contract which performs important safety checks - function burn(address to) external lock returns (uint amount0, uint amount1) { - (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings - address _token0 = token0; // gas savings - address _token1 = token1; // gas savings - uint balance0 = IERC20(_token0).balanceOf(address(this)); - uint balance1 = IERC20(_token1).balanceOf(address(this)); - uint liquidity = balanceOf[address(this)]; - - bool feeOn = _mintFee(_reserve0, _reserve1); - uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee - amount0 = liquidity.mul(balance0) / _totalSupply; // using balances ensures pro-rata distribution - amount1 = liquidity.mul(balance1) / _totalSupply; // using balances ensures pro-rata distribution - require(amount0 > 0 && amount1 > 0, 'UniswapV2: INSUFFICIENT_LIQUIDITY_BURNED'); - _burn(address(this), liquidity); - _safeTransfer(_token0, to, amount0); - _safeTransfer(_token1, to, amount1); - balance0 = IERC20(_token0).balanceOf(address(this)); - balance1 = IERC20(_token1).balanceOf(address(this)); - - _update(balance0, balance1, _reserve0, _reserve1); - if (feeOn) kLast = uint(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date - emit Burn(msg.sender, amount0, amount1, to); - } - - // this low-level function should be called from a contract which performs important safety checks - function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external lock { - require(amount0Out > 0 || amount1Out > 0, 'UniswapV2: INSUFFICIENT_OUTPUT_AMOUNT'); - (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings - require(amount0Out < _reserve0 && amount1Out < _reserve1, 'UniswapV2: INSUFFICIENT_LIQUIDITY'); - - uint balance0; - uint balance1; - { // scope for _token{0,1}, avoids stack too deep errors - address _token0 = token0; - address _token1 = token1; - require(to != _token0 && to != _token1, 'UniswapV2: INVALID_TO'); - if (amount0Out > 0) _safeTransfer(_token0, to, amount0Out); // optimistically transfer tokens - if (amount1Out > 0) _safeTransfer(_token1, to, amount1Out); // optimistically transfer tokens - if (data.length > 0) IUniswapV2Callee(to).uniswapV2Call(msg.sender, amount0Out, amount1Out, data); - balance0 = IERC20(_token0).balanceOf(address(this)); - balance1 = IERC20(_token1).balanceOf(address(this)); - } - uint amount0In = balance0 > _reserve0 - amount0Out ? balance0 - (_reserve0 - amount0Out) : 0; - uint amount1In = balance1 > _reserve1 - amount1Out ? balance1 - (_reserve1 - amount1Out) : 0; - require(amount0In > 0 || amount1In > 0, 'UniswapV2: INSUFFICIENT_INPUT_AMOUNT'); - { // scope for reserve{0,1}Adjusted, avoids stack too deep errors - uint balance0Adjusted = balance0.mul(1000).sub(amount0In.mul(3)); - uint balance1Adjusted = balance1.mul(1000).sub(amount1In.mul(3)); - require(balance0Adjusted.mul(balance1Adjusted) >= uint(_reserve0).mul(_reserve1).mul(1000**2), 'UniswapV2: K'); - } - - _update(balance0, balance1, _reserve0, _reserve1); - emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to); - } - - // force balances to match reserves - function skim(address to) external lock { - address _token0 = token0; // gas savings - address _token1 = token1; // gas savings - _safeTransfer(_token0, to, IERC20(_token0).balanceOf(address(this)).sub(reserve0)); - _safeTransfer(_token1, to, IERC20(_token1).balanceOf(address(this)).sub(reserve1)); - } - - // force reserves to match balances - function sync() external lock { - _update(IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this)), reserve0, reserve1); - } -} diff --git a/lib/v2-core/contracts/interfaces/IERC20.sol b/lib/v2-core/contracts/interfaces/IERC20.sol deleted file mode 100644 index c1e8c3e..0000000 --- a/lib/v2-core/contracts/interfaces/IERC20.sol +++ /dev/null @@ -1,17 +0,0 @@ -pragma solidity >=0.5.0; - -interface IERC20 { - event Approval(address indexed owner, address indexed spender, uint value); - event Transfer(address indexed from, address indexed to, uint value); - - function name() external view returns (string memory); - function symbol() external view returns (string memory); - function decimals() external view returns (uint8); - function totalSupply() external view returns (uint); - function balanceOf(address owner) external view returns (uint); - function allowance(address owner, address spender) external view returns (uint); - - function approve(address spender, uint value) external returns (bool); - function transfer(address to, uint value) external returns (bool); - function transferFrom(address from, address to, uint value) external returns (bool); -} diff --git a/lib/v2-core/contracts/interfaces/IUniswapV2Callee.sol b/lib/v2-core/contracts/interfaces/IUniswapV2Callee.sol deleted file mode 100644 index f3910ab..0000000 --- a/lib/v2-core/contracts/interfaces/IUniswapV2Callee.sol +++ /dev/null @@ -1,5 +0,0 @@ -pragma solidity >=0.5.0; - -interface IUniswapV2Callee { - function uniswapV2Call(address sender, uint amount0, uint amount1, bytes calldata data) external; -} diff --git a/lib/v2-core/contracts/interfaces/IUniswapV2ERC20.sol b/lib/v2-core/contracts/interfaces/IUniswapV2ERC20.sol deleted file mode 100644 index 8718931..0000000 --- a/lib/v2-core/contracts/interfaces/IUniswapV2ERC20.sol +++ /dev/null @@ -1,23 +0,0 @@ -pragma solidity >=0.5.0; - -interface IUniswapV2ERC20 { - event Approval(address indexed owner, address indexed spender, uint value); - event Transfer(address indexed from, address indexed to, uint value); - - function name() external pure returns (string memory); - function symbol() external pure returns (string memory); - function decimals() external pure returns (uint8); - function totalSupply() external view returns (uint); - function balanceOf(address owner) external view returns (uint); - function allowance(address owner, address spender) external view returns (uint); - - function approve(address spender, uint value) external returns (bool); - function transfer(address to, uint value) external returns (bool); - function transferFrom(address from, address to, uint value) external returns (bool); - - function DOMAIN_SEPARATOR() external view returns (bytes32); - function PERMIT_TYPEHASH() external pure returns (bytes32); - function nonces(address owner) external view returns (uint); - - function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; -} diff --git a/lib/v2-core/contracts/interfaces/IUniswapV2Factory.sol b/lib/v2-core/contracts/interfaces/IUniswapV2Factory.sol deleted file mode 100644 index e73dc59..0000000 --- a/lib/v2-core/contracts/interfaces/IUniswapV2Factory.sol +++ /dev/null @@ -1,17 +0,0 @@ -pragma solidity >=0.5.0; - -interface IUniswapV2Factory { - event PairCreated(address indexed token0, address indexed token1, address pair, uint); - - function feeTo() external view returns (address); - function feeToSetter() external view returns (address); - - function getPair(address tokenA, address tokenB) external view returns (address pair); - function allPairs(uint) external view returns (address pair); - function allPairsLength() external view returns (uint); - - function createPair(address tokenA, address tokenB) external returns (address pair); - - function setFeeTo(address) external; - function setFeeToSetter(address) external; -} diff --git a/lib/v2-core/contracts/interfaces/IUniswapV2Pair.sol b/lib/v2-core/contracts/interfaces/IUniswapV2Pair.sol deleted file mode 100644 index 762dd4d..0000000 --- a/lib/v2-core/contracts/interfaces/IUniswapV2Pair.sol +++ /dev/null @@ -1,52 +0,0 @@ -pragma solidity >=0.5.0; - -interface IUniswapV2Pair { - event Approval(address indexed owner, address indexed spender, uint value); - event Transfer(address indexed from, address indexed to, uint value); - - function name() external pure returns (string memory); - function symbol() external pure returns (string memory); - function decimals() external pure returns (uint8); - function totalSupply() external view returns (uint); - function balanceOf(address owner) external view returns (uint); - function allowance(address owner, address spender) external view returns (uint); - - function approve(address spender, uint value) external returns (bool); - function transfer(address to, uint value) external returns (bool); - function transferFrom(address from, address to, uint value) external returns (bool); - - function DOMAIN_SEPARATOR() external view returns (bytes32); - function PERMIT_TYPEHASH() external pure returns (bytes32); - function nonces(address owner) external view returns (uint); - - function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; - - event Mint(address indexed sender, uint amount0, uint amount1); - event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); - event Swap( - address indexed sender, - uint amount0In, - uint amount1In, - uint amount0Out, - uint amount1Out, - address indexed to - ); - event Sync(uint112 reserve0, uint112 reserve1); - - function MINIMUM_LIQUIDITY() external pure returns (uint); - function factory() external view returns (address); - function token0() external view returns (address); - function token1() external view returns (address); - function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); - function price0CumulativeLast() external view returns (uint); - function price1CumulativeLast() external view returns (uint); - function kLast() external view returns (uint); - - function mint(address to) external returns (uint liquidity); - function burn(address to) external returns (uint amount0, uint amount1); - function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; - function skim(address to) external; - function sync() external; - - function initialize(address, address) external; -} diff --git a/lib/v2-core/contracts/libraries/Math.sol b/lib/v2-core/contracts/libraries/Math.sol deleted file mode 100644 index 1cab10d..0000000 --- a/lib/v2-core/contracts/libraries/Math.sol +++ /dev/null @@ -1,23 +0,0 @@ -pragma solidity =0.5.16; - -// a library for performing various math operations - -library Math { - function min(uint x, uint y) internal pure returns (uint z) { - z = x < y ? x : y; - } - - // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) - function sqrt(uint y) internal pure returns (uint z) { - if (y > 3) { - z = y; - uint x = y / 2 + 1; - while (x < z) { - z = x; - x = (y / x + x) / 2; - } - } else if (y != 0) { - z = 1; - } - } -} diff --git a/lib/v2-core/contracts/libraries/SafeMath.sol b/lib/v2-core/contracts/libraries/SafeMath.sol deleted file mode 100644 index f2fbe16..0000000 --- a/lib/v2-core/contracts/libraries/SafeMath.sol +++ /dev/null @@ -1,17 +0,0 @@ -pragma solidity =0.5.16; - -// a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math) - -library SafeMath { - function add(uint x, uint y) internal pure returns (uint z) { - require((z = x + y) >= x, 'ds-math-add-overflow'); - } - - function sub(uint x, uint y) internal pure returns (uint z) { - require((z = x - y) <= x, 'ds-math-sub-underflow'); - } - - function mul(uint x, uint y) internal pure returns (uint z) { - require(y == 0 || (z = x * y) / y == x, 'ds-math-mul-overflow'); - } -} diff --git a/lib/v2-core/contracts/libraries/UQ112x112.sol b/lib/v2-core/contracts/libraries/UQ112x112.sol deleted file mode 100644 index a453f72..0000000 --- a/lib/v2-core/contracts/libraries/UQ112x112.sol +++ /dev/null @@ -1,20 +0,0 @@ -pragma solidity =0.5.16; - -// a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format)) - -// range: [0, 2**112 - 1] -// resolution: 1 / 2**112 - -library UQ112x112 { - uint224 constant Q112 = 2**112; - - // encode a uint112 as a UQ112x112 - function encode(uint112 y) internal pure returns (uint224 z) { - z = uint224(y) * Q112; // never overflows - } - - // divide a UQ112x112 by a uint112, returning a UQ112x112 - function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) { - z = x / uint224(y); - } -} diff --git a/lib/v2-core/contracts/test/ERC20.sol b/lib/v2-core/contracts/test/ERC20.sol deleted file mode 100644 index 74f0777..0000000 --- a/lib/v2-core/contracts/test/ERC20.sol +++ /dev/null @@ -1,9 +0,0 @@ -pragma solidity =0.5.16; - -import '../UniswapV2ERC20.sol'; - -contract ERC20 is UniswapV2ERC20 { - constructor(uint _totalSupply) public { - _mint(msg.sender, _totalSupply); - } -} diff --git a/lib/v2-core/package.json b/lib/v2-core/package.json deleted file mode 100644 index 10c7b6f..0000000 --- a/lib/v2-core/package.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "@uniswap/v2-core", - "description": "🎛 Core contracts for the UniswapV2 protocol", - "version": "1.0.1", - "homepage": "https://uniswap.org", - "repository": { - "type": "git", - "url": "https://github.com/Uniswap/uniswap-v2-core" - }, - "keywords": [ - "uniswap", - "ethereum", - "v2", - "core", - "uniswap-v2" - ], - "files": [ - "contracts", - "build" - ], - "engines": { - "node": ">=10" - }, - "devDependencies": { - "@types/chai": "^4.2.6", - "@types/mocha": "^5.2.7", - "chai": "^4.2.0", - "ethereum-waffle": "^2.4.1", - "ethereumjs-util": "^6.2.0", - "mocha": "^6.2.2", - "prettier": "^1.19.1", - "rimraf": "^3.0.0", - "solc": "0.5.16", - "ts-node": "^8.5.4", - "typescript": "^3.7.3" - }, - "scripts": { - "lint": "yarn prettier ./test/*.ts --check", - "lint:fix": "yarn prettier ./test/*.ts --write", - "clean": "rimraf ./build/", - "precompile": "yarn clean", - "compile": "waffle .waffle.json", - "pretest": "yarn compile", - "test": "mocha", - "prepublishOnly": "yarn test" - }, - "license": "GPL-3.0-or-later" -} diff --git a/lib/v2-core/test/UniswapV2ERC20.spec.ts b/lib/v2-core/test/UniswapV2ERC20.spec.ts deleted file mode 100644 index ec57312..0000000 --- a/lib/v2-core/test/UniswapV2ERC20.spec.ts +++ /dev/null @@ -1,116 +0,0 @@ -import chai, { expect } from 'chai' -import { Contract } from 'ethers' -import { MaxUint256 } from 'ethers/constants' -import { bigNumberify, hexlify, keccak256, defaultAbiCoder, toUtf8Bytes } from 'ethers/utils' -import { solidity, MockProvider, deployContract } from 'ethereum-waffle' -import { ecsign } from 'ethereumjs-util' - -import { expandTo18Decimals, getApprovalDigest } from './shared/utilities' - -import ERC20 from '../build/ERC20.json' - -chai.use(solidity) - -const TOTAL_SUPPLY = expandTo18Decimals(10000) -const TEST_AMOUNT = expandTo18Decimals(10) - -describe('UniswapV2ERC20', () => { - const provider = new MockProvider({ - hardfork: 'istanbul', - mnemonic: 'horn horn horn horn horn horn horn horn horn horn horn horn', - gasLimit: 9999999 - }) - const [wallet, other] = provider.getWallets() - - let token: Contract - beforeEach(async () => { - token = await deployContract(wallet, ERC20, [TOTAL_SUPPLY]) - }) - - it('name, symbol, decimals, totalSupply, balanceOf, DOMAIN_SEPARATOR, PERMIT_TYPEHASH', async () => { - const name = await token.name() - expect(name).to.eq('Uniswap V2') - expect(await token.symbol()).to.eq('UNI-V2') - expect(await token.decimals()).to.eq(18) - expect(await token.totalSupply()).to.eq(TOTAL_SUPPLY) - expect(await token.balanceOf(wallet.address)).to.eq(TOTAL_SUPPLY) - expect(await token.DOMAIN_SEPARATOR()).to.eq( - keccak256( - defaultAbiCoder.encode( - ['bytes32', 'bytes32', 'bytes32', 'uint256', 'address'], - [ - keccak256( - toUtf8Bytes('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)') - ), - keccak256(toUtf8Bytes(name)), - keccak256(toUtf8Bytes('1')), - 1, - token.address - ] - ) - ) - ) - expect(await token.PERMIT_TYPEHASH()).to.eq( - keccak256(toUtf8Bytes('Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)')) - ) - }) - - it('approve', async () => { - await expect(token.approve(other.address, TEST_AMOUNT)) - .to.emit(token, 'Approval') - .withArgs(wallet.address, other.address, TEST_AMOUNT) - expect(await token.allowance(wallet.address, other.address)).to.eq(TEST_AMOUNT) - }) - - it('transfer', async () => { - await expect(token.transfer(other.address, TEST_AMOUNT)) - .to.emit(token, 'Transfer') - .withArgs(wallet.address, other.address, TEST_AMOUNT) - expect(await token.balanceOf(wallet.address)).to.eq(TOTAL_SUPPLY.sub(TEST_AMOUNT)) - expect(await token.balanceOf(other.address)).to.eq(TEST_AMOUNT) - }) - - it('transfer:fail', async () => { - await expect(token.transfer(other.address, TOTAL_SUPPLY.add(1))).to.be.reverted // ds-math-sub-underflow - await expect(token.connect(other).transfer(wallet.address, 1)).to.be.reverted // ds-math-sub-underflow - }) - - it('transferFrom', async () => { - await token.approve(other.address, TEST_AMOUNT) - await expect(token.connect(other).transferFrom(wallet.address, other.address, TEST_AMOUNT)) - .to.emit(token, 'Transfer') - .withArgs(wallet.address, other.address, TEST_AMOUNT) - expect(await token.allowance(wallet.address, other.address)).to.eq(0) - expect(await token.balanceOf(wallet.address)).to.eq(TOTAL_SUPPLY.sub(TEST_AMOUNT)) - expect(await token.balanceOf(other.address)).to.eq(TEST_AMOUNT) - }) - - it('transferFrom:max', async () => { - await token.approve(other.address, MaxUint256) - await expect(token.connect(other).transferFrom(wallet.address, other.address, TEST_AMOUNT)) - .to.emit(token, 'Transfer') - .withArgs(wallet.address, other.address, TEST_AMOUNT) - expect(await token.allowance(wallet.address, other.address)).to.eq(MaxUint256) - expect(await token.balanceOf(wallet.address)).to.eq(TOTAL_SUPPLY.sub(TEST_AMOUNT)) - expect(await token.balanceOf(other.address)).to.eq(TEST_AMOUNT) - }) - - it('permit', async () => { - const nonce = await token.nonces(wallet.address) - const deadline = MaxUint256 - const digest = await getApprovalDigest( - token, - { owner: wallet.address, spender: other.address, value: TEST_AMOUNT }, - nonce, - deadline - ) - - const { v, r, s } = ecsign(Buffer.from(digest.slice(2), 'hex'), Buffer.from(wallet.privateKey.slice(2), 'hex')) - - await expect(token.permit(wallet.address, other.address, TEST_AMOUNT, deadline, v, hexlify(r), hexlify(s))) - .to.emit(token, 'Approval') - .withArgs(wallet.address, other.address, TEST_AMOUNT) - expect(await token.allowance(wallet.address, other.address)).to.eq(TEST_AMOUNT) - expect(await token.nonces(wallet.address)).to.eq(bigNumberify(1)) - }) -}) diff --git a/lib/v2-core/test/UniswapV2Factory.spec.ts b/lib/v2-core/test/UniswapV2Factory.spec.ts deleted file mode 100644 index 432aac3..0000000 --- a/lib/v2-core/test/UniswapV2Factory.spec.ts +++ /dev/null @@ -1,86 +0,0 @@ -import chai, { expect } from 'chai' -import { Contract } from 'ethers' -import { AddressZero } from 'ethers/constants' -import { bigNumberify } from 'ethers/utils' -import { solidity, MockProvider, createFixtureLoader } from 'ethereum-waffle' - -import { getCreate2Address } from './shared/utilities' -import { factoryFixture } from './shared/fixtures' - -import UniswapV2Pair from '../build/UniswapV2Pair.json' - -chai.use(solidity) - -const TEST_ADDRESSES: [string, string] = [ - '0x1000000000000000000000000000000000000000', - '0x2000000000000000000000000000000000000000' -] - -describe('UniswapV2Factory', () => { - const provider = new MockProvider({ - hardfork: 'istanbul', - mnemonic: 'horn horn horn horn horn horn horn horn horn horn horn horn', - gasLimit: 9999999 - }) - const [wallet, other] = provider.getWallets() - const loadFixture = createFixtureLoader(provider, [wallet, other]) - - let factory: Contract - beforeEach(async () => { - const fixture = await loadFixture(factoryFixture) - factory = fixture.factory - }) - - it('feeTo, feeToSetter, allPairsLength', async () => { - expect(await factory.feeTo()).to.eq(AddressZero) - expect(await factory.feeToSetter()).to.eq(wallet.address) - expect(await factory.allPairsLength()).to.eq(0) - }) - - async function createPair(tokens: [string, string]) { - const bytecode = `0x${UniswapV2Pair.evm.bytecode.object}` - const create2Address = getCreate2Address(factory.address, tokens, bytecode) - await expect(factory.createPair(...tokens)) - .to.emit(factory, 'PairCreated') - .withArgs(TEST_ADDRESSES[0], TEST_ADDRESSES[1], create2Address, bigNumberify(1)) - - await expect(factory.createPair(...tokens)).to.be.reverted // UniswapV2: PAIR_EXISTS - await expect(factory.createPair(...tokens.slice().reverse())).to.be.reverted // UniswapV2: PAIR_EXISTS - expect(await factory.getPair(...tokens)).to.eq(create2Address) - expect(await factory.getPair(...tokens.slice().reverse())).to.eq(create2Address) - expect(await factory.allPairs(0)).to.eq(create2Address) - expect(await factory.allPairsLength()).to.eq(1) - - const pair = new Contract(create2Address, JSON.stringify(UniswapV2Pair.abi), provider) - expect(await pair.factory()).to.eq(factory.address) - expect(await pair.token0()).to.eq(TEST_ADDRESSES[0]) - expect(await pair.token1()).to.eq(TEST_ADDRESSES[1]) - } - - it('createPair', async () => { - await createPair(TEST_ADDRESSES) - }) - - it('createPair:reverse', async () => { - await createPair(TEST_ADDRESSES.slice().reverse() as [string, string]) - }) - - it('createPair:gas', async () => { - const tx = await factory.createPair(...TEST_ADDRESSES) - const receipt = await tx.wait() - expect(receipt.gasUsed).to.eq(2512920) - }) - - it('setFeeTo', async () => { - await expect(factory.connect(other).setFeeTo(other.address)).to.be.revertedWith('UniswapV2: FORBIDDEN') - await factory.setFeeTo(wallet.address) - expect(await factory.feeTo()).to.eq(wallet.address) - }) - - it('setFeeToSetter', async () => { - await expect(factory.connect(other).setFeeToSetter(other.address)).to.be.revertedWith('UniswapV2: FORBIDDEN') - await factory.setFeeToSetter(other.address) - expect(await factory.feeToSetter()).to.eq(other.address) - await expect(factory.setFeeToSetter(wallet.address)).to.be.revertedWith('UniswapV2: FORBIDDEN') - }) -}) diff --git a/lib/v2-core/test/UniswapV2Pair.spec.ts b/lib/v2-core/test/UniswapV2Pair.spec.ts deleted file mode 100644 index 93179d1..0000000 --- a/lib/v2-core/test/UniswapV2Pair.spec.ts +++ /dev/null @@ -1,284 +0,0 @@ -import chai, { expect } from 'chai' -import { Contract } from 'ethers' -import { solidity, MockProvider, createFixtureLoader } from 'ethereum-waffle' -import { BigNumber, bigNumberify } from 'ethers/utils' - -import { expandTo18Decimals, mineBlock, encodePrice } from './shared/utilities' -import { pairFixture } from './shared/fixtures' -import { AddressZero } from 'ethers/constants' - -const MINIMUM_LIQUIDITY = bigNumberify(10).pow(3) - -chai.use(solidity) - -const overrides = { - gasLimit: 9999999 -} - -describe('UniswapV2Pair', () => { - const provider = new MockProvider({ - hardfork: 'istanbul', - mnemonic: 'horn horn horn horn horn horn horn horn horn horn horn horn', - gasLimit: 9999999 - }) - const [wallet, other] = provider.getWallets() - const loadFixture = createFixtureLoader(provider, [wallet]) - - let factory: Contract - let token0: Contract - let token1: Contract - let pair: Contract - beforeEach(async () => { - const fixture = await loadFixture(pairFixture) - factory = fixture.factory - token0 = fixture.token0 - token1 = fixture.token1 - pair = fixture.pair - }) - - it('mint', async () => { - const token0Amount = expandTo18Decimals(1) - const token1Amount = expandTo18Decimals(4) - await token0.transfer(pair.address, token0Amount) - await token1.transfer(pair.address, token1Amount) - - const expectedLiquidity = expandTo18Decimals(2) - await expect(pair.mint(wallet.address, overrides)) - .to.emit(pair, 'Transfer') - .withArgs(AddressZero, AddressZero, MINIMUM_LIQUIDITY) - .to.emit(pair, 'Transfer') - .withArgs(AddressZero, wallet.address, expectedLiquidity.sub(MINIMUM_LIQUIDITY)) - .to.emit(pair, 'Sync') - .withArgs(token0Amount, token1Amount) - .to.emit(pair, 'Mint') - .withArgs(wallet.address, token0Amount, token1Amount) - - expect(await pair.totalSupply()).to.eq(expectedLiquidity) - expect(await pair.balanceOf(wallet.address)).to.eq(expectedLiquidity.sub(MINIMUM_LIQUIDITY)) - expect(await token0.balanceOf(pair.address)).to.eq(token0Amount) - expect(await token1.balanceOf(pair.address)).to.eq(token1Amount) - const reserves = await pair.getReserves() - expect(reserves[0]).to.eq(token0Amount) - expect(reserves[1]).to.eq(token1Amount) - }) - - async function addLiquidity(token0Amount: BigNumber, token1Amount: BigNumber) { - await token0.transfer(pair.address, token0Amount) - await token1.transfer(pair.address, token1Amount) - await pair.mint(wallet.address, overrides) - } - const swapTestCases: BigNumber[][] = [ - [1, 5, 10, '1662497915624478906'], - [1, 10, 5, '453305446940074565'], - - [2, 5, 10, '2851015155847869602'], - [2, 10, 5, '831248957812239453'], - - [1, 10, 10, '906610893880149131'], - [1, 100, 100, '987158034397061298'], - [1, 1000, 1000, '996006981039903216'] - ].map(a => a.map(n => (typeof n === 'string' ? bigNumberify(n) : expandTo18Decimals(n)))) - swapTestCases.forEach((swapTestCase, i) => { - it(`getInputPrice:${i}`, async () => { - const [swapAmount, token0Amount, token1Amount, expectedOutputAmount] = swapTestCase - await addLiquidity(token0Amount, token1Amount) - await token0.transfer(pair.address, swapAmount) - await expect(pair.swap(0, expectedOutputAmount.add(1), wallet.address, '0x', overrides)).to.be.revertedWith( - 'UniswapV2: K' - ) - await pair.swap(0, expectedOutputAmount, wallet.address, '0x', overrides) - }) - }) - - const optimisticTestCases: BigNumber[][] = [ - ['997000000000000000', 5, 10, 1], // given amountIn, amountOut = floor(amountIn * .997) - ['997000000000000000', 10, 5, 1], - ['997000000000000000', 5, 5, 1], - [1, 5, 5, '1003009027081243732'] // given amountOut, amountIn = ceiling(amountOut / .997) - ].map(a => a.map(n => (typeof n === 'string' ? bigNumberify(n) : expandTo18Decimals(n)))) - optimisticTestCases.forEach((optimisticTestCase, i) => { - it(`optimistic:${i}`, async () => { - const [outputAmount, token0Amount, token1Amount, inputAmount] = optimisticTestCase - await addLiquidity(token0Amount, token1Amount) - await token0.transfer(pair.address, inputAmount) - await expect(pair.swap(outputAmount.add(1), 0, wallet.address, '0x', overrides)).to.be.revertedWith( - 'UniswapV2: K' - ) - await pair.swap(outputAmount, 0, wallet.address, '0x', overrides) - }) - }) - - it('swap:token0', async () => { - const token0Amount = expandTo18Decimals(5) - const token1Amount = expandTo18Decimals(10) - await addLiquidity(token0Amount, token1Amount) - - const swapAmount = expandTo18Decimals(1) - const expectedOutputAmount = bigNumberify('1662497915624478906') - await token0.transfer(pair.address, swapAmount) - await expect(pair.swap(0, expectedOutputAmount, wallet.address, '0x', overrides)) - .to.emit(token1, 'Transfer') - .withArgs(pair.address, wallet.address, expectedOutputAmount) - .to.emit(pair, 'Sync') - .withArgs(token0Amount.add(swapAmount), token1Amount.sub(expectedOutputAmount)) - .to.emit(pair, 'Swap') - .withArgs(wallet.address, swapAmount, 0, 0, expectedOutputAmount, wallet.address) - - const reserves = await pair.getReserves() - expect(reserves[0]).to.eq(token0Amount.add(swapAmount)) - expect(reserves[1]).to.eq(token1Amount.sub(expectedOutputAmount)) - expect(await token0.balanceOf(pair.address)).to.eq(token0Amount.add(swapAmount)) - expect(await token1.balanceOf(pair.address)).to.eq(token1Amount.sub(expectedOutputAmount)) - const totalSupplyToken0 = await token0.totalSupply() - const totalSupplyToken1 = await token1.totalSupply() - expect(await token0.balanceOf(wallet.address)).to.eq(totalSupplyToken0.sub(token0Amount).sub(swapAmount)) - expect(await token1.balanceOf(wallet.address)).to.eq(totalSupplyToken1.sub(token1Amount).add(expectedOutputAmount)) - }) - - it('swap:token1', async () => { - const token0Amount = expandTo18Decimals(5) - const token1Amount = expandTo18Decimals(10) - await addLiquidity(token0Amount, token1Amount) - - const swapAmount = expandTo18Decimals(1) - const expectedOutputAmount = bigNumberify('453305446940074565') - await token1.transfer(pair.address, swapAmount) - await expect(pair.swap(expectedOutputAmount, 0, wallet.address, '0x', overrides)) - .to.emit(token0, 'Transfer') - .withArgs(pair.address, wallet.address, expectedOutputAmount) - .to.emit(pair, 'Sync') - .withArgs(token0Amount.sub(expectedOutputAmount), token1Amount.add(swapAmount)) - .to.emit(pair, 'Swap') - .withArgs(wallet.address, 0, swapAmount, expectedOutputAmount, 0, wallet.address) - - const reserves = await pair.getReserves() - expect(reserves[0]).to.eq(token0Amount.sub(expectedOutputAmount)) - expect(reserves[1]).to.eq(token1Amount.add(swapAmount)) - expect(await token0.balanceOf(pair.address)).to.eq(token0Amount.sub(expectedOutputAmount)) - expect(await token1.balanceOf(pair.address)).to.eq(token1Amount.add(swapAmount)) - const totalSupplyToken0 = await token0.totalSupply() - const totalSupplyToken1 = await token1.totalSupply() - expect(await token0.balanceOf(wallet.address)).to.eq(totalSupplyToken0.sub(token0Amount).add(expectedOutputAmount)) - expect(await token1.balanceOf(wallet.address)).to.eq(totalSupplyToken1.sub(token1Amount).sub(swapAmount)) - }) - - it('swap:gas', async () => { - const token0Amount = expandTo18Decimals(5) - const token1Amount = expandTo18Decimals(10) - await addLiquidity(token0Amount, token1Amount) - - // ensure that setting price{0,1}CumulativeLast for the first time doesn't affect our gas math - await mineBlock(provider, (await provider.getBlock('latest')).timestamp + 1) - await pair.sync(overrides) - - const swapAmount = expandTo18Decimals(1) - const expectedOutputAmount = bigNumberify('453305446940074565') - await token1.transfer(pair.address, swapAmount) - await mineBlock(provider, (await provider.getBlock('latest')).timestamp + 1) - const tx = await pair.swap(expectedOutputAmount, 0, wallet.address, '0x', overrides) - const receipt = await tx.wait() - expect(receipt.gasUsed).to.eq(73462) - }) - - it('burn', async () => { - const token0Amount = expandTo18Decimals(3) - const token1Amount = expandTo18Decimals(3) - await addLiquidity(token0Amount, token1Amount) - - const expectedLiquidity = expandTo18Decimals(3) - await pair.transfer(pair.address, expectedLiquidity.sub(MINIMUM_LIQUIDITY)) - await expect(pair.burn(wallet.address, overrides)) - .to.emit(pair, 'Transfer') - .withArgs(pair.address, AddressZero, expectedLiquidity.sub(MINIMUM_LIQUIDITY)) - .to.emit(token0, 'Transfer') - .withArgs(pair.address, wallet.address, token0Amount.sub(1000)) - .to.emit(token1, 'Transfer') - .withArgs(pair.address, wallet.address, token1Amount.sub(1000)) - .to.emit(pair, 'Sync') - .withArgs(1000, 1000) - .to.emit(pair, 'Burn') - .withArgs(wallet.address, token0Amount.sub(1000), token1Amount.sub(1000), wallet.address) - - expect(await pair.balanceOf(wallet.address)).to.eq(0) - expect(await pair.totalSupply()).to.eq(MINIMUM_LIQUIDITY) - expect(await token0.balanceOf(pair.address)).to.eq(1000) - expect(await token1.balanceOf(pair.address)).to.eq(1000) - const totalSupplyToken0 = await token0.totalSupply() - const totalSupplyToken1 = await token1.totalSupply() - expect(await token0.balanceOf(wallet.address)).to.eq(totalSupplyToken0.sub(1000)) - expect(await token1.balanceOf(wallet.address)).to.eq(totalSupplyToken1.sub(1000)) - }) - - it('price{0,1}CumulativeLast', async () => { - const token0Amount = expandTo18Decimals(3) - const token1Amount = expandTo18Decimals(3) - await addLiquidity(token0Amount, token1Amount) - - const blockTimestamp = (await pair.getReserves())[2] - await mineBlock(provider, blockTimestamp + 1) - await pair.sync(overrides) - - const initialPrice = encodePrice(token0Amount, token1Amount) - expect(await pair.price0CumulativeLast()).to.eq(initialPrice[0]) - expect(await pair.price1CumulativeLast()).to.eq(initialPrice[1]) - expect((await pair.getReserves())[2]).to.eq(blockTimestamp + 1) - - const swapAmount = expandTo18Decimals(3) - await token0.transfer(pair.address, swapAmount) - await mineBlock(provider, blockTimestamp + 10) - // swap to a new price eagerly instead of syncing - await pair.swap(0, expandTo18Decimals(1), wallet.address, '0x', overrides) // make the price nice - - expect(await pair.price0CumulativeLast()).to.eq(initialPrice[0].mul(10)) - expect(await pair.price1CumulativeLast()).to.eq(initialPrice[1].mul(10)) - expect((await pair.getReserves())[2]).to.eq(blockTimestamp + 10) - - await mineBlock(provider, blockTimestamp + 20) - await pair.sync(overrides) - - const newPrice = encodePrice(expandTo18Decimals(6), expandTo18Decimals(2)) - expect(await pair.price0CumulativeLast()).to.eq(initialPrice[0].mul(10).add(newPrice[0].mul(10))) - expect(await pair.price1CumulativeLast()).to.eq(initialPrice[1].mul(10).add(newPrice[1].mul(10))) - expect((await pair.getReserves())[2]).to.eq(blockTimestamp + 20) - }) - - it('feeTo:off', async () => { - const token0Amount = expandTo18Decimals(1000) - const token1Amount = expandTo18Decimals(1000) - await addLiquidity(token0Amount, token1Amount) - - const swapAmount = expandTo18Decimals(1) - const expectedOutputAmount = bigNumberify('996006981039903216') - await token1.transfer(pair.address, swapAmount) - await pair.swap(expectedOutputAmount, 0, wallet.address, '0x', overrides) - - const expectedLiquidity = expandTo18Decimals(1000) - await pair.transfer(pair.address, expectedLiquidity.sub(MINIMUM_LIQUIDITY)) - await pair.burn(wallet.address, overrides) - expect(await pair.totalSupply()).to.eq(MINIMUM_LIQUIDITY) - }) - - it('feeTo:on', async () => { - await factory.setFeeTo(other.address) - - const token0Amount = expandTo18Decimals(1000) - const token1Amount = expandTo18Decimals(1000) - await addLiquidity(token0Amount, token1Amount) - - const swapAmount = expandTo18Decimals(1) - const expectedOutputAmount = bigNumberify('996006981039903216') - await token1.transfer(pair.address, swapAmount) - await pair.swap(expectedOutputAmount, 0, wallet.address, '0x', overrides) - - const expectedLiquidity = expandTo18Decimals(1000) - await pair.transfer(pair.address, expectedLiquidity.sub(MINIMUM_LIQUIDITY)) - await pair.burn(wallet.address, overrides) - expect(await pair.totalSupply()).to.eq(MINIMUM_LIQUIDITY.add('249750499251388')) - expect(await pair.balanceOf(other.address)).to.eq('249750499251388') - - // using 1000 here instead of the symbolic MINIMUM_LIQUIDITY because the amounts only happen to be equal... - // ...because the initial liquidity amounts were equal - expect(await token0.balanceOf(pair.address)).to.eq(bigNumberify(1000).add('249501683697445')) - expect(await token1.balanceOf(pair.address)).to.eq(bigNumberify(1000).add('250000187312969')) - }) -}) diff --git a/lib/v2-core/test/shared/fixtures.ts b/lib/v2-core/test/shared/fixtures.ts deleted file mode 100644 index 8cca572..0000000 --- a/lib/v2-core/test/shared/fixtures.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Contract, Wallet } from 'ethers' -import { Web3Provider } from 'ethers/providers' -import { deployContract } from 'ethereum-waffle' - -import { expandTo18Decimals } from './utilities' - -import ERC20 from '../../build/ERC20.json' -import UniswapV2Factory from '../../build/UniswapV2Factory.json' -import UniswapV2Pair from '../../build/UniswapV2Pair.json' - -interface FactoryFixture { - factory: Contract -} - -const overrides = { - gasLimit: 9999999 -} - -export async function factoryFixture(_: Web3Provider, [wallet]: Wallet[]): Promise { - const factory = await deployContract(wallet, UniswapV2Factory, [wallet.address], overrides) - return { factory } -} - -interface PairFixture extends FactoryFixture { - token0: Contract - token1: Contract - pair: Contract -} - -export async function pairFixture(provider: Web3Provider, [wallet]: Wallet[]): Promise { - const { factory } = await factoryFixture(provider, [wallet]) - - const tokenA = await deployContract(wallet, ERC20, [expandTo18Decimals(10000)], overrides) - const tokenB = await deployContract(wallet, ERC20, [expandTo18Decimals(10000)], overrides) - - await factory.createPair(tokenA.address, tokenB.address, overrides) - const pairAddress = await factory.getPair(tokenA.address, tokenB.address) - const pair = new Contract(pairAddress, JSON.stringify(UniswapV2Pair.abi), provider).connect(wallet) - - const token0Address = (await pair.token0()).address - const token0 = tokenA.address === token0Address ? tokenA : tokenB - const token1 = tokenA.address === token0Address ? tokenB : tokenA - - return { factory, token0, token1, pair } -} diff --git a/lib/v2-core/test/shared/utilities.ts b/lib/v2-core/test/shared/utilities.ts deleted file mode 100644 index 8111516..0000000 --- a/lib/v2-core/test/shared/utilities.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { Contract } from 'ethers' -import { Web3Provider } from 'ethers/providers' -import { - BigNumber, - bigNumberify, - getAddress, - keccak256, - defaultAbiCoder, - toUtf8Bytes, - solidityPack -} from 'ethers/utils' - -const PERMIT_TYPEHASH = keccak256( - toUtf8Bytes('Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)') -) - -export function expandTo18Decimals(n: number): BigNumber { - return bigNumberify(n).mul(bigNumberify(10).pow(18)) -} - -function getDomainSeparator(name: string, tokenAddress: string) { - return keccak256( - defaultAbiCoder.encode( - ['bytes32', 'bytes32', 'bytes32', 'uint256', 'address'], - [ - keccak256(toUtf8Bytes('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')), - keccak256(toUtf8Bytes(name)), - keccak256(toUtf8Bytes('1')), - 1, - tokenAddress - ] - ) - ) -} - -export function getCreate2Address( - factoryAddress: string, - [tokenA, tokenB]: [string, string], - bytecode: string -): string { - const [token0, token1] = tokenA < tokenB ? [tokenA, tokenB] : [tokenB, tokenA] - const create2Inputs = [ - '0xff', - factoryAddress, - keccak256(solidityPack(['address', 'address'], [token0, token1])), - keccak256(bytecode) - ] - const sanitizedInputs = `0x${create2Inputs.map(i => i.slice(2)).join('')}` - return getAddress(`0x${keccak256(sanitizedInputs).slice(-40)}`) -} - -export async function getApprovalDigest( - token: Contract, - approve: { - owner: string - spender: string - value: BigNumber - }, - nonce: BigNumber, - deadline: BigNumber -): Promise { - const name = await token.name() - const DOMAIN_SEPARATOR = getDomainSeparator(name, token.address) - return keccak256( - solidityPack( - ['bytes1', 'bytes1', 'bytes32', 'bytes32'], - [ - '0x19', - '0x01', - DOMAIN_SEPARATOR, - keccak256( - defaultAbiCoder.encode( - ['bytes32', 'address', 'address', 'uint256', 'uint256', 'uint256'], - [PERMIT_TYPEHASH, approve.owner, approve.spender, approve.value, nonce, deadline] - ) - ) - ] - ) - ) -} - -export async function mineBlock(provider: Web3Provider, timestamp: number): Promise { - await new Promise(async (resolve, reject) => { - ;(provider._web3Provider.sendAsync as any)( - { jsonrpc: '2.0', method: 'evm_mine', params: [timestamp] }, - (error: any, result: any): void => { - if (error) { - reject(error) - } else { - resolve(result) - } - } - ) - }) -} - -export function encodePrice(reserve0: BigNumber, reserve1: BigNumber) { - return [reserve1.mul(bigNumberify(2).pow(112)).div(reserve0), reserve0.mul(bigNumberify(2).pow(112)).div(reserve1)] -} diff --git a/lib/v2-core/tsconfig.json b/lib/v2-core/tsconfig.json deleted file mode 100644 index 13ad6fe..0000000 --- a/lib/v2-core/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "compilerOptions": { - "target": "es5", - "module": "commonjs", - "strict": true, - "esModuleInterop": true, - "resolveJsonModule": true - } -} diff --git a/lib/v2-core/yarn.lock b/lib/v2-core/yarn.lock deleted file mode 100644 index 479002b..0000000 --- a/lib/v2-core/yarn.lock +++ /dev/null @@ -1,7195 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@ethereum-waffle/chai@^2.4.1": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/chai/-/chai-2.4.1.tgz#47a6cc2eebaca775b169b524a6dc0cfcf3d3c22d" - integrity sha512-EMH8UtwhsSaCeUIlH72JPaUGhYTIeHJW0aVSM9EXKh0SMNJpptaHCz5dFpjoRwvhtVwOynuCc7SpFXMq7p8T0A== - dependencies: - ethers "^4.0.45" - -"@ethereum-waffle/compiler@^2.4.1": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/compiler/-/compiler-2.4.1.tgz#8a1f0b4c5be8e22408a391944d3ecc7fc92e49a5" - integrity sha512-f+o79gKFzXaan2IOvjYRFlnR2ae3bzDET6otiH9N27hYUx5w0AQRNDkQEpVcS+sjUL9WV6ZzcFlXcVsM6144fg== - dependencies: - "@resolver-engine/imports" "^0.3.3" - "@resolver-engine/imports-fs" "^0.3.3" - "@types/mkdirp" "^0.5.2" - "@types/node-fetch" "^2.5.5" - mkdirp "^0.5.1" - node-fetch "^2.6.0" - solc "^0.6.3" - -"@ethereum-waffle/provider@^2.4.1": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/provider/-/provider-2.4.1.tgz#5480be31f9c655864e3eede374759973d20947ef" - integrity sha512-OhRQfQlR6BsgGUEaeeaQXztbRQ0v/AmwEdmWHmBwJN6NX/FjLmOTIyF3LBWBFHH4K5GgSCDhFs6w5Khz+ojRKg== - dependencies: - ethers "^4.0.45" - ganache-core "^2.10.2" - -"@resolver-engine/core@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@resolver-engine/core/-/core-0.3.3.tgz#590f77d85d45bc7ecc4e06c654f41345db6ca967" - integrity sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ== - dependencies: - debug "^3.1.0" - is-url "^1.2.4" - request "^2.85.0" - -"@resolver-engine/fs@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@resolver-engine/fs/-/fs-0.3.3.tgz#fbf83fa0c4f60154a82c817d2fe3f3b0c049a973" - integrity sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ== - dependencies: - "@resolver-engine/core" "^0.3.3" - debug "^3.1.0" - -"@resolver-engine/imports-fs@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@resolver-engine/imports-fs/-/imports-fs-0.3.3.tgz#4085db4b8d3c03feb7a425fbfcf5325c0d1e6c1b" - integrity sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA== - dependencies: - "@resolver-engine/fs" "^0.3.3" - "@resolver-engine/imports" "^0.3.3" - debug "^3.1.0" - -"@resolver-engine/imports@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@resolver-engine/imports/-/imports-0.3.3.tgz#badfb513bb3ff3c1ee9fd56073e3144245588bcc" - integrity sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q== - dependencies: - "@resolver-engine/core" "^0.3.3" - debug "^3.1.0" - hosted-git-info "^2.6.0" - path-browserify "^1.0.0" - url "^0.11.0" - -"@sindresorhus/is@^0.14.0": - version "0.14.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" - integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== - -"@szmarczak/http-timer@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" - integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== - dependencies: - defer-to-connect "^1.0.1" - -"@types/bignumber.js@^5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@types/bignumber.js/-/bignumber.js-5.0.0.tgz#d9f1a378509f3010a3255e9cc822ad0eeb4ab969" - integrity sha512-0DH7aPGCClywOFaxxjE6UwpN2kQYe9LwuDQMv+zYA97j5GkOMo8e66LYT+a8JYU7jfmUFRZLa9KycxHDsKXJCA== - dependencies: - bignumber.js "*" - -"@types/bn.js@^4.11.3", "@types/bn.js@^4.11.4": - 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/chai@^4.2.6": - version "4.2.7" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.7.tgz#1c8c25cbf6e59ffa7d6b9652c78e547d9a41692d" - integrity sha512-luq8meHGYwvky0O7u0eQZdA7B4Wd9owUCqvbw2m3XCrCU8mplYOujMBbvyS547AxJkC+pGnd0Cm15eNxEUNU8g== - -"@types/mkdirp@^0.5.2": - version "0.5.2" - resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-0.5.2.tgz#503aacfe5cc2703d5484326b1b27efa67a339c1f" - integrity sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg== - dependencies: - "@types/node" "*" - -"@types/mocha@^5.2.7": - version "5.2.7" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.7.tgz#315d570ccb56c53452ff8638738df60726d5b6ea" - integrity sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ== - -"@types/node-fetch@^2.5.5": - version "2.5.6" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.6.tgz#df8377a66e64ddf75b65b072e37b3c5c5425a96f" - integrity sha512-2w0NTwMWF1d3NJMK0Uiq2UNN8htVCyOWOD0jIPjPgC5Ph/YP4dVhs9YxxcMcuLuwAslz0dVEcZQUaqkLs3IzOQ== - dependencies: - "@types/node" "*" - form-data "^3.0.0" - -"@types/node@*": - version "13.11.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-13.11.1.tgz#49a2a83df9d26daacead30d0ccc8762b128d53c7" - integrity sha512-eWQGP3qtxwL8FGneRrC5DwrJLGN4/dH1clNTuLfN81HCrxVtxRjygDTUoZJ5ASlDEeo0ppYFQjQIlXhtXpOn6g== - -"@types/node@^10.12.18", "@types/node@^10.3.2": - version "10.17.19" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.19.tgz#1d31ddd5503dba2af7a901aafef3392e4955620e" - integrity sha512-46/xThm3zvvc9t9/7M3AaLEqtOpqlYYYcCZbpYVAQHG20+oMZBkae/VMrn4BTi6AJ8cpack0mEXhGiKmDNbLrQ== - -"@types/node@^12.6.1": - version "12.12.35" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.35.tgz#1e61b226c14380f4384f70cfe49a65c2c553ad2b" - integrity sha512-ASYsaKecA7TUsDrqIGPNk3JeEox0z/0XR/WsJJ8BIX/9+SkMSImQXKWfU/yBrSyc7ZSE/NPqLu36Nur0miCFfQ== - -"@web3-js/scrypt-shim@^0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@web3-js/scrypt-shim/-/scrypt-shim-0.1.0.tgz#0bf7529ab6788311d3e07586f7d89107c3bea2cc" - integrity sha512-ZtZeWCc/s0nMcdx/+rZwY1EcuRdemOK9ag21ty9UsHkFxsNb/AaoucUz0iPuyGe0Ku+PFuRmWZG7Z7462p9xPw== - dependencies: - scryptsy "^2.1.0" - semver "^6.3.0" - -"@web3-js/websocket@^1.0.29": - version "1.0.30" - resolved "https://registry.yarnpkg.com/@web3-js/websocket/-/websocket-1.0.30.tgz#9ea15b7b582cf3bf3e8bc1f4d3d54c0731a87f87" - integrity sha512-fDwrD47MiDrzcJdSeTLF75aCcxVVt8B1N74rA+vh2XCAvFy4tEWJjtnUtj2QG7/zlQ6g9cQ88bZFBxwd9/FmtA== - dependencies: - debug "^2.2.0" - es5-ext "^0.10.50" - nan "^2.14.0" - typedarray-to-buffer "^3.1.5" - yaeti "^0.0.6" - -abstract-leveldown@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-3.0.0.tgz#5cb89f958a44f526779d740d1440e743e0c30a57" - integrity sha512-KUWx9UWGQD12zsmLNj64/pndaz4iJh/Pj7nopgkfDG6RlCcbMZvT6+9l7dchK4idog2Is8VdC/PvNbFuFmalIQ== - dependencies: - xtend "~4.0.0" - -abstract-leveldown@^2.4.1, abstract-leveldown@~2.7.1: - version "2.7.2" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz#87a44d7ebebc341d59665204834c8b7e0932cc93" - integrity sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w== - dependencies: - xtend "~4.0.0" - -abstract-leveldown@^5.0.0, abstract-leveldown@~5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz#f7128e1f86ccabf7d2893077ce5d06d798e386c6" - integrity sha512-5mU5P1gXtsMIXg65/rsYGsi93+MlogXZ9FA8JnwKurHQg64bfXwGYVdVdijNTVNOlAsuIiOwHdvFFD5JqCJQ7A== - dependencies: - xtend "~4.0.0" - -abstract-leveldown@~2.6.0: - version "2.6.3" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz#1c5e8c6a5ef965ae8c35dfb3a8770c476b82c4b8" - integrity sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA== - dependencies: - xtend "~4.0.0" - -accepts@~1.3.7: - version "1.3.7" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" - integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== - dependencies: - mime-types "~2.1.24" - negotiator "0.6.2" - -aes-js@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" - integrity sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0= - -aes-js@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.2.tgz#db9aabde85d5caabbfc0d4f2a4446960f627146a" - integrity sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ== - -ajv@^6.5.5: - version "6.12.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.0.tgz#06d60b96d87b8454a5adaba86e7854da629db4b7" - integrity sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw== - 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" - -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@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" - integrity sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA== - dependencies: - ansi-wrap "^0.1.0" - -ansi-gray@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" - integrity sha1-KWLPVOyXksSFEKPetSRDaGHvclE= - dependencies: - ansi-wrap "0.1.0" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= - -ansi-styles@^3.2.0, ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-wrap@0.1.0, ansi-wrap@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" - integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768= - -any-promise@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" - integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= - -anymatch@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== - dependencies: - micromatch "^3.1.4" - normalize-path "^2.1.1" - -append-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/append-buffer/-/append-buffer-1.0.2.tgz#d8220cf466081525efea50614f3de6514dfa58f1" - integrity sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE= - dependencies: - buffer-equal "^1.0.0" - -archy@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" - integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA= - -arg@^4.1.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.2.tgz#e70c90579e02c63d80e3ad4e31d8bfdb8bd50064" - integrity sha512-+ytCkGcBtHZ3V2r2Z06AncYO8jz46UEamcspGoU8lHcEbpn6J77QK0vdWvChsclg/tM5XIJC5tnjmPp7Eq6Obg== - -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" - -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= - -arr-filter@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/arr-filter/-/arr-filter-1.1.2.tgz#43fdddd091e8ef11aa4c45d9cdc18e2dff1711ee" - integrity sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4= - dependencies: - make-iterator "^1.0.0" - -arr-flatten@^1.0.1, arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - -arr-map@^2.0.0, arr-map@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/arr-map/-/arr-map-2.0.2.tgz#3a77345ffc1cf35e2a91825601f9e58f2e24cac4" - integrity sha1-Onc0X/wc814qkYJWAfnljy4kysQ= - dependencies: - make-iterator "^1.0.0" - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= - -array-each@^1.0.0, array-each@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f" - integrity sha1-p5SvDAWrF1KEbudTofIRoFugxE8= - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= - -array-initial@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/array-initial/-/array-initial-1.1.0.tgz#2fa74b26739371c3947bd7a7adc73be334b3d795" - integrity sha1-L6dLJnOTccOUe9enrcc74zSz15U= - dependencies: - array-slice "^1.0.0" - is-number "^4.0.0" - -array-last@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/array-last/-/array-last-1.3.0.tgz#7aa77073fec565ddab2493f5f88185f404a9d336" - integrity sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg== - dependencies: - is-number "^4.0.0" - -array-slice@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-1.1.0.tgz#e368ea15f89bc7069f7ffb89aec3a6c7d4ac22d4" - integrity sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w== - -array-sort@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-sort/-/array-sort-1.0.0.tgz#e4c05356453f56f53512a7d1d6123f2c54c0a88a" - integrity sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg== - dependencies: - default-compare "^1.0.0" - get-value "^2.0.6" - kind-of "^5.0.2" - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= - -asn1.js@^4.0.0: - version "4.10.1" - resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" - integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== - dependencies: - bn.js "^4.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - -assertion-error@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" - integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= - -async-done@^1.2.0, async-done@^1.2.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/async-done/-/async-done-1.3.2.tgz#5e15aa729962a4b07414f528a88cdf18e0b290a2" - integrity sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.2" - process-nextick-args "^2.0.0" - stream-exhaust "^1.0.1" - -async-each@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" - integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== - -async-eventemitter@^0.2.2: - version "0.2.4" - resolved "https://registry.yarnpkg.com/async-eventemitter/-/async-eventemitter-0.2.4.tgz#f5e7c8ca7d3e46aab9ec40a292baf686a0bafaca" - integrity sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw== - dependencies: - async "^2.4.0" - -async-limiter@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" - integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== - -async-settle@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/async-settle/-/async-settle-1.0.0.tgz#1d0a914bb02575bec8a8f3a74e5080f72b2c0c6b" - integrity sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs= - dependencies: - async-done "^1.2.2" - -async@2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.2.tgz#18330ea7e6e313887f5d2f2a904bac6fe4dd5381" - integrity sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg== - dependencies: - lodash "^4.17.11" - -async@^1.4.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" - integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= - -async@^2.0.1, async@^2.1.2, async@^2.4.0, async@^2.5.0, async@^2.6.1: - version "2.6.3" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" - integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== - dependencies: - lodash "^4.17.14" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -atob@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" - integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug== - -babel-code-frame@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" - integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= - dependencies: - chalk "^1.1.3" - esutils "^2.0.2" - js-tokens "^3.0.2" - -babel-core@^6.0.14, babel-core@^6.26.0: - version "6.26.3" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" - integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA== - dependencies: - babel-code-frame "^6.26.0" - babel-generator "^6.26.0" - babel-helpers "^6.24.1" - babel-messages "^6.23.0" - babel-register "^6.26.0" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - convert-source-map "^1.5.1" - debug "^2.6.9" - json5 "^0.5.1" - lodash "^4.17.4" - minimatch "^3.0.4" - path-is-absolute "^1.0.1" - private "^0.1.8" - slash "^1.0.0" - source-map "^0.5.7" - -babel-generator@^6.26.0: - version "6.26.1" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" - integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== - dependencies: - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - detect-indent "^4.0.0" - jsesc "^1.3.0" - lodash "^4.17.4" - source-map "^0.5.7" - trim-right "^1.0.1" - -babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" - integrity sha1-zORReto1b0IgvK6KAsKzRvmlZmQ= - dependencies: - babel-helper-explode-assignable-expression "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-call-delegate@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" - integrity sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340= - dependencies: - babel-helper-hoist-variables "^6.24.1" - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-define-map@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" - integrity sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8= - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-helper-explode-assignable-expression@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" - integrity sha1-8luCz33BBDPFX3BZLVdGQArCLKo= - dependencies: - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-function-name@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" - integrity sha1-00dbjAPtmCQqJbSDUasYOZ01gKk= - dependencies: - babel-helper-get-function-arity "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-get-function-arity@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" - integrity sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-hoist-variables@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" - integrity sha1-HssnaJydJVE+rbyZFKc/VAi+enY= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-optimise-call-expression@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" - integrity sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-regex@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" - integrity sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI= - dependencies: - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-helper-remap-async-to-generator@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" - integrity sha1-XsWBgnrXI/7N04HxySg5BnbkVRs= - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-replace-supers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" - integrity sha1-v22/5Dk40XNpohPKiov3S2qQqxo= - dependencies: - babel-helper-optimise-call-expression "^6.24.1" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helpers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" - integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI= - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-messages@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" - integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-check-es2015-constants@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" - integrity sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-syntax-async-functions@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" - integrity sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU= - -babel-plugin-syntax-exponentiation-operator@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" - integrity sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4= - -babel-plugin-syntax-trailing-function-commas@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" - integrity sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM= - -babel-plugin-transform-async-to-generator@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" - integrity sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E= - dependencies: - babel-helper-remap-async-to-generator "^6.24.1" - babel-plugin-syntax-async-functions "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-arrow-functions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" - integrity sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" - integrity sha1-u8UbSflk1wy42OC5ToICRs46YUE= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-block-scoping@^6.23.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" - integrity sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8= - dependencies: - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-plugin-transform-es2015-classes@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" - integrity sha1-WkxYpQyclGHlZLSyo7+ryXolhNs= - dependencies: - babel-helper-define-map "^6.24.1" - babel-helper-function-name "^6.24.1" - babel-helper-optimise-call-expression "^6.24.1" - babel-helper-replace-supers "^6.24.1" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-computed-properties@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" - integrity sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM= - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-destructuring@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" - integrity sha1-mXux8auWf2gtKwh2/jWNYOdlxW0= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-duplicate-keys@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" - integrity sha1-c+s9MQypaePvnskcU3QabxV2Qj4= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-for-of@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" - integrity sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-function-name@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" - integrity sha1-g0yJhTvDaxrw86TF26qU/Y6sqos= - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-literals@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" - integrity sha1-T1SgLWzWbPkVKAAZox0xklN3yi4= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" - integrity sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ= - dependencies: - babel-plugin-transform-es2015-modules-commonjs "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: - version "6.26.2" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" - integrity sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q== - dependencies: - babel-plugin-transform-strict-mode "^6.24.1" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-types "^6.26.0" - -babel-plugin-transform-es2015-modules-systemjs@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" - integrity sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM= - dependencies: - babel-helper-hoist-variables "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-modules-umd@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" - integrity sha1-rJl+YoXNGO1hdq22B9YCNErThGg= - dependencies: - babel-plugin-transform-es2015-modules-amd "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-object-super@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" - integrity sha1-JM72muIcuDp/hgPa0CH1cusnj40= - dependencies: - babel-helper-replace-supers "^6.24.1" - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-parameters@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" - integrity sha1-V6w1GrScrxSpfNE7CfZv3wpiXys= - dependencies: - babel-helper-call-delegate "^6.24.1" - babel-helper-get-function-arity "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-shorthand-properties@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" - integrity sha1-JPh11nIch2YbvZmkYi5R8U3jiqA= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-spread@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" - integrity sha1-1taKmfia7cRTbIGlQujdnxdG+NE= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-sticky-regex@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" - integrity sha1-AMHNsaynERLN8M9hJsLta0V8zbw= - dependencies: - babel-helper-regex "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-template-literals@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" - integrity sha1-qEs0UPfp+PH2g51taH2oS7EjbY0= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-typeof-symbol@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" - integrity sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-unicode-regex@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" - integrity sha1-04sS9C6nMj9yk4fxinxa4frrNek= - dependencies: - babel-helper-regex "^6.24.1" - babel-runtime "^6.22.0" - regexpu-core "^2.0.0" - -babel-plugin-transform-exponentiation-operator@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" - integrity sha1-KrDJx/MJj6SJB3cruBP+QejeOg4= - dependencies: - babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" - babel-plugin-syntax-exponentiation-operator "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-regenerator@^6.22.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" - integrity sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8= - dependencies: - regenerator-transform "^0.10.0" - -babel-plugin-transform-strict-mode@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" - integrity sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-preset-env@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" - integrity sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg== - dependencies: - babel-plugin-check-es2015-constants "^6.22.0" - babel-plugin-syntax-trailing-function-commas "^6.22.0" - babel-plugin-transform-async-to-generator "^6.22.0" - babel-plugin-transform-es2015-arrow-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoping "^6.23.0" - babel-plugin-transform-es2015-classes "^6.23.0" - babel-plugin-transform-es2015-computed-properties "^6.22.0" - babel-plugin-transform-es2015-destructuring "^6.23.0" - babel-plugin-transform-es2015-duplicate-keys "^6.22.0" - babel-plugin-transform-es2015-for-of "^6.23.0" - babel-plugin-transform-es2015-function-name "^6.22.0" - babel-plugin-transform-es2015-literals "^6.22.0" - babel-plugin-transform-es2015-modules-amd "^6.22.0" - babel-plugin-transform-es2015-modules-commonjs "^6.23.0" - babel-plugin-transform-es2015-modules-systemjs "^6.23.0" - babel-plugin-transform-es2015-modules-umd "^6.23.0" - babel-plugin-transform-es2015-object-super "^6.22.0" - babel-plugin-transform-es2015-parameters "^6.23.0" - babel-plugin-transform-es2015-shorthand-properties "^6.22.0" - babel-plugin-transform-es2015-spread "^6.22.0" - babel-plugin-transform-es2015-sticky-regex "^6.22.0" - babel-plugin-transform-es2015-template-literals "^6.22.0" - babel-plugin-transform-es2015-typeof-symbol "^6.23.0" - babel-plugin-transform-es2015-unicode-regex "^6.22.0" - babel-plugin-transform-exponentiation-operator "^6.22.0" - babel-plugin-transform-regenerator "^6.22.0" - browserslist "^3.2.6" - invariant "^2.2.2" - semver "^5.3.0" - -babel-register@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" - integrity sha1-btAhFz4vy0htestFxgCahW9kcHE= - dependencies: - babel-core "^6.26.0" - babel-runtime "^6.26.0" - core-js "^2.5.0" - home-or-tmp "^2.0.0" - lodash "^4.17.4" - mkdirp "^0.5.1" - source-map-support "^0.4.15" - -babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" - integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.11.0" - -babel-template@^6.24.1, babel-template@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" - integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= - dependencies: - babel-runtime "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - lodash "^4.17.4" - -babel-traverse@^6.24.1, babel-traverse@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" - integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= - dependencies: - babel-code-frame "^6.26.0" - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - debug "^2.6.8" - globals "^9.18.0" - invariant "^2.2.2" - lodash "^4.17.4" - -babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" - integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= - dependencies: - babel-runtime "^6.26.0" - esutils "^2.0.2" - lodash "^4.17.4" - to-fast-properties "^1.0.3" - -babelify@^7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/babelify/-/babelify-7.3.0.tgz#aa56aede7067fd7bd549666ee16dc285087e88e5" - integrity sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU= - dependencies: - babel-core "^6.0.14" - object-assign "^4.0.0" - -babylon@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" - integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== - -bach@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/bach/-/bach-1.2.0.tgz#4b3ce96bf27134f79a1b414a51c14e34c3bd9880" - integrity sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA= - dependencies: - arr-filter "^1.1.1" - arr-flatten "^1.0.1" - arr-map "^2.0.0" - array-each "^1.0.0" - array-initial "^1.0.0" - array-last "^1.1.1" - async-done "^1.2.2" - async-settle "^1.0.0" - now-and-later "^2.0.0" - -backoff@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/backoff/-/backoff-2.5.0.tgz#f616eda9d3e4b66b8ca7fca79f695722c5f8e26f" - integrity sha1-9hbtqdPktmuMp/ynn2lXIsX44m8= - dependencies: - precond "0.2" - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -base-x@^3.0.2: - version "3.0.8" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.8.tgz#1e1106c2537f0162e8b52474a557ebb09000018d" - integrity sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA== - dependencies: - safe-buffer "^5.0.1" - -base64-js@^1.0.2: - version "1.3.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" - integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== - -base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - -bignumber.js@*: - version "9.0.0" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.0.tgz#805880f84a329b5eac6e7cb6f8274b6d82bdf075" - integrity sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A== - -binary-extensions@^1.0.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" - integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== - -bindings@^1.2.1, bindings@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" - integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== - dependencies: - file-uri-to-path "1.0.0" - -bip39@2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.5.0.tgz#51cbd5179460504a63ea3c000db3f787ca051235" - integrity sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA== - dependencies: - create-hash "^1.1.0" - pbkdf2 "^3.0.9" - randombytes "^2.0.1" - safe-buffer "^5.0.1" - unorm "^1.3.3" - -bip66@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/bip66/-/bip66-1.1.5.tgz#01fa8748785ca70955d5011217d1b3139969ca22" - integrity sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI= - dependencies: - safe-buffer "^5.0.1" - -bl@^1.0.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c" - integrity sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA== - dependencies: - readable-stream "^2.3.5" - safe-buffer "^5.1.1" - -bluebird@^3.5.0: - version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== - -bn.js@4.11.6: - version "4.11.6" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" - integrity sha1-UzRK2xRhehP26N0s4okF0cC6MhU= - -bn.js@4.11.8, bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.10.0, bn.js@^4.11.0, bn.js@^4.11.1, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.4.0, bn.js@^4.8.0: - version "4.11.8" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" - integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== - -body-parser@1.19.0, body-parser@^1.16.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" - integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== - 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" - -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" - -braces@^2.3.1, braces@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - -brorand@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= - -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - -browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.0.6: - version "1.2.0" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" - integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== - dependencies: - buffer-xor "^1.0.3" - cipher-base "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.3" - inherits "^2.0.1" - safe-buffer "^5.0.1" - -browserify-cipher@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" - integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== - dependencies: - browserify-aes "^1.0.4" - browserify-des "^1.0.0" - evp_bytestokey "^1.0.0" - -browserify-des@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" - integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== - dependencies: - cipher-base "^1.0.1" - des.js "^1.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -browserify-rsa@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" - integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= - dependencies: - bn.js "^4.1.0" - randombytes "^2.0.1" - -browserify-sha3@^0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/browserify-sha3/-/browserify-sha3-0.0.4.tgz#086c47b8c82316c9d47022c26185954576dd8e26" - integrity sha1-CGxHuMgjFsnUcCLCYYWVRXbdjiY= - dependencies: - js-sha3 "^0.6.1" - safe-buffer "^5.1.1" - -browserify-sign@^4.0.0: - version "4.0.4" - resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" - integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= - dependencies: - bn.js "^4.1.1" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.2" - elliptic "^6.0.0" - inherits "^2.0.1" - parse-asn1 "^5.0.0" - -browserslist@^3.2.6: - version "3.2.8" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" - integrity sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ== - dependencies: - caniuse-lite "^1.0.30000844" - electron-to-chromium "^1.3.47" - -bs58@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-2.0.1.tgz#55908d58f1982aba2008fa1bed8f91998a29bf8d" - integrity sha1-VZCNWPGYKrogCPob7Y+RmYopv40= - -bs58@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" - integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo= - 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-alloc-unsafe@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" - integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== - -buffer-alloc@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" - integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== - dependencies: - buffer-alloc-unsafe "^1.1.0" - buffer-fill "^1.0.0" - -buffer-crc32@~0.2.3: - version "0.2.13" - resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" - integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= - -buffer-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe" - integrity sha1-WWFrSYME1Var1GaWayLu2j7KX74= - -buffer-fill@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" - integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= - -buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - -buffer-to-arraybuffer@^0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz#6064a40fa76eb43c723aba9ef8f6e1216d10511a" - integrity sha1-YGSkD6dutDxyOrqe+PbhIW0QURo= - -buffer-xor@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= - -buffer@^5.0.5, buffer@^5.2.1: - version "5.6.0" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786" - integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw== - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - -bytes@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" - integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== - -bytewise-core@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/bytewise-core/-/bytewise-core-1.2.3.tgz#3fb410c7e91558eb1ab22a82834577aa6bd61d42" - integrity sha1-P7QQx+kVWOsasiqCg0V3qmvWHUI= - dependencies: - typewise-core "^1.2" - -bytewise@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/bytewise/-/bytewise-1.1.0.tgz#1d13cbff717ae7158094aa881b35d081b387253e" - integrity sha1-HRPL/3F65xWAlKqIGzXQgbOHJT4= - dependencies: - bytewise-core "^1.2.2" - typewise "^1.0.3" - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - -cacheable-request@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" - integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== - dependencies: - clone-response "^1.0.2" - get-stream "^5.1.0" - http-cache-semantics "^4.0.0" - keyv "^3.0.0" - lowercase-keys "^2.0.0" - normalize-url "^4.1.0" - responselike "^1.0.2" - -cachedown@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/cachedown/-/cachedown-1.0.0.tgz#d43f036e4510696b31246d7db31ebf0f7ac32d15" - integrity sha1-1D8DbkUQaWsxJG19sx6/D3rDLRU= - dependencies: - abstract-leveldown "^2.4.1" - lru-cache "^3.2.0" - -camelcase@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" - integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= - -camelcase@^5.0.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -caniuse-lite@^1.0.30000844: - version "1.0.30001041" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001041.tgz#c2ea138dafc6fe03877921ddcddd4a02a14daf76" - integrity sha512-fqDtRCApddNrQuBxBS7kEiSGdBsgO4wiVw4G/IClfqzfhW45MbTumfN4cuUJGTM0YGFNn97DCXPJ683PS6zwvA== - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -chai@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5" - integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw== - 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.0" - type-detect "^4.0.5" - -chalk@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -chalk@^2.0.1: - 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" - -check-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= - -checkpoint-store@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/checkpoint-store/-/checkpoint-store-1.1.0.tgz#04e4cb516b91433893581e6d4601a78e9552ea06" - integrity sha1-BOTLUWuRQziTWB5tRgGnjpVS6gY= - dependencies: - functional-red-black-tree "^1.0.1" - -chokidar@^2.0.0: - version "2.1.8" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" - integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== - 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" - -chownr@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== - -cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - -cliui@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" - integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - wrap-ansi "^2.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" - -clone-buffer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" - integrity sha1-4+JbIHrE5wGvch4staFnksrD3Fg= - -clone-response@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" - integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= - dependencies: - mimic-response "^1.0.0" - -clone-stats@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" - integrity sha1-s3gt/4u1R04Yuba/D9/ngvh3doA= - -clone@2.1.2, clone@^2.0.0, clone@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" - integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= - -cloneable-readable@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.3.tgz#120a00cb053bfb63a222e709f9683ea2e11d8cec" - integrity sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ== - dependencies: - inherits "^2.0.1" - process-nextick-args "^2.0.0" - readable-stream "^2.3.5" - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - -coinstring@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/coinstring/-/coinstring-2.3.0.tgz#cdb63363a961502404a25afb82c2e26d5ff627a4" - integrity sha1-zbYzY6lhUCQEolr7gsLibV/2J6Q= - dependencies: - bs58 "^2.0.1" - create-hash "^1.1.1" - -collection-map@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-map/-/collection-map-1.0.0.tgz#aea0f06f8d26c780c2b75494385544b2255af18c" - integrity sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw= - dependencies: - arr-map "^2.0.2" - for-own "^1.0.0" - make-iterator "^1.0.0" - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-support@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" - integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== - -combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -command-exists@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.8.tgz#715acefdd1223b9c9b37110a149c6392c2852291" - integrity sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw== - -commander@3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" - integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== - -commander@~2.8.1: - version "2.8.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" - integrity sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ= - dependencies: - graceful-readlink ">= 1.0.0" - -component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -concat-stream@^1.5.1, concat-stream@^1.6.0: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -content-disposition@0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" - integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== - dependencies: - safe-buffer "5.1.2" - -content-type@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== - -convert-source-map@^1.5.0, convert-source-map@^1.5.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" - integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== - dependencies: - safe-buffer "~5.1.1" - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= - -cookie@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" - integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== - -cookiejar@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c" - integrity sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA== - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= - -copy-props@^2.0.1: - version "2.0.4" - resolved "https://registry.yarnpkg.com/copy-props/-/copy-props-2.0.4.tgz#93bb1cadfafd31da5bb8a9d4b41f471ec3a72dfe" - integrity sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A== - dependencies: - each-props "^1.3.0" - is-plain-object "^2.0.1" - -core-js-pure@^3.0.1: - version "3.6.5" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.5.tgz#c79e75f5e38dbc85a662d91eea52b8256d53b813" - integrity sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA== - -core-js@^2.4.0, core-js@^2.5.0: - version "2.6.11" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" - integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== - -core-util-is@1.0.2, core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -cors@^2.8.1: - version "2.8.5" - resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" - integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== - dependencies: - object-assign "^4" - vary "^1" - -create-ecdh@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" - integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== - dependencies: - bn.js "^4.1.0" - elliptic "^6.0.0" - -create-hash@^1.1.0, create-hash@^1.1.1, create-hash@^1.1.2, create-hash@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - -create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: - 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" - -cross-fetch@^2.1.0, cross-fetch@^2.1.1: - version "2.2.3" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.2.3.tgz#e8a0b3c54598136e037f8650f8e823ccdfac198e" - integrity sha512-PrWWNH3yL2NYIb/7WF/5vFG3DCQiXDOVf8k3ijatbrtnwNuhMWLC7YF7uqf53tbTFDzHIUD8oITw4Bxt8ST3Nw== - dependencies: - node-fetch "2.1.2" - whatwg-fetch "2.0.4" - -crypto-browserify@3.12.0: - version "3.12.0" - resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" - integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== - dependencies: - browserify-cipher "^1.0.0" - browserify-sign "^4.0.0" - create-ecdh "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.0" - diffie-hellman "^5.0.0" - inherits "^2.0.1" - pbkdf2 "^3.0.3" - public-encrypt "^4.0.0" - randombytes "^2.0.0" - randomfill "^1.0.3" - -d@1, d@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" - integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== - dependencies: - es5-ext "^0.10.50" - type "^1.0.1" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@3.2.6, debug@^3.1.0: - 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" - -decamelize@^1.1.1, decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= - -decode-uri-component@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= - -decompress-response@^3.2.0, decompress-response@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" - integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= - dependencies: - mimic-response "^1.0.0" - -decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" - integrity sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ== - dependencies: - file-type "^5.2.0" - is-stream "^1.1.0" - tar-stream "^1.5.2" - -decompress-tarbz2@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz#3082a5b880ea4043816349f378b56c516be1a39b" - integrity sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A== - dependencies: - decompress-tar "^4.1.0" - file-type "^6.1.0" - is-stream "^1.1.0" - seek-bzip "^1.0.5" - unbzip2-stream "^1.0.9" - -decompress-targz@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/decompress-targz/-/decompress-targz-4.1.1.tgz#c09bc35c4d11f3de09f2d2da53e9de23e7ce1eee" - integrity sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w== - dependencies: - decompress-tar "^4.1.1" - file-type "^5.2.0" - is-stream "^1.1.0" - -decompress-unzip@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/decompress-unzip/-/decompress-unzip-4.0.1.tgz#deaaccdfd14aeaf85578f733ae8210f9b4848f69" - integrity sha1-3qrM39FK6vhVePczroIQ+bSEj2k= - dependencies: - file-type "^3.8.0" - get-stream "^2.2.0" - pify "^2.3.0" - yauzl "^2.4.2" - -decompress@^4.0.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.1.tgz#007f55cc6a62c055afa37c07eb6a4ee1b773f118" - integrity sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ== - dependencies: - decompress-tar "^4.0.0" - decompress-tarbz2 "^4.0.0" - decompress-targz "^4.0.0" - decompress-unzip "^4.0.1" - graceful-fs "^4.1.10" - make-dir "^1.0.0" - pify "^2.3.0" - strip-dirs "^2.0.0" - -deep-eql@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" - integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== - dependencies: - type-detect "^4.0.0" - -deep-equal@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" - integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== - dependencies: - is-arguments "^1.0.4" - is-date-object "^1.0.1" - is-regex "^1.0.4" - object-is "^1.0.1" - object-keys "^1.1.1" - regexp.prototype.flags "^1.2.0" - -default-compare@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/default-compare/-/default-compare-1.0.0.tgz#cb61131844ad84d84788fb68fd01681ca7781a2f" - integrity sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ== - dependencies: - kind-of "^5.0.2" - -default-resolution@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/default-resolution/-/default-resolution-2.0.0.tgz#bcb82baa72ad79b426a76732f1a81ad6df26d684" - integrity sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ= - -defer-to-connect@^1.0.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" - integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== - -deferred-leveldown@~1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz#3acd2e0b75d1669924bc0a4b642851131173e1eb" - integrity sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA== - dependencies: - abstract-leveldown "~2.6.0" - -deferred-leveldown@~4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-4.0.2.tgz#0b0570087827bf480a23494b398f04c128c19a20" - integrity sha512-5fMC8ek8alH16QiV0lTCis610D1Zt1+LA4MS4d63JgS32lrCjTFDUFz2ao09/j2I4Bqb5jL4FZYwu7Jz0XO1ww== - dependencies: - abstract-leveldown "~5.0.0" - inherits "^2.0.3" - -define-properties@^1.1.2, define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - -defined@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" - integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= - -des.js@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" - integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== - dependencies: - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - -destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= - -detect-file@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" - integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= - -detect-indent@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" - integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg= - dependencies: - repeating "^2.0.0" - -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@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -diffie-hellman@^5.0.0: - version "5.0.3" - resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" - integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== - dependencies: - bn.js "^4.1.0" - miller-rabin "^4.0.0" - randombytes "^2.0.0" - -dom-walk@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" - integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== - -dotignore@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/dotignore/-/dotignore-0.1.2.tgz#f942f2200d28c3a76fbdd6f0ee9f3257c8a2e905" - integrity sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw== - dependencies: - minimatch "^3.0.4" - -drbg.js@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/drbg.js/-/drbg.js-1.0.1.tgz#3e36b6c42b37043823cdbc332d58f31e2445480b" - integrity sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs= - dependencies: - browserify-aes "^1.0.6" - create-hash "^1.1.2" - create-hmac "^1.1.4" - -duplexer3@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" - integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= - -duplexify@^3.6.0: - version "3.7.1" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" - integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== - dependencies: - end-of-stream "^1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" - -each-props@^1.3.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/each-props/-/each-props-1.3.2.tgz#ea45a414d16dd5cfa419b1a81720d5ca06892333" - integrity sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA== - dependencies: - is-plain-object "^2.0.1" - object.defaults "^1.1.0" - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= - -electron-to-chromium@^1.3.47: - version "1.3.406" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.406.tgz#d4b8f8c9f7405dddbbb646d6b15042cd7c1e6e61" - integrity sha512-bx8vBZoEbhsMmwEZIj2twzfhFoKKZlSLQiENhqgc5/FdAj4/UHEzAri42OTSFA5+0agLR03ReTvIms2dfZ7/Ew== - -elliptic@6.3.3: - version "6.3.3" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.3.3.tgz#5482d9646d54bcb89fd7d994fc9e2e9568876e3f" - integrity sha1-VILZZG1UvLif19mU/J4ulWiHbj8= - dependencies: - bn.js "^4.4.0" - brorand "^1.0.1" - hash.js "^1.0.0" - inherits "^2.0.1" - -elliptic@6.5.2, elliptic@^6.0.0, elliptic@^6.4.0, elliptic@^6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" - integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw== - 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" - -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== - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= - -encoding-down@5.0.4, encoding-down@~5.0.0: - version "5.0.4" - resolved "https://registry.yarnpkg.com/encoding-down/-/encoding-down-5.0.4.tgz#1e477da8e9e9d0f7c8293d320044f8b2cd8e9614" - integrity sha512-8CIZLDcSKxgzT+zX8ZVfgNbu8Md2wq/iqa1Y7zyVR18QBEAc0Nmzuvj/N5ykSKpfGzjM8qxbaFntLPwnVoUhZw== - dependencies: - abstract-leveldown "^5.0.0" - inherits "^2.0.3" - level-codec "^9.0.0" - level-errors "^2.0.0" - xtend "^4.0.1" - -encoding@^0.1.11: - version "0.1.12" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" - integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s= - dependencies: - iconv-lite "~0.4.13" - -end-of-stream@^1.0.0, end-of-stream@^1.1.0: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -errno@~0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" - integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== - dependencies: - prr "~1.0.1" - -error-ex@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.5: - version "1.17.5" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.5.tgz#d8c9d1d66c8981fb9200e2251d799eee92774ae9" - integrity sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg== - dependencies: - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.1.5" - is-regex "^1.0.5" - object-inspect "^1.7.0" - object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimleft "^2.1.1" - string.prototype.trimright "^2.1.1" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50: - version "0.10.53" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" - integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q== - dependencies: - es6-iterator "~2.0.3" - es6-symbol "~3.1.3" - next-tick "~1.0.0" - -es6-iterator@^2.0.1, es6-iterator@^2.0.3, es6-iterator@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" - integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= - dependencies: - d "1" - es5-ext "^0.10.35" - es6-symbol "^3.1.1" - -es6-symbol@^3.1.1, es6-symbol@~3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" - integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== - dependencies: - d "^1.0.1" - ext "^1.1.2" - -es6-weak-map@^2.0.1: - version "2.0.3" - resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53" - integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA== - dependencies: - d "1" - es5-ext "^0.10.46" - es6-iterator "^2.0.3" - es6-symbol "^3.1.1" - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= - -escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -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== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= - -eth-block-tracker@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/eth-block-tracker/-/eth-block-tracker-3.0.1.tgz#95cd5e763c7293e0b1b2790a2a39ac2ac188a5e1" - integrity sha512-WUVxWLuhMmsfenfZvFO5sbl1qFY2IqUlw/FPVmjjdElpqLsZtSG+wPe9Dz7W/sB6e80HgFKknOmKk2eNlznHug== - dependencies: - eth-query "^2.1.0" - ethereumjs-tx "^1.3.3" - ethereumjs-util "^5.1.3" - ethjs-util "^0.1.3" - json-rpc-engine "^3.6.0" - pify "^2.3.0" - tape "^4.6.3" - -eth-ens-namehash@2.0.8: - version "2.0.8" - resolved "https://registry.yarnpkg.com/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz#229ac46eca86d52e0c991e7cb2aef83ff0f68bcf" - integrity sha1-IprEbsqG1S4MmR58sq74P/D2i88= - dependencies: - idna-uts46-hx "^2.3.1" - js-sha3 "^0.5.7" - -eth-json-rpc-infura@^3.1.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/eth-json-rpc-infura/-/eth-json-rpc-infura-3.2.1.tgz#26702a821067862b72d979c016fd611502c6057f" - integrity sha512-W7zR4DZvyTn23Bxc0EWsq4XGDdD63+XPUCEhV2zQvQGavDVC4ZpFDK4k99qN7bd7/fjj37+rxmuBOBeIqCA5Mw== - dependencies: - cross-fetch "^2.1.1" - eth-json-rpc-middleware "^1.5.0" - json-rpc-engine "^3.4.0" - json-rpc-error "^2.0.0" - -eth-json-rpc-middleware@^1.5.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.6.0.tgz#5c9d4c28f745ccb01630f0300ba945f4bef9593f" - integrity sha512-tDVCTlrUvdqHKqivYMjtFZsdD7TtpNLBCfKAcOpaVs7orBMS/A8HWro6dIzNtTZIR05FAbJ3bioFOnZpuCew9Q== - dependencies: - async "^2.5.0" - eth-query "^2.1.2" - eth-tx-summary "^3.1.2" - ethereumjs-block "^1.6.0" - ethereumjs-tx "^1.3.3" - ethereumjs-util "^5.1.2" - ethereumjs-vm "^2.1.0" - fetch-ponyfill "^4.0.0" - json-rpc-engine "^3.6.0" - json-rpc-error "^2.0.0" - json-stable-stringify "^1.0.1" - promise-to-callback "^1.0.0" - tape "^4.6.3" - -eth-lib@0.2.7: - version "0.2.7" - resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.2.7.tgz#2f93f17b1e23aec3759cd4a3fe20c1286a3fc1ca" - integrity sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco= - dependencies: - bn.js "^4.11.6" - elliptic "^6.4.0" - xhr-request-promise "^0.1.2" - -eth-lib@^0.1.26: - version "0.1.29" - resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.1.29.tgz#0c11f5060d42da9f931eab6199084734f4dbd1d9" - integrity sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ== - dependencies: - bn.js "^4.11.6" - elliptic "^6.4.0" - nano-json-stream-parser "^0.1.2" - servify "^0.1.12" - ws "^3.0.0" - xhr-request-promise "^0.1.2" - -eth-query@^2.0.2, eth-query@^2.1.0, eth-query@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/eth-query/-/eth-query-2.1.2.tgz#d6741d9000106b51510c72db92d6365456a6da5e" - integrity sha1-1nQdkAAQa1FRDHLbktY2VFam2l4= - dependencies: - json-rpc-random-id "^1.0.0" - xtend "^4.0.1" - -eth-sig-util@2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-2.3.0.tgz#c54a6ac8e8796f7e25f59cf436982a930e645231" - integrity sha512-ugD1AvaggvKaZDgnS19W5qOfepjGc7qHrt7TrAaL54gJw9SHvgIXJ3r2xOMW30RWJZNP+1GlTOy5oye7yXA4xA== - dependencies: - buffer "^5.2.1" - elliptic "^6.4.0" - ethereumjs-abi "0.6.5" - ethereumjs-util "^5.1.1" - tweetnacl "^1.0.0" - tweetnacl-util "^0.15.0" - -eth-sig-util@^1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-1.4.2.tgz#8d958202c7edbaae839707fba6f09ff327606210" - integrity sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA= - dependencies: - ethereumjs-abi "git+https://github.com/ethereumjs/ethereumjs-abi.git" - ethereumjs-util "^5.1.1" - -eth-tx-summary@^3.1.2: - version "3.2.4" - resolved "https://registry.yarnpkg.com/eth-tx-summary/-/eth-tx-summary-3.2.4.tgz#e10eb95eb57cdfe549bf29f97f1e4f1db679035c" - integrity sha512-NtlDnaVZah146Rm8HMRUNMgIwG/ED4jiqk0TME9zFheMl1jOp6jL1m0NKGjJwehXQ6ZKCPr16MTr+qspKpEXNg== - dependencies: - async "^2.1.2" - clone "^2.0.0" - concat-stream "^1.5.1" - end-of-stream "^1.1.0" - eth-query "^2.0.2" - ethereumjs-block "^1.4.1" - ethereumjs-tx "^1.1.1" - ethereumjs-util "^5.0.1" - ethereumjs-vm "^2.6.0" - through2 "^2.0.3" - -ethashjs@~0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/ethashjs/-/ethashjs-0.0.7.tgz#30bfe4196726690a0c59d3b8272e70d4d0c34bae" - integrity sha1-ML/kGWcmaQoMWdO4Jy5w1NDDS64= - dependencies: - async "^1.4.2" - buffer-xor "^1.0.3" - ethereumjs-util "^4.0.1" - miller-rabin "^4.0.0" - -ethereum-bloom-filters@^1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.7.tgz#b7b80735e385dbb7f944ce6b4533e24511306060" - integrity sha512-cDcJJSJ9GMAcURiAWO3DxIEhTL/uWqlQnvgKpuYQzYPrt/izuGU+1ntQmHt0IRq6ADoSYHFnB+aCEFIldjhkMQ== - dependencies: - js-sha3 "^0.8.0" - -ethereum-common@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.2.0.tgz#13bf966131cce1eeade62a1b434249bb4cb120ca" - integrity sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA== - -ethereum-common@^0.0.18: - version "0.0.18" - resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.0.18.tgz#2fdc3576f232903358976eb39da783213ff9523f" - integrity sha1-L9w1dvIykDNYl26znaeDIT/5Uj8= - -ethereum-waffle@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/ethereum-waffle/-/ethereum-waffle-2.4.1.tgz#db13376d5d366a0b3e8813cb64956a4682cbe144" - integrity sha512-52HOubO/V80LDGN+N3FVb6yBq8L5vV2+kP7wjR5AgDoEeQHIrwqumcjJ22tE+FvzR8+eHTh3ItXjQPqJrMp+Mw== - dependencies: - "@ethereum-waffle/chai" "^2.4.1" - "@ethereum-waffle/compiler" "^2.4.1" - "@ethereum-waffle/provider" "^2.4.1" - ethers "^4.0.45" - -ethereumjs-abi@0.6.5: - version "0.6.5" - resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.5.tgz#5a637ef16ab43473fa72a29ad90871405b3f5241" - integrity sha1-WmN+8Wq0NHP6cqKa2QhxQFs/UkE= - dependencies: - bn.js "^4.10.0" - ethereumjs-util "^4.3.0" - -ethereumjs-abi@0.6.7: - version "0.6.7" - resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.7.tgz#d1d1c5cdb8d910a7d97645ba9e93be5d153bba2e" - integrity sha512-EMLOA8ICO5yAaXDhjVEfYjsJIXYutY8ufTE93eEKwsVtp2usQreKwsDTJ9zvam3omYqNuffr8IONIqb2uUslGQ== - dependencies: - bn.js "^4.11.8" - ethereumjs-util "^6.0.0" - -"ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git": - version "0.6.8" - resolved "git+https://github.com/ethereumjs/ethereumjs-abi.git#1cfbb13862f90f0b391d8a699544d5fe4dfb8c7b" - dependencies: - bn.js "^4.11.8" - ethereumjs-util "^6.0.0" - -ethereumjs-account@3.0.0, ethereumjs-account@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ethereumjs-account/-/ethereumjs-account-3.0.0.tgz#728f060c8e0c6e87f1e987f751d3da25422570a9" - integrity sha512-WP6BdscjiiPkQfF9PVfMcwx/rDvfZTjFKY0Uwc09zSQr9JfIVH87dYIJu0gNhBhpmovV4yq295fdllS925fnBA== - dependencies: - ethereumjs-util "^6.0.0" - rlp "^2.2.1" - safe-buffer "^5.1.1" - -ethereumjs-account@^2.0.3: - version "2.0.5" - resolved "https://registry.yarnpkg.com/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz#eeafc62de544cb07b0ee44b10f572c9c49e00a84" - integrity sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA== - dependencies: - ethereumjs-util "^5.0.0" - rlp "^2.0.0" - safe-buffer "^5.1.1" - -ethereumjs-block@2.2.2, ethereumjs-block@^2.2.2, ethereumjs-block@~2.2.0, ethereumjs-block@~2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz#c7654be7e22df489fda206139ecd63e2e9c04965" - integrity sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg== - dependencies: - async "^2.0.1" - ethereumjs-common "^1.5.0" - ethereumjs-tx "^2.1.1" - ethereumjs-util "^5.0.0" - merkle-patricia-tree "^2.1.2" - -ethereumjs-block@^1.2.2, ethereumjs-block@^1.4.1, ethereumjs-block@^1.6.0: - version "1.7.1" - resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz#78b88e6cc56de29a6b4884ee75379b6860333c3f" - integrity sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg== - dependencies: - async "^2.0.1" - ethereum-common "0.2.0" - ethereumjs-tx "^1.2.2" - ethereumjs-util "^5.0.0" - merkle-patricia-tree "^2.1.2" - -ethereumjs-blockchain@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/ethereumjs-blockchain/-/ethereumjs-blockchain-4.0.3.tgz#e013034633a30ad2006728e8e2b21956b267b773" - integrity sha512-0nJWbyA+Gu0ZKZr/cywMtB/77aS/4lOVsIKbgUN2sFQYscXO5rPbUfrEe7G2Zhjp86/a0VqLllemDSTHvx3vZA== - dependencies: - async "^2.6.1" - ethashjs "~0.0.7" - ethereumjs-block "~2.2.2" - ethereumjs-common "^1.5.0" - ethereumjs-util "~6.1.0" - flow-stoplight "^1.0.0" - level-mem "^3.0.1" - lru-cache "^5.1.1" - rlp "^2.2.2" - semaphore "^1.1.0" - -ethereumjs-common@1.5.0, ethereumjs-common@^1.1.0, ethereumjs-common@^1.3.2, ethereumjs-common@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/ethereumjs-common/-/ethereumjs-common-1.5.0.tgz#d3e82fc7c47c0cef95047f431a99485abc9bb1cd" - integrity sha512-SZOjgK1356hIY7MRj3/ma5qtfr/4B5BL+G4rP/XSMYr2z1H5el4RX5GReYCKmQmYI/nSBmRnwrZ17IfHuG0viQ== - -ethereumjs-tx@2.1.2, ethereumjs-tx@^2.1.1, ethereumjs-tx@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz#5dfe7688bf177b45c9a23f86cf9104d47ea35fed" - integrity sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw== - dependencies: - ethereumjs-common "^1.5.0" - ethereumjs-util "^6.0.0" - -ethereumjs-tx@^1.1.1, ethereumjs-tx@^1.2.0, ethereumjs-tx@^1.2.2, ethereumjs-tx@^1.3.3: - version "1.3.7" - resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz#88323a2d875b10549b8347e09f4862b546f3d89a" - integrity sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA== - dependencies: - ethereum-common "^0.0.18" - ethereumjs-util "^5.0.0" - -ethereumjs-util@6.2.0, ethereumjs-util@^6.0.0, ethereumjs-util@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.0.tgz#23ec79b2488a7d041242f01e25f24e5ad0357960" - integrity sha512-vb0XN9J2QGdZGIEKG2vXM+kUdEivUfU6Wmi5y0cg+LRhDYKnXIZ/Lz7XjFbHRR9VIKq2lVGLzGBkA++y2nOdOQ== - 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" - -ethereumjs-util@^4.0.1, ethereumjs-util@^4.3.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz#3e9428b317eebda3d7260d854fddda954b1f1bc6" - integrity sha1-PpQosxfuvaPXJg2FT93alUsfG8Y= - dependencies: - bn.js "^4.8.0" - create-hash "^1.1.2" - keccakjs "^0.2.0" - rlp "^2.0.0" - secp256k1 "^3.0.1" - -ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.2, ethereumjs-util@^5.1.3, ethereumjs-util@^5.1.5: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz#3e0c0d1741471acf1036052d048623dee54ad642" - integrity sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA== - dependencies: - bn.js "^4.11.0" - create-hash "^1.1.2" - ethjs-util "^0.1.3" - keccak "^1.0.2" - rlp "^2.0.0" - safe-buffer "^5.1.1" - secp256k1 "^3.0.1" - -ethereumjs-util@~6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.1.0.tgz#e9c51e5549e8ebd757a339cc00f5380507e799c8" - integrity sha512-URESKMFbDeJxnAxPppnk2fN6Y3BIatn9fwn76Lm8bQlt+s52TpG8dN9M66MLPuRAiAOIqL3dfwqWJf0sd0fL0Q== - dependencies: - bn.js "^4.11.0" - create-hash "^1.1.2" - ethjs-util "0.1.6" - keccak "^1.0.2" - rlp "^2.0.0" - safe-buffer "^5.1.1" - secp256k1 "^3.0.1" - -ethereumjs-vm@4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-4.1.3.tgz#dc8eb45f47d775da9f0b2437d5e20896fdf66f37" - integrity sha512-RTrD0y7My4O6Qr1P2ZIsMfD6RzL6kU/RhBZ0a5XrPzAeR61crBS7or66ohDrvxDI/rDBxMi+6SnsELih6fzalw== - dependencies: - async "^2.1.2" - async-eventemitter "^0.2.2" - core-js-pure "^3.0.1" - ethereumjs-account "^3.0.0" - ethereumjs-block "^2.2.2" - ethereumjs-blockchain "^4.0.3" - ethereumjs-common "^1.5.0" - ethereumjs-tx "^2.1.2" - ethereumjs-util "^6.2.0" - fake-merkle-patricia-tree "^1.0.1" - functional-red-black-tree "^1.0.1" - merkle-patricia-tree "^2.3.2" - rustbn.js "~0.2.0" - safe-buffer "^5.1.1" - util.promisify "^1.0.0" - -ethereumjs-vm@^2.1.0, ethereumjs-vm@^2.3.4, ethereumjs-vm@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz#76243ed8de031b408793ac33907fb3407fe400c6" - integrity sha512-r/XIUik/ynGbxS3y+mvGnbOKnuLo40V5Mj1J25+HEO63aWYREIqvWeRO/hnROlMBE5WoniQmPmhiaN0ctiHaXw== - dependencies: - async "^2.1.2" - async-eventemitter "^0.2.2" - ethereumjs-account "^2.0.3" - ethereumjs-block "~2.2.0" - ethereumjs-common "^1.1.0" - ethereumjs-util "^6.0.0" - fake-merkle-patricia-tree "^1.0.1" - functional-red-black-tree "^1.0.1" - merkle-patricia-tree "^2.3.2" - rustbn.js "~0.2.0" - safe-buffer "^5.1.1" - -ethereumjs-wallet@0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/ethereumjs-wallet/-/ethereumjs-wallet-0.6.3.tgz#b0eae6f327637c2aeb9ccb9047b982ac542e6ab1" - integrity sha512-qiXPiZOsStem+Dj/CQHbn5qex+FVkuPmGH7SvSnA9F3tdRDt8dLMyvIj3+U05QzVZNPYh4HXEdnzoYI4dZkr9w== - dependencies: - aes-js "^3.1.1" - bs58check "^2.1.2" - ethereumjs-util "^6.0.0" - hdkey "^1.1.0" - randombytes "^2.0.6" - safe-buffer "^5.1.2" - scrypt.js "^0.3.0" - utf8 "^3.0.0" - uuid "^3.3.2" - -ethers@4.0.0-beta.3: - version "4.0.0-beta.3" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.0-beta.3.tgz#15bef14e57e94ecbeb7f9b39dd0a4bd435bc9066" - integrity sha512-YYPogooSknTwvHg3+Mv71gM/3Wcrx+ZpCzarBj3mqs9njjRkrOo2/eufzhHloOCo3JSoNI4TQJJ6yU5ABm3Uog== - dependencies: - "@types/node" "^10.3.2" - aes-js "3.0.0" - bn.js "^4.4.0" - elliptic "6.3.3" - hash.js "1.1.3" - js-sha3 "0.5.7" - scrypt-js "2.0.3" - setimmediate "1.0.4" - uuid "2.0.1" - xmlhttprequest "1.8.0" - -ethers@^4.0.45: - version "4.0.46" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.46.tgz#13cd3ed099487f43ece00194b89a8a8781f71507" - integrity sha512-/dPMzzpInhtiip4hKFvsDiJKeRk64IhyA+Po7CtNXneQFSOCYXg8eBFt+jXbxUQyApgWnWOtYxWdfn9+CvvxDA== - dependencies: - aes-js "3.0.0" - bn.js "^4.4.0" - elliptic "6.5.2" - 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" - -ethjs-unit@0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" - integrity sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk= - dependencies: - bn.js "4.11.6" - number-to-bn "1.7.0" - -ethjs-util@0.1.6, ethjs-util@^0.1.3: - 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@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" - integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== - -events@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59" - integrity sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg== - -evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" - integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== - dependencies: - md5.js "^1.3.4" - safe-buffer "^5.1.1" - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= - 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" - -expand-tilde@^2.0.0, expand-tilde@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" - integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= - dependencies: - homedir-polyfill "^1.0.1" - -express@^4.14.0: - version "4.17.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" - integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== - 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" - -ext@^1.1.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244" - integrity sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A== - dependencies: - type "^2.0.0" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extend@^3.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== - -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - -fake-merkle-patricia-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz#4b8c3acfb520afadf9860b1f14cd8ce3402cddd3" - integrity sha1-S4w6z7Ugr635hgsfFM2M40As3dM= - dependencies: - checkpoint-store "^1.1.0" - -fancy-log@^1.3.2: - version "1.3.3" - resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.3.tgz#dbc19154f558690150a23953a0adbd035be45fc7" - integrity sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw== - dependencies: - ansi-gray "^0.1.1" - color-support "^1.1.3" - parse-node-version "^1.0.0" - time-stamp "^1.0.0" - -fast-deep-equal@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" - integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== - -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== - -fd-slicer@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" - integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4= - dependencies: - pend "~1.2.0" - -fetch-ponyfill@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz#ae3ce5f732c645eab87e4ae8793414709b239893" - integrity sha1-rjzl9zLGReq4fkroeTQUcJsjmJM= - dependencies: - node-fetch "~1.7.1" - -file-type@^3.8.0: - version "3.9.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" - integrity sha1-JXoHg4TR24CHvESdEH1SpSZyuek= - -file-type@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6" - integrity sha1-LdvqfHP/42No365J3DOMBYwritY= - -file-type@^6.1.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" - integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg== - -file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" - integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== - -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - -finalhandler@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" - integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== - 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" - -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@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - -findup-sync@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc" - integrity sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw= - dependencies: - detect-file "^1.0.0" - is-glob "^3.1.0" - micromatch "^3.0.4" - resolve-dir "^1.0.1" - -findup-sync@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1" - integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg== - dependencies: - detect-file "^1.0.0" - is-glob "^4.0.0" - micromatch "^3.0.4" - resolve-dir "^1.0.1" - -fined@^1.0.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/fined/-/fined-1.2.0.tgz#d00beccf1aa2b475d16d423b0238b713a2c4a37b" - integrity sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng== - dependencies: - expand-tilde "^2.0.2" - is-plain-object "^2.0.3" - object.defaults "^1.1.0" - object.pick "^1.2.0" - parse-filepath "^1.0.1" - -flagged-respawn@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-1.0.1.tgz#e7de6f1279ddd9ca9aac8a5971d618606b3aab41" - integrity sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q== - -flat@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/flat/-/flat-4.1.0.tgz#090bec8b05e39cba309747f1d588f04dbaf98db2" - integrity sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw== - dependencies: - is-buffer "~2.0.3" - -flow-stoplight@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/flow-stoplight/-/flow-stoplight-1.0.0.tgz#4a292c5bcff8b39fa6cc0cb1a853d86f27eeff7b" - integrity sha1-SiksW8/4s5+mzAyxqFPYbyfu/3s= - -flush-write-stream@^1.0.2: - version "1.1.1" - resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" - integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== - dependencies: - inherits "^2.0.3" - readable-stream "^2.3.6" - -for-each@~0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" - integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== - dependencies: - is-callable "^1.1.3" - -for-in@^1.0.1, for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= - -for-own@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b" - integrity sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs= - dependencies: - for-in "^1.0.1" - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - -form-data@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682" - integrity sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -forwarded@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" - integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= - -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= - dependencies: - map-cache "^0.2.2" - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= - -fs-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== - -fs-extra@^0.30.0: - version "0.30.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" - integrity sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A= - dependencies: - graceful-fs "^4.1.2" - jsonfile "^2.1.0" - klaw "^1.0.0" - path-is-absolute "^1.0.0" - rimraf "^2.2.8" - -fs-extra@^4.0.2: - version "4.0.3" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" - integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-minipass@^1.2.5: - version "1.2.7" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" - integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== - dependencies: - minipass "^2.6.0" - -fs-mkdirp-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz#0b7815fc3201c6a69e14db98ce098c16935259eb" - integrity sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes= - dependencies: - graceful-fs "^4.1.11" - through2 "^2.0.3" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@^1.2.7: - version "1.2.12" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.12.tgz#db7e0d8ec3b0b45724fd4d83d43554a8f1f0de5c" - integrity sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q== - dependencies: - bindings "^1.5.0" - nan "^2.12.1" - -function-bind@^1.1.1, 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== - -functional-red-black-tree@^1.0.1, functional-red-black-tree@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - -ganache-core@^2.10.2: - version "2.10.2" - resolved "https://registry.yarnpkg.com/ganache-core/-/ganache-core-2.10.2.tgz#17c171c6c0195b6734a0dd741a9d2afd4f74e292" - integrity sha512-4XEO0VsqQ1+OW7Za5fQs9/Kk7o8M0T1sRfFSF8h9NeJ2ABaqMO5waqxf567ZMcSkRKaTjUucBSz83xNfZv1HDg== - 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 "2.3.0" - ethereumjs-abi "0.6.7" - ethereumjs-account "3.0.0" - ethereumjs-block "2.2.2" - ethereumjs-common "1.5.0" - ethereumjs-tx "2.1.2" - ethereumjs-util "6.2.0" - ethereumjs-vm "4.1.3" - heap "0.2.6" - level-sublevel "6.6.4" - levelup "3.1.1" - lodash "4.17.14" - merkle-patricia-tree "2.3.2" - seedrandom "3.0.1" - source-map-support "0.5.12" - tmp "0.1.0" - web3-provider-engine "14.2.1" - websocket "1.0.29" - optionalDependencies: - ethereumjs-wallet "0.6.3" - web3 "1.2.4" - -get-caller-file@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" - integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== - -get-caller-file@^2.0.1: - 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 sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= - -get-stream@^2.2.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" - integrity sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4= - dependencies: - object-assign "^4.0.1" - pinkie-promise "^2.0.0" - -get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= - -get-stream@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - -get-stream@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9" - integrity sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw== - dependencies: - pump "^3.0.0" - -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - -glob-stream@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-6.1.0.tgz#7045c99413b3eb94888d83ab46d0b404cc7bdde4" - integrity sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ= - dependencies: - extend "^3.0.0" - glob "^7.1.1" - glob-parent "^3.1.0" - is-negated-glob "^1.0.0" - ordered-read-streams "^1.0.0" - pumpify "^1.3.5" - readable-stream "^2.1.5" - remove-trailing-separator "^1.0.1" - to-absolute-glob "^2.0.0" - unique-stream "^2.0.2" - -glob-watcher@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-5.0.3.tgz#88a8abf1c4d131eb93928994bc4a593c2e5dd626" - integrity sha512-8tWsULNEPHKQ2MR4zXuzSmqbdyV5PtwwCaWSGQ1WwHsJ07ilNeN1JB8ntxhckbnpSHaf9dXFUHzIWvm1I13dsg== - dependencies: - anymatch "^2.0.0" - async-done "^1.2.0" - chokidar "^2.0.0" - is-negated-glob "^1.0.0" - just-debounce "^1.0.0" - object.defaults "^1.1.0" - -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.1, glob@^7.1.3, glob@~7.1.6: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - 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" - -global-modules@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" - integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== - dependencies: - global-prefix "^1.0.1" - is-windows "^1.0.1" - resolve-dir "^1.0.0" - -global-prefix@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" - integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= - dependencies: - expand-tilde "^2.0.2" - homedir-polyfill "^1.0.1" - ini "^1.3.4" - is-windows "^1.0.1" - which "^1.2.14" - -global@~4.3.0: - version "4.3.2" - resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" - integrity sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8= - dependencies: - min-document "^2.19.0" - process "~0.5.1" - -globals@^9.18.0: - version "9.18.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" - integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== - -glogg@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.2.tgz#2d7dd702beda22eb3bffadf880696da6d846313f" - integrity sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA== - dependencies: - sparkles "^1.0.0" - -got@9.6.0: - version "9.6.0" - resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" - integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== - dependencies: - "@sindresorhus/is" "^0.14.0" - "@szmarczak/http-timer" "^1.1.2" - cacheable-request "^6.0.0" - decompress-response "^3.3.0" - duplexer3 "^0.1.4" - get-stream "^4.1.0" - lowercase-keys "^1.0.1" - mimic-response "^1.0.1" - p-cancelable "^1.0.0" - to-readable-stream "^1.0.0" - url-parse-lax "^3.0.0" - -got@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" - integrity sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw== - 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" - -graceful-fs@^4.0.0, graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9: - version "4.2.3" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" - integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== - -"graceful-readlink@>= 1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" - integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= - -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== - -gulp-cli@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/gulp-cli/-/gulp-cli-2.2.0.tgz#5533126eeb7fe415a7e3e84a297d334d5cf70ebc" - integrity sha512-rGs3bVYHdyJpLqR0TUBnlcZ1O5O++Zs4bA0ajm+zr3WFCfiSLjGwoCBqFs18wzN+ZxahT9DkOK5nDf26iDsWjA== - dependencies: - ansi-colors "^1.0.1" - archy "^1.0.0" - array-sort "^1.0.0" - color-support "^1.1.3" - concat-stream "^1.6.0" - copy-props "^2.0.1" - fancy-log "^1.3.2" - gulplog "^1.0.0" - interpret "^1.1.0" - isobject "^3.0.1" - liftoff "^3.1.0" - matchdep "^2.0.0" - mute-stdout "^1.0.0" - pretty-hrtime "^1.0.0" - replace-homedir "^1.0.0" - semver-greatest-satisfied-range "^1.1.0" - v8flags "^3.0.1" - yargs "^7.1.0" - -gulp@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/gulp/-/gulp-4.0.2.tgz#543651070fd0f6ab0a0650c6a3e6ff5a7cb09caa" - integrity sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA== - dependencies: - glob-watcher "^5.0.3" - gulp-cli "^2.2.0" - undertaker "^1.2.1" - vinyl-fs "^3.0.0" - -gulplog@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5" - integrity sha1-4oxNRdBey77YGDY86PnFkmIp/+U= - dependencies: - glogg "^1.0.0" - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" - integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== - dependencies: - ajv "^6.5.5" - har-schema "^2.0.0" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= - dependencies: - ansi-regex "^2.0.0" - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-symbol-support-x@^1.4.1: - version "1.4.2" - resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" - integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== - -has-symbols@^1.0.0, has-symbols@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" - integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== - -has-to-string-tag-x@^1.2.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" - integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw== - dependencies: - has-symbol-support-x "^1.4.1" - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -has@^1.0.3, has@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hash-base@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" - integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -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.0.0, hash.js@^1.0.3: - 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" - -hdkey@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/hdkey/-/hdkey-1.1.1.tgz#c2b3bfd5883ff9529b72f2f08b28be0972a9f64a" - integrity sha512-DvHZ5OuavsfWs5yfVJZestsnc3wzPvLWNk6c2nRUfo6X+OtxypGt20vDDf7Ba+MJzjL3KS1og2nw2eBbLCOUTA== - dependencies: - coinstring "^2.0.0" - safe-buffer "^5.1.1" - secp256k1 "^3.0.1" - -he@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -heap@0.2.6: - version "0.2.6" - resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.6.tgz#087e1f10b046932fc8594dd9e6d378afc9d1e5ac" - integrity sha1-CH4fELBGky/IWU3Z5tN4r8nR5aw= - -hmac-drbg@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - -home-or-tmp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" - integrity sha1-42w/LSyufXRqhX440Y1fMqeILbg= - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.1" - -homedir-polyfill@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" - integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== - dependencies: - parse-passwd "^1.0.0" - -hosted-git-info@^2.1.4, hosted-git-info@^2.6.0: - version "2.8.8" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" - integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== - -http-cache-semantics@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" - integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== - -http-errors@1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" - integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -http-errors@~1.7.2: - version "1.7.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" - integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -http-https@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/http-https/-/http-https-1.0.0.tgz#2f908dd5f1db4068c058cd6e6d4ce392c913389b" - integrity sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs= - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -iconv-lite@0.4.24, iconv-lite@~0.4.13: - 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" - -idna-uts46-hx@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz#a1dc5c4df37eee522bf66d969cc980e00e8711f9" - integrity sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA== - dependencies: - punycode "2.1.0" - -ieee754@^1.1.4: - version "1.1.13" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" - integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== - -immediate@^3.2.3, immediate@~3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c" - integrity sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw= - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - -ini@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== - -interpret@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" - integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== - -invariant@^2.2.2: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== - dependencies: - loose-envify "^1.0.0" - -invert-kv@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" - integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= - -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - -is-absolute@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" - integrity sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA== - dependencies: - is-relative "^1.0.0" - is-windows "^1.0.1" - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== - dependencies: - kind-of "^6.0.0" - -is-arguments@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" - integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-binary-path@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= - dependencies: - binary-extensions "^1.0.0" - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - -is-buffer@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" - integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== - -is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" - integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== - -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== - dependencies: - kind-of "^6.0.0" - -is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== - -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^2.1.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 sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-finite@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" - integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== - -is-fn@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fn/-/is-fn-1.0.0.tgz#9543d5de7bcf5b08a22ec8a20bae6e286d510d8c" - integrity sha1-lUPV3nvPWwiiLsiiC65uKG1RDYw= - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-function@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5" - integrity sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU= - -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= - dependencies: - is-extglob "^2.1.0" - -is-glob@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== - dependencies: - is-extglob "^2.1.1" - -is-hex-prefixed@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554" - integrity sha1-fY035q135dEnFIkTxXPggtd39VQ= - -is-natural-number@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" - integrity sha1-q5124dtM7VHjXeDHLr7PCfc0zeg= - -is-negated-glob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2" - integrity sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI= - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= - dependencies: - kind-of "^3.0.2" - -is-number@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" - integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== - -is-object@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" - integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA= - -is-plain-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= - -is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-regex@^1.0.4, is-regex@^1.0.5, is-regex@~1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" - integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== - dependencies: - has "^1.0.3" - -is-relative@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" - integrity sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA== - dependencies: - is-unc-path "^1.0.0" - -is-retry-allowed@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" - integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== - -is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - -is-symbol@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" - integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== - dependencies: - has-symbols "^1.0.1" - -is-typedarray@^1.0.0, is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -is-unc-path@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d" - integrity sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ== - dependencies: - unc-path-regex "^0.1.2" - -is-url@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" - integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww== - -is-utf8@^0.2.0, is-utf8@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= - -is-valid-glob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-1.0.0.tgz#29bf3eff701be2d4d315dbacc39bc39fe8f601aa" - integrity sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao= - -is-windows@^1.0.1, is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= - -isarray@1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - -isurl@^1.0.0-alpha5: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" - integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w== - dependencies: - has-to-string-tag-x "^1.2.0" - is-object "^1.0.1" - -js-sha3@0.5.7, js-sha3@^0.5.7: - version "0.5.7" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" - integrity sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc= - -js-sha3@0.8.0, js-sha3@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" - integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== - -js-sha3@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.6.1.tgz#5b89f77a7477679877f58c4a075240934b1f95c0" - integrity sha1-W4n3enR3Z5h39YxKB1JAk0sflcA= - -"js-tokens@^3.0.0 || ^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-tokens@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" - integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= - -js-yaml@3.13.1: - version "3.13.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" - integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -jsesc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" - integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s= - -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= - -json-buffer@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" - integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= - -json-rpc-engine@^3.4.0, json-rpc-engine@^3.6.0: - version "3.8.0" - resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-3.8.0.tgz#9d4ff447241792e1d0a232f6ef927302bb0c62a9" - integrity sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA== - dependencies: - async "^2.0.1" - babel-preset-env "^1.7.0" - babelify "^7.3.0" - json-rpc-error "^2.0.0" - promise-to-callback "^1.0.0" - safe-event-emitter "^1.0.1" - -json-rpc-error@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/json-rpc-error/-/json-rpc-error-2.0.0.tgz#a7af9c202838b5e905c7250e547f1aff77258a02" - integrity sha1-p6+cICg4tekFxyUOVH8a/3cligI= - dependencies: - inherits "^2.0.1" - -json-rpc-random-id@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz#ba49d96aded1444dbb8da3d203748acbbcdec8c8" - integrity sha1-uknZat7RRE27jaPSA3SKy7zeyMg= - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= - -json-stable-stringify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= - dependencies: - jsonify "~0.0.0" - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - -json5@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" - integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= - -jsonfile@^2.1.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" - integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug= - 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 sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= - optionalDependencies: - graceful-fs "^4.1.6" - -jsonify@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -just-debounce@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/just-debounce/-/just-debounce-1.0.0.tgz#87fccfaeffc0b68cd19d55f6722943f929ea35ea" - integrity sha1-h/zPrv/AtozRnVX2cilD+SnqNeo= - -keccak@^1.0.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/keccak/-/keccak-1.4.0.tgz#572f8a6dbee8e7b3aa421550f9e6408ca2186f80" - integrity sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw== - dependencies: - bindings "^1.2.1" - inherits "^2.0.3" - nan "^2.2.1" - safe-buffer "^5.1.0" - -keccak@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/keccak/-/keccak-2.1.0.tgz#734ea53f2edcfd0f42cdb8d5f4c358fef052752b" - integrity sha512-m1wbJRTo+gWbctZWay9i26v5fFnYkOn7D5PCxJ3fZUGUEb49dE1Pm4BREUYCt/aoO6di7jeoGmhvqN9Nzylm3Q== - dependencies: - bindings "^1.5.0" - inherits "^2.0.4" - nan "^2.14.0" - safe-buffer "^5.2.0" - -keccakjs@^0.2.0: - version "0.2.3" - resolved "https://registry.yarnpkg.com/keccakjs/-/keccakjs-0.2.3.tgz#5e4e969ce39689a3861f445d7752ee3477f9fe72" - integrity sha512-BjLkNDcfaZ6l8HBG9tH0tpmDv3sS2mA7FNQxFHpCdzP3Gb2MVruXBSuoM66SnVxKJpAr5dKGdkHD+bDokt8fTg== - dependencies: - browserify-sha3 "^0.0.4" - sha3 "^1.2.2" - -keyv@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" - integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== - dependencies: - json-buffer "3.0.0" - -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0, kind-of@^5.0.2: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== - -kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -klaw@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" - integrity sha1-QIhDO0azsbolnXh4XY6W9zugJDk= - optionalDependencies: - graceful-fs "^4.1.9" - -last-run@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/last-run/-/last-run-1.1.1.tgz#45b96942c17b1c79c772198259ba943bebf8ca5b" - integrity sha1-RblpQsF7HHnHchmCWbqUO+v4yls= - dependencies: - default-resolution "^2.0.0" - es6-weak-map "^2.0.1" - -lazystream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" - integrity sha1-9plf4PggOS9hOWvolGJAe7dxaOQ= - dependencies: - readable-stream "^2.0.5" - -lcid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= - dependencies: - invert-kv "^1.0.0" - -lead@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lead/-/lead-1.0.0.tgz#6f14f99a37be3a9dd784f5495690e5903466ee42" - integrity sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI= - dependencies: - flush-write-stream "^1.0.2" - -level-codec@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-9.0.1.tgz#042f4aa85e56d4328ace368c950811ba802b7247" - integrity sha512-ajFP0kJ+nyq4i6kptSM+mAvJKLOg1X5FiFPtLG9M5gCEZyBmgDi3FkDrvlMkEzrUn1cWxtvVmrvoS4ASyO/q+Q== - -level-codec@~7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-7.0.1.tgz#341f22f907ce0f16763f24bddd681e395a0fb8a7" - integrity sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ== - -level-errors@^1.0.3: - version "1.1.2" - resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.1.2.tgz#4399c2f3d3ab87d0625f7e3676e2d807deff404d" - integrity sha512-Sw/IJwWbPKF5Ai4Wz60B52yj0zYeqzObLh8k1Tk88jVmD51cJSKWSYpRyhVIvFzZdvsPqlH5wfhp/yxdsaQH4w== - dependencies: - errno "~0.1.1" - -level-errors@^2.0.0, level-errors@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-2.0.1.tgz#2132a677bf4e679ce029f517c2f17432800c05c8" - integrity sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw== - dependencies: - errno "~0.1.1" - -level-errors@~1.0.3: - version "1.0.5" - resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.0.5.tgz#83dbfb12f0b8a2516bdc9a31c4876038e227b859" - integrity sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig== - dependencies: - errno "~0.1.1" - -level-iterator-stream@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-2.0.3.tgz#ccfff7c046dcf47955ae9a86f46dfa06a31688b4" - integrity sha512-I6Heg70nfF+e5Y3/qfthJFexhRw/Gi3bIymCoXAlijZdAcLaPuWSJs3KXyTYf23ID6g0o2QF62Yh+grOXY3Rig== - dependencies: - inherits "^2.0.1" - readable-stream "^2.0.5" - xtend "^4.0.0" - -level-iterator-stream@~1.3.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz#e43b78b1a8143e6fa97a4f485eb8ea530352f2ed" - integrity sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0= - dependencies: - inherits "^2.0.1" - level-errors "^1.0.3" - readable-stream "^1.0.33" - xtend "^4.0.0" - -level-iterator-stream@~3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-3.0.1.tgz#2c98a4f8820d87cdacab3132506815419077c730" - integrity sha512-nEIQvxEED9yRThxvOrq8Aqziy4EGzrxSZK+QzEFAVuJvQ8glfyZ96GB6BoI4sBbLfjMXm2w4vu3Tkcm9obcY0g== - dependencies: - inherits "^2.0.1" - readable-stream "^2.3.6" - xtend "^4.0.0" - -level-mem@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/level-mem/-/level-mem-3.0.1.tgz#7ce8cf256eac40f716eb6489654726247f5a89e5" - integrity sha512-LbtfK9+3Ug1UmvvhR2DqLqXiPW1OJ5jEh0a3m9ZgAipiwpSxGj/qaVVy54RG5vAQN1nCuXqjvprCuKSCxcJHBg== - dependencies: - level-packager "~4.0.0" - memdown "~3.0.0" - -level-packager@~4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/level-packager/-/level-packager-4.0.1.tgz#7e7d3016af005be0869bc5fa8de93d2a7f56ffe6" - integrity sha512-svCRKfYLn9/4CoFfi+d8krOtrp6RoX8+xm0Na5cgXMqSyRru0AnDYdLl+YI8u1FyS6gGZ94ILLZDE5dh2but3Q== - dependencies: - encoding-down "~5.0.0" - levelup "^3.0.0" - -level-post@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/level-post/-/level-post-1.0.7.tgz#19ccca9441a7cc527879a0635000f06d5e8f27d0" - integrity sha512-PWYqG4Q00asOrLhX7BejSajByB4EmG2GaKHfj3h5UmmZ2duciXLPGYWIjBzLECFWUGOZWlm5B20h/n3Gs3HKew== - dependencies: - ltgt "^2.1.2" - -level-sublevel@6.6.4: - version "6.6.4" - resolved "https://registry.yarnpkg.com/level-sublevel/-/level-sublevel-6.6.4.tgz#f7844ae893919cd9d69ae19d7159499afd5352ba" - integrity sha512-pcCrTUOiO48+Kp6F1+UAzF/OtWqLcQVTVF39HLdZ3RO8XBoXt+XVPKZO1vVr1aUoxHZA9OtD2e1v7G+3S5KFDA== - dependencies: - bytewise "~1.1.0" - level-codec "^9.0.0" - level-errors "^2.0.0" - level-iterator-stream "^2.0.3" - ltgt "~2.1.1" - pull-defer "^0.2.2" - pull-level "^2.0.3" - pull-stream "^3.6.8" - typewiselite "~1.0.0" - xtend "~4.0.0" - -level-ws@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-0.0.0.tgz#372e512177924a00424b0b43aef2bb42496d228b" - integrity sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos= - dependencies: - readable-stream "~1.0.15" - xtend "~2.1.1" - -levelup@3.1.1, levelup@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/levelup/-/levelup-3.1.1.tgz#c2c0b3be2b4dc316647c53b42e2f559e232d2189" - integrity sha512-9N10xRkUU4dShSRRFTBdNaBxofz+PGaIZO962ckboJZiNmLuhVT6FZ6ZKAsICKfUBO76ySaYU6fJWX/jnj3Lcg== - dependencies: - deferred-leveldown "~4.0.0" - level-errors "~2.0.0" - level-iterator-stream "~3.0.0" - xtend "~4.0.0" - -levelup@^1.2.1: - version "1.3.9" - resolved "https://registry.yarnpkg.com/levelup/-/levelup-1.3.9.tgz#2dbcae845b2bb2b6bea84df334c475533bbd82ab" - integrity sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ== - dependencies: - deferred-leveldown "~1.2.1" - level-codec "~7.0.0" - level-errors "~1.0.3" - level-iterator-stream "~1.3.0" - prr "~1.0.1" - semver "~5.4.1" - xtend "~4.0.0" - -liftoff@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-3.1.0.tgz#c9ba6081f908670607ee79062d700df062c52ed3" - integrity sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog== - dependencies: - extend "^3.0.0" - findup-sync "^3.0.0" - fined "^1.0.1" - flagged-respawn "^1.0.0" - is-plain-object "^2.0.4" - object.map "^1.0.0" - rechoir "^0.6.2" - resolve "^1.1.7" - -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - -locate-path@^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" - -lodash@4.17.14: - version "4.17.14" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba" - integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw== - -lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4: - version "4.17.15" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" - integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== - -log-symbols@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" - integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== - dependencies: - chalk "^2.0.1" - -looper@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/looper/-/looper-2.0.0.tgz#66cd0c774af3d4fedac53794f742db56da8f09ec" - integrity sha1-Zs0Md0rz1P7axTeU90LbVtqPCew= - -looper@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/looper/-/looper-3.0.0.tgz#2efa54c3b1cbaba9b94aee2e5914b0be57fbb749" - integrity sha1-LvpUw7HLq6m5Su4uWRSwvlf7t0k= - -loose-envify@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" - integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== - -lowercase-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" - integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== - -lru-cache@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-3.2.0.tgz#71789b3b7f5399bec8565dda38aa30d2a097efee" - integrity sha1-cXibO39Tmb7IVl3aOKow0qCX7+4= - dependencies: - pseudomap "^1.0.1" - -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - -ltgt@^2.1.2, ltgt@~2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5" - integrity sha1-81ypHEk/e3PaDgdJUwTxezH4fuU= - -ltgt@~2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.1.3.tgz#10851a06d9964b971178441c23c9e52698eece34" - integrity sha1-EIUaBtmWS5cReEQcI8nlJpjuzjQ= - -make-dir@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" - integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== - dependencies: - pify "^3.0.0" - -make-error@^1.1.1: - version "1.3.5" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8" - integrity sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g== - -make-iterator@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/make-iterator/-/make-iterator-1.0.1.tgz#29b33f312aa8f547c4a5e490f56afcec99133ad6" - integrity sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw== - dependencies: - kind-of "^6.0.2" - -map-cache@^0.2.0, map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= - -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= - dependencies: - object-visit "^1.0.0" - -matchdep@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/matchdep/-/matchdep-2.0.0.tgz#c6f34834a0d8dbc3b37c27ee8bbcb27c7775582e" - integrity sha1-xvNINKDY28OzfCfui7yyfHd1WC4= - dependencies: - findup-sync "^2.0.0" - micromatch "^3.0.4" - resolve "^1.4.0" - stack-trace "0.0.10" - -md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= - -memdown@^1.0.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/memdown/-/memdown-1.4.1.tgz#b4e4e192174664ffbae41361aa500f3119efe215" - integrity sha1-tOThkhdGZP+65BNhqlAPMRnv4hU= - dependencies: - abstract-leveldown "~2.7.1" - functional-red-black-tree "^1.0.1" - immediate "^3.2.3" - inherits "~2.0.1" - ltgt "~2.2.0" - safe-buffer "~5.1.1" - -memdown@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/memdown/-/memdown-3.0.0.tgz#93aca055d743b20efc37492e9e399784f2958309" - integrity sha512-tbV02LfZMWLcHcq4tw++NuqMO+FZX8tNJEiD2aNRm48ZZusVg5N8NART+dmBkepJVye986oixErf7jfXboMGMA== - dependencies: - abstract-leveldown "~5.0.0" - functional-red-black-tree "~1.0.1" - immediate "~3.2.3" - inherits "~2.0.1" - ltgt "~2.2.0" - safe-buffer "~5.1.1" - -memorystream@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" - integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI= - -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= - -merkle-patricia-tree@2.3.2, merkle-patricia-tree@^2.1.2, merkle-patricia-tree@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz#982ca1b5a0fde00eed2f6aeed1f9152860b8208a" - integrity sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g== - dependencies: - async "^1.4.2" - ethereumjs-util "^5.0.0" - level-ws "0.0.0" - levelup "^1.2.1" - memdown "^1.0.0" - readable-stream "^2.0.0" - rlp "^2.0.0" - semaphore ">=1.0.1" - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= - -micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - -miller-rabin@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" - integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== - dependencies: - bn.js "^4.0.0" - brorand "^1.0.1" - -mime-db@1.43.0: - version "1.43.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" - integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== - -mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.19, mime-types@~2.1.24: - version "2.1.26" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" - integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== - dependencies: - mime-db "1.43.0" - -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -mimic-response@^1.0.0, mimic-response@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" - integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== - -min-document@^2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" - integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= - dependencies: - dom-walk "^0.1.0" - -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= - -minimatch@3.0.4, 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" - -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - -minimist@^1.2.5, minimist@~1.2.0: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - -minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" - integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - -minizlib@^1.2.1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" - integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== - dependencies: - minipass "^2.9.0" - -mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" - integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - -mkdirp-promise@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz#e9b8f68e552c68a9c1713b84883f7a1dd039b8a1" - integrity sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE= - dependencies: - mkdirp "*" - -mkdirp@*: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - -mkdirp@0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= - dependencies: - minimist "0.0.8" - -mkdirp@^0.5.0, mkdirp@^0.5.1: - 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" - -mocha@^6.2.2: - version "6.2.2" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-6.2.2.tgz#5d8987e28940caf8957a7d7664b910dc5b2fea20" - integrity sha512-FgDS9Re79yU1xz5d+C4rv1G7QagNGHZ+iXF81hO8zY35YZZcLEsJVfFolfsqKFWunATEvNzMK0r/CwWd/szO9A== - dependencies: - ansi-colors "3.2.3" - browser-stdout "1.3.1" - 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 "2.2.0" - minimatch "3.0.4" - mkdirp "0.5.1" - ms "2.1.1" - node-environment-flags "1.0.5" - 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.0" - yargs-parser "13.1.1" - yargs-unparser "1.6.0" - -mock-fs@^4.1.0: - version "4.11.0" - resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.11.0.tgz#0828107e4b843a6ba855ecebfe3c6e073b69db92" - integrity sha512-Yp4o3/ZA15wsXqJTT+R+9w2AYIkD1i80Lds47wDbuUhOvQvm+O2EfjFZSz0pMgZZSPHRhGxgcd2+GL4+jZMtdw== - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -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.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -mute-stdout@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mute-stdout/-/mute-stdout-1.0.1.tgz#acb0300eb4de23a7ddeec014e3e96044b3472331" - integrity sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg== - -nan@2.13.2: - version "2.13.2" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.13.2.tgz#f51dc7ae66ba7d5d55e1e6d4d8092e802c9aefe7" - integrity sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw== - -nan@^2.0.8, nan@^2.11.0, nan@^2.12.1, nan@^2.14.0, nan@^2.2.1: - version "2.14.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" - integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== - -nano-json-stream-parser@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f" - integrity sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18= - -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -negotiator@0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" - integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== - -next-tick@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" - integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= - -node-environment-flags@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.5.tgz#fa930275f5bf5dae188d6192b24b4c8bbac3d76a" - integrity sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ== - dependencies: - object.getownpropertydescriptors "^2.0.3" - semver "^5.7.0" - -node-fetch@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" - integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U= - -node-fetch@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" - integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== - -node-fetch@~1.7.1: - version "1.7.3" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" - integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== - dependencies: - encoding "^0.1.11" - is-stream "^1.0.1" - -normalize-package-data@^2.3.2: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= - dependencies: - remove-trailing-separator "^1.0.1" - -normalize-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -normalize-url@^4.1.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" - integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== - -now-and-later@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/now-and-later/-/now-and-later-2.0.1.tgz#8e579c8685764a7cc02cb680380e94f43ccb1f7c" - integrity sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ== - dependencies: - once "^1.3.2" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -number-to-bn@1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0" - integrity sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA= - dependencies: - bn.js "4.11.6" - strip-hex-prefix "1.0.0" - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -object-assign@^4, object-assign@^4.0.0, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-inspect@^1.7.0, object-inspect@~1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" - integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== - -object-is@^1.0.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.2.tgz#c5d2e87ff9e119f78b7a088441519e2eec1573b6" - integrity sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - -object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object-keys@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" - integrity sha1-KKaq50KN0sOpLz2V8hM13SBOAzY= - -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= - dependencies: - isobject "^3.0.0" - -object.assign@4.1.0, object.assign@^4.0.4, 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.defaults@^1.0.0, object.defaults@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf" - integrity sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8= - dependencies: - array-each "^1.0.1" - array-slice "^1.0.0" - for-own "^1.0.0" - isobject "^3.0.0" - -object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" - integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - -object.map@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object.map/-/object.map-1.0.1.tgz#cf83e59dc8fcc0ad5f4250e1f78b3b81bd801d37" - integrity sha1-z4Plncj8wK1fQlDh94s7gb2AHTc= - dependencies: - for-own "^1.0.0" - make-iterator "^1.0.0" - -object.pick@^1.2.0, object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= - dependencies: - isobject "^3.0.1" - -object.reduce@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object.reduce/-/object.reduce-1.0.1.tgz#6fe348f2ac7fa0f95ca621226599096825bb03ad" - integrity sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60= - dependencies: - for-own "^1.0.0" - make-iterator "^1.0.0" - -oboe@2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.4.tgz#20c88cdb0c15371bb04119257d4fdd34b0aa49f6" - integrity sha1-IMiM2wwVNxuwQRklfU/dNLCqSfY= - dependencies: - http-https "^1.0.0" - -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= - dependencies: - ee-first "1.1.1" - -once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -ordered-read-streams@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz#77c0cb37c41525d64166d990ffad7ec6a0e1363e" - integrity sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4= - dependencies: - readable-stream "^2.0.1" - -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - -os-locale@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" - integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= - dependencies: - lcid "^1.0.0" - -os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -p-cancelable@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" - integrity sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw== - -p-cancelable@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" - integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -p-limit@^2.0.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" - integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ== - dependencies: - p-try "^2.0.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-timeout@^1.1.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386" - integrity sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y= - dependencies: - p-finally "^1.0.0" - -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== - -parse-asn1@^5.0.0: - version "5.1.5" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" - integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ== - dependencies: - asn1.js "^4.0.0" - browserify-aes "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.0" - pbkdf2 "^3.0.3" - safe-buffer "^5.1.1" - -parse-filepath@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891" - integrity sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE= - dependencies: - is-absolute "^1.0.0" - map-cache "^0.2.0" - path-root "^0.1.1" - -parse-headers@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.3.tgz#5e8e7512383d140ba02f0c7aa9f49b4399c92515" - integrity sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA== - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= - dependencies: - error-ex "^1.2.0" - -parse-node-version@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" - integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== - -parse-passwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" - integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= - -parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= - -path-browserify@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" - integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== - -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= - dependencies: - pinkie-promise "^2.0.0" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - -path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== - -path-root-regex@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" - integrity sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0= - -path-root@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" - integrity sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc= - dependencies: - path-root-regex "^0.1.0" - -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= - -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -pathval@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" - integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA= - -pbkdf2@^3.0.3, pbkdf2@^3.0.9: - version "3.0.17" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" - integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== - 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" - -pend@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" - integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - -pify@^2.0.0, pify@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= - -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= - -precond@0.2: - version "0.2.3" - resolved "https://registry.yarnpkg.com/precond/-/precond-0.2.3.tgz#aa9591bcaa24923f1e0f4849d240f47efc1075ac" - integrity sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw= - -prepend-http@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= - -prepend-http@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" - integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= - -prettier@^1.19.1: - version "1.19.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" - integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== - -pretty-hrtime@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" - integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE= - -private@^0.1.6, private@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" - integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== - -process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -process@~0.5.1: - version "0.5.2" - resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" - integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8= - -promise-to-callback@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/promise-to-callback/-/promise-to-callback-1.0.0.tgz#5d2a749010bfb67d963598fcd3960746a68feef7" - integrity sha1-XSp0kBC/tn2WNZj805YHRqaP7vc= - dependencies: - is-fn "^1.0.0" - set-immediate-shim "^1.0.1" - -proxy-addr@~2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" - integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== - dependencies: - forwarded "~0.1.2" - ipaddr.js "1.9.1" - -prr@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" - integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= - -pseudomap@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= - -psl@^1.1.28: - version "1.8.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== - -public-encrypt@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" - integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== - dependencies: - bn.js "^4.1.0" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - parse-asn1 "^5.0.0" - randombytes "^2.0.1" - safe-buffer "^5.1.2" - -pull-cat@^1.1.9: - version "1.1.11" - resolved "https://registry.yarnpkg.com/pull-cat/-/pull-cat-1.1.11.tgz#b642dd1255da376a706b6db4fa962f5fdb74c31b" - integrity sha1-tkLdElXaN2pwa220+pYvX9t0wxs= - -pull-defer@^0.2.2: - version "0.2.3" - resolved "https://registry.yarnpkg.com/pull-defer/-/pull-defer-0.2.3.tgz#4ee09c6d9e227bede9938db80391c3dac489d113" - integrity sha512-/An3KE7mVjZCqNhZsr22k1Tx8MACnUnHZZNPSJ0S62td8JtYr/AiRG42Vz7Syu31SoTLUzVIe61jtT/pNdjVYA== - -pull-level@^2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pull-level/-/pull-level-2.0.4.tgz#4822e61757c10bdcc7cf4a03af04c92734c9afac" - integrity sha512-fW6pljDeUThpq5KXwKbRG3X7Ogk3vc75d5OQU/TvXXui65ykm+Bn+fiktg+MOx2jJ85cd+sheufPL+rw9QSVZg== - dependencies: - level-post "^1.0.7" - pull-cat "^1.1.9" - pull-live "^1.0.1" - pull-pushable "^2.0.0" - pull-stream "^3.4.0" - pull-window "^2.1.4" - stream-to-pull-stream "^1.7.1" - -pull-live@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/pull-live/-/pull-live-1.0.1.tgz#a4ecee01e330155e9124bbbcf4761f21b38f51f5" - integrity sha1-pOzuAeMwFV6RJLu89HYfIbOPUfU= - dependencies: - pull-cat "^1.1.9" - pull-stream "^3.4.0" - -pull-pushable@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/pull-pushable/-/pull-pushable-2.2.0.tgz#5f2f3aed47ad86919f01b12a2e99d6f1bd776581" - integrity sha1-Xy867UethpGfAbEqLpnW8b13ZYE= - -pull-stream@^3.2.3, pull-stream@^3.4.0, pull-stream@^3.6.8: - version "3.6.14" - resolved "https://registry.yarnpkg.com/pull-stream/-/pull-stream-3.6.14.tgz#529dbd5b86131f4a5ed636fdf7f6af00781357ee" - integrity sha512-KIqdvpqHHaTUA2mCYcLG1ibEbu/LCKoJZsBWyv9lSYtPkJPBq8m3Hxa103xHi6D2thj5YXa0TqK3L3GUkwgnew== - -pull-window@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/pull-window/-/pull-window-2.1.4.tgz#fc3b86feebd1920c7ae297691e23f705f88552f0" - integrity sha1-/DuG/uvRkgx64pdpHiP3BfiFUvA= - dependencies: - looper "^2.0.0" - -pump@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" - integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pumpify@^1.3.5: - version "1.5.1" - resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" - integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== - dependencies: - duplexify "^3.6.0" - inherits "^2.0.3" - pump "^2.0.0" - -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= - -punycode@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" - integrity sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0= - -punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -qs@6.7.0: - version "6.7.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" - integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== - -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== - -query-string@^5.0.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" - integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== - dependencies: - decode-uri-component "^0.2.0" - object-assign "^4.1.0" - strict-uri-encode "^1.0.0" - -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= - -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.0.6, randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -randomfill@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" - integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== - dependencies: - randombytes "^2.0.5" - safe-buffer "^5.1.0" - -range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -raw-body@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" - integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== - dependencies: - bytes "3.1.0" - http-errors "1.7.2" - iconv-lite "0.4.24" - unpipe "1.0.0" - -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - -readable-stream@^1.0.33: - version "1.1.14" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" - integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@~1.0.15: - version "1.0.34" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" - integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readdirp@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" - integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== - dependencies: - graceful-fs "^4.1.11" - micromatch "^3.1.10" - readable-stream "^2.0.2" - -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= - dependencies: - resolve "^1.1.6" - -regenerate@^1.2.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" - integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== - -regenerator-runtime@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" - integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== - -regenerator-transform@^0.10.0: - version "0.10.1" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" - integrity sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q== - dependencies: - babel-runtime "^6.18.0" - babel-types "^6.19.0" - private "^0.1.6" - -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - -regexp.prototype.flags@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75" - integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - -regexpu-core@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" - integrity sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA= - dependencies: - regenerate "^1.2.1" - regjsgen "^0.2.0" - regjsparser "^0.1.4" - -regjsgen@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" - integrity sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc= - -regjsparser@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" - integrity sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw= - dependencies: - jsesc "~0.5.0" - -remove-bom-buffer@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz#c2bf1e377520d324f623892e33c10cac2c252b53" - integrity sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ== - dependencies: - is-buffer "^1.1.5" - is-utf8 "^0.2.1" - -remove-bom-stream@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz#05f1a593f16e42e1fb90ebf59de8e569525f9523" - integrity sha1-BfGlk/FuQuH7kOv1nejlaVJflSM= - dependencies: - remove-bom-buffer "^3.0.0" - safe-buffer "^5.1.0" - through2 "^2.0.3" - -remove-trailing-separator@^1.0.1, remove-trailing-separator@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= - -repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== - -repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= - -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= - dependencies: - is-finite "^1.0.0" - -replace-ext@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" - integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= - -replace-homedir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/replace-homedir/-/replace-homedir-1.0.0.tgz#e87f6d513b928dde808260c12be7fec6ff6e798c" - integrity sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw= - dependencies: - homedir-polyfill "^1.0.1" - is-absolute "^1.0.0" - remove-trailing-separator "^1.1.0" - -request@^2.79.0, request@^2.85.0: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -require-from-string@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= - -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-dir@^1.0.0, resolve-dir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" - integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= - dependencies: - expand-tilde "^2.0.0" - global-modules "^1.0.0" - -resolve-options@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/resolve-options/-/resolve-options-1.1.0.tgz#32bb9e39c06d67338dc9378c0d6d6074566ad131" - integrity sha1-MrueOcBtZzONyTeMDW1gdFZq0TE= - dependencies: - value-or-function "^3.0.0" - -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= - -resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.4.0, resolve@~1.15.1: - version "1.15.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" - integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w== - dependencies: - path-parse "^1.0.6" - -responselike@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" - integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= - dependencies: - lowercase-keys "^1.0.0" - -resumer@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/resumer/-/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759" - integrity sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k= - dependencies: - through "~2.3.4" - -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== - -rimraf@^2.2.8, rimraf@^2.6.3: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - -rimraf@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.0.tgz#614176d4b3010b75e5c390eb0ee96f6dc0cebb9b" - integrity sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg== - dependencies: - glob "^7.1.3" - -ripemd160@^2.0.0, ripemd160@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - -rlp@^2.0.0, rlp@^2.2.1, rlp@^2.2.2, rlp@^2.2.3: - version "2.2.4" - resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.4.tgz#d6b0e1659e9285fc509a5d169a9bd06f704951c1" - integrity sha512-fdq2yYCWpAQBhwkZv+Z8o/Z4sPmYm1CUq6P7n6lVTOdb949CnqA0sndXal5C1NleSVSZm6q5F3iEbauyVln/iw== - dependencies: - bn.js "^4.11.1" - -rustbn.js@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca" - integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA== - -safe-buffer@5.1.2, 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-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" - integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== - -safe-event-emitter@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/safe-event-emitter/-/safe-event-emitter-1.0.1.tgz#5b692ef22329ed8f69fdce607e50ca734f6f20af" - integrity sha512-e1wFe99A91XYYxoQbcq2ZJUWurxEyP8vfz7A7vuUe1s95q8r5ebraVaA1BukYJcpM6V16ugWoD9vngi8Ccu5fg== - dependencies: - events "^3.0.0" - -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= - dependencies: - ret "~0.1.10" - -"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== - -scrypt-js@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.3.tgz#bb0040be03043da9a012a2cea9fc9f852cfc87d4" - integrity sha1-uwBAvgMEPamgEqLOqfyfhSz8h9Q= - -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@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/scrypt.js/-/scrypt.js-0.3.0.tgz#6c62d61728ad533c8c376a2e5e3e86d41a95c4c0" - integrity sha512-42LTc1nyFsyv/o0gcHtDztrn+aqpkaCNt5Qh7ATBZfhEZU7IC/0oT/qbBH+uRNoAPvs2fwiOId68FDEoSRA8/A== - dependencies: - scryptsy "^1.2.1" - optionalDependencies: - scrypt "^6.0.2" - -scrypt@^6.0.2: - version "6.0.3" - resolved "https://registry.yarnpkg.com/scrypt/-/scrypt-6.0.3.tgz#04e014a5682b53fa50c2d5cce167d719c06d870d" - integrity sha1-BOAUpWgrU/pQwtXM4WfXGcBthw0= - dependencies: - nan "^2.0.8" - -scryptsy@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/scryptsy/-/scryptsy-1.2.1.tgz#a3225fa4b2524f802700761e2855bdf3b2d92163" - integrity sha1-oyJfpLJST4AnAHYeKFW987LZIWM= - dependencies: - pbkdf2 "^3.0.3" - -scryptsy@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/scryptsy/-/scryptsy-2.1.0.tgz#8d1e8d0c025b58fdd25b6fa9a0dc905ee8faa790" - integrity sha512-1CdSqHQowJBnMAFyPEBRfqag/YP9OF394FV+4YREIJX4ljD7OxvQRDayyoyyCk+senRjSkP6VnUNQmVQqB6g7w== - -secp256k1@^3.0.1: - version "3.8.0" - resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-3.8.0.tgz#28f59f4b01dbee9575f56a47034b7d2e3b3b352d" - integrity sha512-k5ke5avRZbtl9Tqx/SA7CbY3NF6Ro+Sj9cZxezFzuBlLDmyqPiL8hJJ+EmzD8Ig4LUDByHJ3/iPOVoRixs/hmw== - 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" - -seedrandom@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.1.tgz#eb3dde015bcf55df05a233514e5df44ef9dce083" - integrity sha512-1/02Y/rUeU1CJBAGLebiC5Lbo5FnB22gQbIFFYTLkwvp1xdABZJH1sn4ZT1MzXmPpzv+Rf/Lu2NcsLJiK4rcDg== - -seek-bzip@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.5.tgz#cfe917cb3d274bcffac792758af53173eb1fabdc" - integrity sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w= - dependencies: - commander "~2.8.1" - -semaphore@>=1.0.1, semaphore@^1.0.3, semaphore@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/semaphore/-/semaphore-1.1.0.tgz#aaad8b86b20fe8e9b32b16dc2ee682a8cd26a8aa" - integrity sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA== - -semver-greatest-satisfied-range@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz#13e8c2658ab9691cb0cd71093240280d36f77a5b" - integrity sha1-E+jCZYq5aRywzXEJMkAoDTb3els= - dependencies: - sver-compat "^1.5.0" - -"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0, semver@^5.7.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -semver@~5.4.1: - version "5.4.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" - integrity sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg== - -send@0.17.1: - version "0.17.1" - resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" - integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== - 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" - -serve-static@1.14.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" - integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.17.1" - -servify@^0.1.12: - version "0.1.12" - resolved "https://registry.yarnpkg.com/servify/-/servify-0.1.12.tgz#142ab7bee1f1d033b66d0707086085b17c06db95" - integrity sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw== - dependencies: - body-parser "^1.16.0" - cors "^2.8.1" - express "^4.14.0" - request "^2.79.0" - xhr "^2.3.3" - -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -set-immediate-shim@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" - integrity sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E= - -set-value@^2.0.0, set-value@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" - integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - -setimmediate@1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.4.tgz#20e81de622d4a02588ce0c8da8973cbcf1d3138f" - integrity sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48= - -setimmediate@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= - -setprototypeof@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" - integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== - -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" - -sha3@^1.2.2: - version "1.2.6" - resolved "https://registry.yarnpkg.com/sha3/-/sha3-1.2.6.tgz#102aa3e47dc793e2357902c3cce8760822f9e905" - integrity sha512-KgLGmJGrmNB4JWVsAV11Yk6KbvsAiygWJc7t5IebWva/0NukNrjJqhtKhzy3Eiv2AKuGvhZZt7dt1mDo7HkoiQ== - dependencies: - nan "2.13.2" - -simple-concat@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.0.tgz#7344cbb8b6e26fb27d66b2fc86f9f6d5997521c6" - integrity sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY= - -simple-get@^2.7.0: - version "2.8.1" - resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.1.tgz#0e22e91d4575d87620620bc91308d57a77f44b5d" - integrity sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw== - dependencies: - decompress-response "^3.3.0" - once "^1.3.1" - simple-concat "^1.0.0" - -slash@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= - -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - -solc@0.5.16: - version "0.5.16" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.5.16.tgz#6c8d710a3792ccc79db924606b558a1149b1c603" - integrity sha512-weEtRtisJyf+8UjELs7S4ST1KK7UIq6SRB7tpprfJBL9b5mTrZAT7m4gJKi2h6MiBpuSWfnraK8BnkyWzuTMRA== - 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" - -solc@^0.6.3: - version "0.6.6" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.6.6.tgz#0d4b9c2e7105dd6015583f5e1c5ba6a35861ea71" - integrity sha512-p0IO/1fRaHWKN+qR+mUivpwnBpFYD8EoFAzT8VL4lmllNwsyEO7TJJAc2QK0XUeWOYOT92NWKhDNNNLTVbHShA== - 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" - -source-map-resolve@^0.5.0: - version "0.5.3" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" - integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== - dependencies: - atob "^2.1.2" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-support@0.5.12: - version "0.5.12" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599" - integrity sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-support@^0.4.15: - version "0.4.18" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" - integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== - dependencies: - source-map "^0.5.6" - -source-map-support@^0.5.6: - version "0.5.16" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" - integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= - -source-map@^0.5.6, source-map@^0.5.7: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - -source-map@^0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -sparkles@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.1.tgz#008db65edce6c50eec0c5e228e1945061dd0437c" - integrity sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw== - -spdx-correct@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" - integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" - integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== - -spdx-expression-parse@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" - integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.5" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" - integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q== - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== - dependencies: - extend-shallow "^3.0.0" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - 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" - -stack-trace@0.0.10: - version "0.0.10" - resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" - integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -"statuses@>= 1.5.0 < 2", statuses@~1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= - -stream-exhaust@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/stream-exhaust/-/stream-exhaust-1.0.2.tgz#acdac8da59ef2bc1e17a2c0ccf6c320d120e555d" - integrity sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw== - -stream-shift@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" - integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== - -stream-to-pull-stream@^1.7.1: - version "1.7.3" - resolved "https://registry.yarnpkg.com/stream-to-pull-stream/-/stream-to-pull-stream-1.7.3.tgz#4161aa2d2eb9964de60bfa1af7feaf917e874ece" - integrity sha512-6sNyqJpr5dIOQdgNy/xcDWwDuzAsAwVzhzrWlAPAQ7Lkjx/rv0wgvxEyKwTq6FmNd5rjTrELt/CLmaSw7crMGg== - dependencies: - looper "^3.0.0" - pull-stream "^3.2.3" - -strict-uri-encode@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" - integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= - -string-width@^1.0.1, string-width@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2": - 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.prototype.trim@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.1.tgz#141233dff32c82bfad80684d7e5f0869ee0fb782" - integrity sha512-MjGFEeqixw47dAMFMtgUro/I0+wNqZB5GKXGt1fFr24u3TzDXCPu7J9Buppzoe3r/LqkSDLDDJzE15RGWDGAVw== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - function-bind "^1.1.1" - -string.prototype.trimend@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" - integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - -string.prototype.trimleft@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz#4408aa2e5d6ddd0c9a80739b087fbc067c03b3cc" - integrity sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - string.prototype.trimstart "^1.0.0" - -string.prototype.trimright@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz#c76f1cef30f21bbad8afeb8db1511496cfb0f2a3" - integrity sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - string.prototype.trimend "^1.0.0" - -string.prototype.trimstart@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" - integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - 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-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= - dependencies: - is-utf8 "^0.2.0" - -strip-dirs@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5" - integrity sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g== - dependencies: - is-natural-number "^4.0.1" - -strip-hex-prefix@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f" - integrity sha1-DF8VX+8RUTczd96du1iNoFUA428= - dependencies: - is-hex-prefixed "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 sha1-PFMZQukIwml8DsNEhYwobHygpgo= - -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@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= - -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" - -sver-compat@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/sver-compat/-/sver-compat-1.5.0.tgz#3cf87dfeb4d07b4a3f14827bc186b3fd0c645cd8" - integrity sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg= - dependencies: - es6-iterator "^2.0.1" - es6-symbol "^3.1.1" - -swarm-js@0.1.39: - version "0.1.39" - resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.39.tgz#79becb07f291d4b2a178c50fee7aa6e10342c0e8" - integrity sha512-QLMqL2rzF6n5s50BptyD6Oi0R1aWlJC5Y17SRIVXRj6OR1DRIPM7nepvrxxkjA1zNzFz6mUOMjfeqeDaWB7OOg== - dependencies: - bluebird "^3.5.0" - buffer "^5.0.5" - decompress "^4.0.0" - 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-promise "^0.1.2" - -tape@^4.6.3: - version "4.13.2" - resolved "https://registry.yarnpkg.com/tape/-/tape-4.13.2.tgz#eb419b9d9bc004025b1a81a5b63093e07f425629" - integrity sha512-waWwC/OqYVE9TS6r1IynlP2sEdk4Lfo6jazlgkuNkPTHIbuG2BTABIaKdlQWwPeB6Oo4ksZ1j33Yt0NTOAlYMQ== - 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.0" - object-inspect "~1.7.0" - resolve "~1.15.1" - resumer "~0.0.0" - string.prototype.trim "~1.2.1" - through "~2.3.8" - -tar-stream@^1.5.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" - integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== - dependencies: - bl "^1.0.0" - buffer-alloc "^1.2.0" - end-of-stream "^1.0.0" - fs-constants "^1.0.0" - readable-stream "^2.3.0" - to-buffer "^1.1.1" - xtend "^4.0.0" - -tar@^4.0.2: - version "4.4.13" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" - integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== - 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" - -through2-filter@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-3.0.0.tgz#700e786df2367c2c88cd8aa5be4cf9c1e7831254" - integrity sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA== - dependencies: - through2 "~2.0.0" - xtend "~4.0.0" - -through2@^2.0.0, through2@^2.0.3, through2@~2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" - integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== - dependencies: - readable-stream "~2.3.6" - xtend "~4.0.1" - -through@^2.3.8, through@~2.3.4, through@~2.3.8: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - -time-stamp@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" - integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM= - -timed-out@^4.0.0, timed-out@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" - integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= - -tmp@0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - -tmp@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877" - integrity sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw== - dependencies: - rimraf "^2.6.3" - -to-absolute-glob@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz#1865f43d9e74b0822db9f145b78cff7d0f7c849b" - integrity sha1-GGX0PZ50sIItufFFt4z/fQ98hJs= - dependencies: - is-absolute "^1.0.0" - is-negated-glob "^1.0.0" - -to-buffer@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" - integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== - -to-fast-properties@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" - integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= - -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= - dependencies: - kind-of "^3.0.2" - -to-readable-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" - integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - -to-through@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-through/-/to-through-2.0.0.tgz#fc92adaba072647bc0b67d6b03664aa195093af6" - integrity sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY= - dependencies: - through2 "^2.0.3" - -toidentifier@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" - integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== - -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-right@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" - integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= - -ts-node@^8.5.4: - version "8.6.2" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.6.2.tgz#7419a01391a818fbafa6f826a33c1a13e9464e35" - integrity sha512-4mZEbofxGqLL2RImpe3zMJukvEvcO1XP8bj8ozBPySdCUXEcU5cIRwR0aM3R+VoZq7iXc8N86NC0FspGRqP4gg== - dependencies: - arg "^4.1.0" - diff "^4.0.1" - make-error "^1.1.1" - source-map-support "^0.5.6" - yn "3.1.1" - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -tweetnacl-util@^0.15.0: - 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 sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - -tweetnacl@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" - integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== - -type-detect@^4.0.0, type-detect@^4.0.5: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - -type-is@~1.6.17, type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -type@^1.0.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" - integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== - -type@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/type/-/type-2.0.0.tgz#5f16ff6ef2eb44f260494dae271033b29c09a9c3" - integrity sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow== - -typedarray-to-buffer@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" - integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== - dependencies: - is-typedarray "^1.0.0" - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= - -typescript@^3.7.3: - version "3.7.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.5.tgz#0692e21f65fd4108b9330238aac11dd2e177a1ae" - integrity sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw== - -typewise-core@^1.2, typewise-core@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/typewise-core/-/typewise-core-1.2.0.tgz#97eb91805c7f55d2f941748fa50d315d991ef195" - integrity sha1-l+uRgFx/VdL5QXSPpQ0xXZke8ZU= - -typewise@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/typewise/-/typewise-1.0.3.tgz#1067936540af97937cc5dcf9922486e9fa284651" - integrity sha1-EGeTZUCvl5N8xdz5kiSG6fooRlE= - dependencies: - typewise-core "^1.2.0" - -typewiselite@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typewiselite/-/typewiselite-1.0.0.tgz#c8882fa1bb1092c06005a97f34ef5c8508e3664e" - integrity sha1-yIgvobsQksBgBal/NO9chQjjZk4= - -ultron@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" - integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== - -unbzip2-stream@^1.0.9: - version "1.4.1" - resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.1.tgz#151b104af853df3efdaa135d8b1eca850a44b426" - integrity sha512-sgDYfSDPMsA4Hr2/w7vOlrJBlwzmyakk1+hW8ObLvxSp0LA36LcL2XItGvOT3OSblohSdevMuT8FQjLsqyy4sA== - dependencies: - buffer "^5.2.1" - through "^2.3.8" - -unc-path-regex@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" - integrity sha1-5z3T17DXxe2G+6xrCufYxqadUPo= - -underscore@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961" - integrity sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg== - -undertaker-registry@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/undertaker-registry/-/undertaker-registry-1.0.1.tgz#5e4bda308e4a8a2ae584f9b9a4359a499825cc50" - integrity sha1-XkvaMI5KiirlhPm5pDWaSZglzFA= - -undertaker@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/undertaker/-/undertaker-1.2.1.tgz#701662ff8ce358715324dfd492a4f036055dfe4b" - integrity sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA== - dependencies: - arr-flatten "^1.0.1" - arr-map "^2.0.0" - bach "^1.0.0" - collection-map "^1.0.0" - es6-weak-map "^2.0.1" - last-run "^1.1.0" - object.defaults "^1.0.0" - object.reduce "^1.0.0" - undertaker-registry "^1.0.0" - -union-value@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" - integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^2.0.1" - -unique-stream@^2.0.2: - version "2.3.1" - resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.3.1.tgz#c65d110e9a4adf9a6c5948b28053d9a8d04cbeac" - integrity sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A== - dependencies: - json-stable-stringify-without-jsonify "^1.0.1" - through2-filter "^3.0.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== - -unorm@^1.3.3: - version "1.6.0" - resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.6.0.tgz#029b289661fba714f1a9af439eb51d9b16c205af" - integrity sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA== - -unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= - -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -upath@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" - integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== - -uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== - dependencies: - punycode "^2.1.0" - -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= - -url-parse-lax@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" - integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= - dependencies: - prepend-http "^1.0.1" - -url-parse-lax@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" - integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= - dependencies: - prepend-http "^2.0.0" - -url-set-query@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339" - integrity sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk= - -url-to-options@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" - integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k= - -url@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" - integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= - dependencies: - punycode "1.3.2" - querystring "0.2.0" - -use@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== - -utf8@3.0.0, utf8@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" - integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== - -util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -util.promisify@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" - integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.2" - has-symbols "^1.0.1" - object.getownpropertydescriptors "^2.1.0" - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= - -uuid@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.1.tgz#c2a30dedb3e535d72ccf82e343941a50ba8533ac" - integrity sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w= - -uuid@3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" - integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== - -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -v8flags@^3.0.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.1.3.tgz#fc9dc23521ca20c5433f81cc4eb9b3033bb105d8" - integrity sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w== - dependencies: - homedir-polyfill "^1.0.1" - -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" - -value-or-function@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/value-or-function/-/value-or-function-3.0.0.tgz#1c243a50b595c1be54a754bfece8563b9ff8d813" - integrity sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM= - -vary@^1, vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -vinyl-fs@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-3.0.3.tgz#c85849405f67428feabbbd5c5dbdd64f47d31bc7" - integrity sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng== - dependencies: - fs-mkdirp-stream "^1.0.0" - glob-stream "^6.1.0" - graceful-fs "^4.0.0" - is-valid-glob "^1.0.0" - lazystream "^1.0.0" - lead "^1.0.0" - object.assign "^4.0.4" - pumpify "^1.3.5" - readable-stream "^2.3.3" - remove-bom-buffer "^3.0.0" - remove-bom-stream "^1.2.0" - resolve-options "^1.1.0" - through2 "^2.0.0" - to-through "^2.0.0" - value-or-function "^3.0.0" - vinyl "^2.0.0" - vinyl-sourcemap "^1.1.0" - -vinyl-sourcemap@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz#92a800593a38703a8cdb11d8b300ad4be63b3e16" - integrity sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY= - dependencies: - append-buffer "^1.0.2" - convert-source-map "^1.5.0" - graceful-fs "^4.1.6" - normalize-path "^2.1.1" - now-and-later "^2.0.0" - remove-bom-buffer "^3.0.0" - vinyl "^2.0.0" - -vinyl@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.0.tgz#d85b07da96e458d25b2ffe19fece9f2caa13ed86" - integrity sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg== - dependencies: - clone "^2.1.1" - clone-buffer "^1.0.0" - clone-stats "^1.0.0" - cloneable-readable "^1.0.0" - remove-trailing-separator "^1.0.1" - replace-ext "^1.0.0" - -web3-bzz@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.2.4.tgz#a4adb7a8cba3d260de649bdb1f14ed359bfb3821" - integrity sha512-MqhAo/+0iQSMBtt3/QI1rU83uvF08sYq8r25+OUZ+4VtihnYsmkkca+rdU0QbRyrXY2/yGIpI46PFdh0khD53A== - dependencies: - "@types/node" "^10.12.18" - got "9.6.0" - swarm-js "0.1.39" - underscore "1.9.1" - -web3-core-helpers@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.2.4.tgz#ffd425861f4d66b3f38df032afdb39ea0971fc0f" - integrity sha512-U7wbsK8IbZvF3B7S+QMSNP0tni/6VipnJkB0tZVEpHEIV2WWeBHYmZDnULWcsS/x/jn9yKhJlXIxWGsEAMkjiw== - dependencies: - underscore "1.9.1" - web3-eth-iban "1.2.4" - web3-utils "1.2.4" - -web3-core-method@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.2.4.tgz#a0fbc50b8ff5fd214021435cc2c6d1e115807aed" - integrity sha512-8p9kpL7di2qOVPWgcM08kb+yKom0rxRCMv6m/K+H+yLSxev9TgMbCgMSbPWAHlyiF3SJHw7APFKahK5Z+8XT5A== - dependencies: - underscore "1.9.1" - web3-core-helpers "1.2.4" - web3-core-promievent "1.2.4" - web3-core-subscriptions "1.2.4" - web3-utils "1.2.4" - -web3-core-promievent@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.2.4.tgz#75e5c0f2940028722cdd21ba503ebd65272df6cb" - integrity sha512-gEUlm27DewUsfUgC3T8AxkKi8Ecx+e+ZCaunB7X4Qk3i9F4C+5PSMGguolrShZ7Zb6717k79Y86f3A00O0VAZw== - dependencies: - any-promise "1.3.0" - eventemitter3 "3.1.2" - -web3-core-requestmanager@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.2.4.tgz#0a7020a23fb91c6913c611dfd3d8c398d1e4b4a8" - integrity sha512-eZJDjyNTDtmSmzd3S488nR/SMJtNnn/GuwxnMh3AzYCqG3ZMfOylqTad2eYJPvc2PM5/Gj1wAMQcRpwOjjLuPg== - dependencies: - underscore "1.9.1" - web3-core-helpers "1.2.4" - web3-providers-http "1.2.4" - web3-providers-ipc "1.2.4" - web3-providers-ws "1.2.4" - -web3-core-subscriptions@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.2.4.tgz#0dc095b5cfd82baa527a39796e3515a846b21b99" - integrity sha512-3D607J2M8ymY9V+/WZq4MLlBulwCkwEjjC2U+cXqgVO1rCyVqbxZNCmHyNYHjDDCxSEbks9Ju5xqJxDSxnyXEw== - dependencies: - eventemitter3 "3.1.2" - underscore "1.9.1" - web3-core-helpers "1.2.4" - -web3-core@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.2.4.tgz#2df13b978dcfc59c2abaa887d27f88f21ad9a9d6" - integrity sha512-CHc27sMuET2cs1IKrkz7xzmTdMfZpYswe7f0HcuyneTwS1yTlTnHyqjAaTy0ZygAb/x4iaVox+Gvr4oSAqSI+A== - dependencies: - "@types/bignumber.js" "^5.0.0" - "@types/bn.js" "^4.11.4" - "@types/node" "^12.6.1" - web3-core-helpers "1.2.4" - web3-core-method "1.2.4" - web3-core-requestmanager "1.2.4" - web3-utils "1.2.4" - -web3-eth-abi@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.2.4.tgz#5b73e5ef70b03999227066d5d1310b168845e2b8" - integrity sha512-8eLIY4xZKoU3DSVu1pORluAw9Ru0/v4CGdw5so31nn+7fR8zgHMgwbFe0aOqWQ5VU42PzMMXeIJwt4AEi2buFg== - dependencies: - ethers "4.0.0-beta.3" - underscore "1.9.1" - web3-utils "1.2.4" - -web3-eth-accounts@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.2.4.tgz#ada6edc49542354328a85cafab067acd7f88c288" - integrity sha512-04LzT/UtWmRFmi4hHRewP5Zz43fWhuHiK5XimP86sUQodk/ByOkXQ3RoXyGXFMNoRxdcAeRNxSfA2DpIBc9xUw== - dependencies: - "@web3-js/scrypt-shim" "^0.1.0" - any-promise "1.3.0" - crypto-browserify "3.12.0" - eth-lib "0.2.7" - ethereumjs-common "^1.3.2" - ethereumjs-tx "^2.1.1" - underscore "1.9.1" - uuid "3.3.2" - web3-core "1.2.4" - web3-core-helpers "1.2.4" - web3-core-method "1.2.4" - web3-utils "1.2.4" - -web3-eth-contract@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.2.4.tgz#68ef7cc633232779b0a2c506a810fbe903575886" - integrity sha512-b/9zC0qjVetEYnzRA1oZ8gF1OSSUkwSYi5LGr4GeckLkzXP7osEnp9lkO/AQcE4GpG+l+STnKPnASXJGZPgBRQ== - dependencies: - "@types/bn.js" "^4.11.4" - underscore "1.9.1" - web3-core "1.2.4" - web3-core-helpers "1.2.4" - web3-core-method "1.2.4" - web3-core-promievent "1.2.4" - web3-core-subscriptions "1.2.4" - web3-eth-abi "1.2.4" - web3-utils "1.2.4" - -web3-eth-ens@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.2.4.tgz#b95b3aa99fb1e35c802b9e02a44c3046a3fa065e" - integrity sha512-g8+JxnZlhdsCzCS38Zm6R/ngXhXzvc3h7bXlxgKU4coTzLLoMpgOAEz71GxyIJinWTFbLXk/WjNY0dazi9NwVw== - dependencies: - eth-ens-namehash "2.0.8" - underscore "1.9.1" - web3-core "1.2.4" - web3-core-helpers "1.2.4" - web3-core-promievent "1.2.4" - web3-eth-abi "1.2.4" - web3-eth-contract "1.2.4" - web3-utils "1.2.4" - -web3-eth-iban@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.2.4.tgz#8e0550fd3fd8e47a39357d87fe27dee9483ee476" - integrity sha512-D9HIyctru/FLRpXakRwmwdjb5bWU2O6UE/3AXvRm6DCOf2e+7Ve11qQrPtaubHfpdW3KWjDKvlxV9iaFv/oTMQ== - dependencies: - bn.js "4.11.8" - web3-utils "1.2.4" - -web3-eth-personal@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.2.4.tgz#3224cca6851c96347d9799b12c1b67b2a6eb232b" - integrity sha512-5Russ7ZECwHaZXcN3DLuLS7390Vzgrzepl4D87SD6Sn1DHsCZtvfdPIYwoTmKNp69LG3mORl7U23Ga5YxqkICw== - dependencies: - "@types/node" "^12.6.1" - web3-core "1.2.4" - web3-core-helpers "1.2.4" - web3-core-method "1.2.4" - web3-net "1.2.4" - web3-utils "1.2.4" - -web3-eth@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.2.4.tgz#24c3b1f1ac79351bbfb808b2ab5c585fa57cdd00" - integrity sha512-+j+kbfmZsbc3+KJpvHM16j1xRFHe2jBAniMo1BHKc3lho6A8Sn9Buyut6odubguX2AxoRArCdIDCkT9hjUERpA== - dependencies: - underscore "1.9.1" - web3-core "1.2.4" - web3-core-helpers "1.2.4" - web3-core-method "1.2.4" - web3-core-subscriptions "1.2.4" - web3-eth-abi "1.2.4" - web3-eth-accounts "1.2.4" - web3-eth-contract "1.2.4" - web3-eth-ens "1.2.4" - web3-eth-iban "1.2.4" - web3-eth-personal "1.2.4" - web3-net "1.2.4" - web3-utils "1.2.4" - -web3-net@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.2.4.tgz#1d246406d3aaffbf39c030e4e98bce0ca5f25458" - integrity sha512-wKOsqhyXWPSYTGbp7ofVvni17yfRptpqoUdp3SC8RAhDmGkX6irsiT9pON79m6b3HUHfLoBilFQyt/fTUZOf7A== - dependencies: - web3-core "1.2.4" - web3-core-method "1.2.4" - web3-utils "1.2.4" - -web3-provider-engine@14.2.1: - version "14.2.1" - resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-14.2.1.tgz#ef351578797bf170e08d529cb5b02f8751329b95" - integrity sha512-iSv31h2qXkr9vrL6UZDm4leZMc32SjWJFGOp/D92JXfcEboCqraZyuExDkpxKw8ziTufXieNM7LSXNHzszYdJw== - dependencies: - async "^2.5.0" - backoff "^2.5.0" - clone "^2.0.0" - cross-fetch "^2.1.0" - eth-block-tracker "^3.0.0" - eth-json-rpc-infura "^3.1.0" - eth-sig-util "^1.4.2" - ethereumjs-block "^1.2.2" - ethereumjs-tx "^1.2.0" - ethereumjs-util "^5.1.5" - ethereumjs-vm "^2.3.4" - json-rpc-error "^2.0.0" - json-stable-stringify "^1.0.1" - promise-to-callback "^1.0.0" - readable-stream "^2.2.9" - request "^2.85.0" - semaphore "^1.0.3" - ws "^5.1.1" - xhr "^2.2.0" - xtend "^4.0.1" - -web3-providers-http@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.2.4.tgz#514fcad71ae77832c2c15574296282fbbc5f4a67" - integrity sha512-dzVCkRrR/cqlIrcrWNiPt9gyt0AZTE0J+MfAu9rR6CyIgtnm1wFUVVGaxYRxuTGQRO4Dlo49gtoGwaGcyxqiTw== - dependencies: - web3-core-helpers "1.2.4" - xhr2-cookies "1.1.0" - -web3-providers-ipc@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.2.4.tgz#9d6659f8d44943fb369b739f48df09092be459bd" - integrity sha512-8J3Dguffin51gckTaNrO3oMBo7g+j0UNk6hXmdmQMMNEtrYqw4ctT6t06YOf9GgtOMjSAc1YEh3LPrvgIsR7og== - dependencies: - oboe "2.1.4" - underscore "1.9.1" - web3-core-helpers "1.2.4" - -web3-providers-ws@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.2.4.tgz#099ee271ee03f6ea4f5df9cfe969e83f4ce0e36f" - integrity sha512-F/vQpDzeK+++oeeNROl1IVTufFCwCR2hpWe5yRXN0ApLwHqXrMI7UwQNdJ9iyibcWjJf/ECbauEEQ8CHgE+MYQ== - dependencies: - "@web3-js/websocket" "^1.0.29" - underscore "1.9.1" - web3-core-helpers "1.2.4" - -web3-shh@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.2.4.tgz#5c8ff5ab624a3b14f08af0d24d2b16c10e9f70dd" - integrity sha512-z+9SCw0dE+69Z/Hv8809XDbLj7lTfEv9Sgu8eKEIdGntZf4v7ewj5rzN5bZZSz8aCvfK7Y6ovz1PBAu4QzS4IQ== - dependencies: - web3-core "1.2.4" - web3-core-method "1.2.4" - web3-core-subscriptions "1.2.4" - web3-net "1.2.4" - -web3-utils@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.2.4.tgz#96832a39a66b05bf8862a5b0bdad2799d709d951" - integrity sha512-+S86Ip+jqfIPQWvw2N/xBQq5JNqCO0dyvukGdJm8fEWHZbckT4WxSpHbx+9KLEWY4H4x9pUwnoRkK87pYyHfgQ== - dependencies: - bn.js "4.11.8" - eth-lib "0.2.7" - ethereum-bloom-filters "^1.0.6" - ethjs-unit "0.1.6" - number-to-bn "1.7.0" - randombytes "^2.1.0" - underscore "1.9.1" - utf8 "3.0.0" - -web3@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3/-/web3-1.2.4.tgz#6e7ab799eefc9b4648c2dab63003f704a1d5e7d9" - integrity sha512-xPXGe+w0x0t88Wj+s/dmAdASr3O9wmA9mpZRtixGZxmBexAF0MjfqYM+MS4tVl5s11hMTN3AZb8cDD4VLfC57A== - dependencies: - "@types/node" "^12.6.1" - web3-bzz "1.2.4" - web3-core "1.2.4" - web3-eth "1.2.4" - web3-eth-personal "1.2.4" - web3-net "1.2.4" - web3-shh "1.2.4" - web3-utils "1.2.4" - -websocket@1.0.29: - version "1.0.29" - resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.29.tgz#3f83e49d3279657c58b02a22d90749c806101b98" - integrity sha512-WhU8jKXC8sTh6ocLSqpZRlOKMNYGwUvjA5+XcIgIk/G3JCaDfkZUr0zA19sVSxJ0TEvm0i5IBzr54RZC4vzW7g== - dependencies: - debug "^2.2.0" - gulp "^4.0.2" - nan "^2.11.0" - typedarray-to-buffer "^3.1.5" - yaeti "^0.0.6" - -whatwg-fetch@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" - integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== - -which-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" - integrity sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8= - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= - -which@1.3.1, which@^1.2.14: - 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" - -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" - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== - dependencies: - ansi-styles "^3.2.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -ws@^3.0.0: - version "3.3.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" - integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== - dependencies: - async-limiter "~1.0.0" - safe-buffer "~5.1.0" - ultron "~1.1.0" - -ws@^5.1.1: - version "5.2.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" - integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== - dependencies: - async-limiter "~1.0.0" - -xhr-request-promise@^0.1.2: - version "0.1.3" - resolved "https://registry.yarnpkg.com/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz#2d5f4b16d8c6c893be97f1a62b0ed4cf3ca5f96c" - integrity sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg== - dependencies: - xhr-request "^1.1.0" - -xhr-request@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/xhr-request/-/xhr-request-1.1.0.tgz#f4a7c1868b9f198723444d82dcae317643f2e2ed" - integrity sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA== - dependencies: - buffer-to-arraybuffer "^0.0.5" - object-assign "^4.1.1" - query-string "^5.0.1" - simple-get "^2.7.0" - timed-out "^4.0.1" - url-set-query "^1.0.0" - xhr "^2.0.4" - -xhr2-cookies@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz#7d77449d0999197f155cb73b23df72505ed89d48" - integrity sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg= - dependencies: - cookiejar "^2.1.1" - -xhr@^2.0.4, xhr@^2.2.0, xhr@^2.3.3: - version "2.5.0" - resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.5.0.tgz#bed8d1676d5ca36108667692b74b316c496e49dd" - integrity sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ== - dependencies: - global "~4.3.0" - is-function "^1.0.1" - parse-headers "^2.0.0" - xtend "^4.0.0" - -xmlhttprequest@1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" - integrity sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw= - -xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -xtend@~2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b" - integrity sha1-bv7MKk2tjmlixJAbM3znuoe10os= - dependencies: - object-keys "~0.4.0" - -y18n@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" - integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= - -y18n@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" - integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== - -yaeti@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" - integrity sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc= - -yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - -yargs-parser@13.1.1, yargs-parser@^13.1.1: - version "13.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" - integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-parser@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" - integrity sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo= - dependencies: - camelcase "^3.0.0" - -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@13.3.0, yargs@^13.3.0: - version "13.3.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83" - integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA== - 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.1" - -yargs@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" - integrity sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg= - dependencies: - camelcase "^3.0.0" - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - 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.2" - which-module "^1.0.0" - y18n "^3.2.1" - yargs-parser "^5.0.0" - -yauzl@^2.4.2: - version "2.10.0" - resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" - integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= - dependencies: - buffer-crc32 "~0.2.3" - fd-slicer "~1.1.0" - -yn@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== diff --git a/lib/v3-core/.gitattributes b/lib/v3-core/.gitattributes deleted file mode 100644 index 7cc88f0..0000000 --- a/lib/v3-core/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -*.sol linguist-language=Solidity \ No newline at end of file diff --git a/lib/v3-core/.github/stale.yml b/lib/v3-core/.github/stale.yml deleted file mode 100644 index c94c52d..0000000 --- a/lib/v3-core/.github/stale.yml +++ /dev/null @@ -1,25 +0,0 @@ -# Configuration for probot-stale - https://github.com/probot/stale - -issues: - # Number of days of inactivity before an Issue or Pull Request becomes stale - daysUntilStale: 7 - - # Number of days of inactivity before an Issue or Pull Request with the stale label is closed. - # Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. - daysUntilClose: 7 - - # Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) - onlyLabels: - - question - - autoclose - - # Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable - exemptLabels: - - p0 - - bug - - # Comment to post when marking as stale. Set to `false` to disable - markComment: > - This issue has been automatically marked as stale because it has not had - recent activity. It will be closed if no further activity occurs. Thank you - for your contributions. diff --git a/lib/v3-core/.github/workflows/fuzz-testing.yml b/lib/v3-core/.github/workflows/fuzz-testing.yml deleted file mode 100644 index bf3892e..0000000 --- a/lib/v3-core/.github/workflows/fuzz-testing.yml +++ /dev/null @@ -1,60 +0,0 @@ -name: Fuzz Testing - -on: - push: - branches: - - main - pull_request: - -jobs: - echidna: - name: Echidna - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - testName: - - TickBitmapEchidnaTest - - TickMathEchidnaTest - - SqrtPriceMathEchidnaTest - - SwapMathEchidnaTest - - TickEchidnaTest - - TickOverflowSafetyEchidnaTest - - OracleEchidnaTest - - BitMathEchidnaTest - - LowGasSafeMathEchidnaTest - - UnsafeMathEchidnaTest - - FullMathEchidnaTest - - steps: - - uses: actions/checkout@v2 - - - name: Set up node - uses: actions/setup-node@v1 - with: - node-version: 12 - - - name: Set up Python 3.8 - uses: actions/setup-python@v2 - with: - python-version: 3.8 - - - name: Install node dependencies - run: yarn install --frozen-lockfile - - - name: Install pip3 - run: | - python -m pip install --upgrade pip - - - name: Install slither - run: | - pip3 install slither-analyzer - - - name: Install echidna - run: | - sudo wget -O /tmp/echidna-test.tar.gz https://github.com/crytic/echidna/releases/download/v1.6.0/echidna-test-v1.6.0-Ubuntu-18.04.tar.gz - sudo tar -xf /tmp/echidna-test.tar.gz -C /usr/bin - sudo chmod +x /usr/bin/echidna-test - - - name: Run ${{ matrix.testName }} - run: echidna-test . --contract ${{ matrix.testName }} --config echidna.config.yml diff --git a/lib/v3-core/.github/workflows/lint.yml b/lib/v3-core/.github/workflows/lint.yml deleted file mode 100644 index 942d420..0000000 --- a/lib/v3-core/.github/workflows/lint.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Lint - -on: - push: - branches: - - main - pull_request: - -jobs: - run-linters: - name: Run linters - runs-on: ubuntu-latest - - steps: - - name: Check out Git repository - uses: actions/checkout@v2 - - - name: Set up node - uses: actions/setup-node@v1 - with: - node-version: 12 - - - name: Install dependencies - run: yarn install --frozen-lockfile - - - name: Run linters - uses: wearerequired/lint-action@a8497ddb33fb1205941fd40452ca9fff07e0770d - with: - github_token: ${{ secrets.github_token }} - prettier: true - auto_fix: true - prettier_extensions: 'css,html,js,json,jsx,md,sass,scss,ts,tsx,vue,yaml,yml,sol' diff --git a/lib/v3-core/.github/workflows/mythx.yml b/lib/v3-core/.github/workflows/mythx.yml deleted file mode 100644 index ffe713f..0000000 --- a/lib/v3-core/.github/workflows/mythx.yml +++ /dev/null @@ -1,65 +0,0 @@ -name: Mythx - -on: - workflow_dispatch: - -jobs: - mythx: - name: Submit to Mythx - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - - name: Set up node - uses: actions/setup-node@v1 - with: - node-version: 12 - - - name: Set up Python 3.8 - uses: actions/setup-python@v2 - with: - python-version: 3.8 - - - name: Install node dependencies - run: yarn install --frozen-lockfile - - - name: Install pip3 - run: | - python -m pip install --upgrade pip - - - name: Install mythx CLI - run: | - pip3 install mythx-cli - - - name: Install solc-select - run: | - pip3 install solc-select - - - name: Install solc 0.7.6 - run: | - solc-select install 0.7.6 - solc-select use 0.7.6 - - - name: Submit code to Mythx - run: | - mythx --api-key ${{ secrets.MYTHX_API_KEY }} \ - --yes \ - analyze \ - --mode deep \ - --async \ - --create-group \ - --group-name "@uniswap/v3-core@${{ github.sha }}" \ - --solc-version 0.7.6 \ - --check-properties \ - contracts/test/TickBitmapEchidnaTest.sol --include TickBitmapEchidnaTest \ - contracts/test/TickMathEchidnaTest.sol --include TickMathEchidnaTest \ - contracts/test/SqrtPriceMathEchidnaTest.sol --include SqrtPriceMathEchidnaTest \ - contracts/test/SwapMathEchidnaTest.sol --include SwapMathEchidnaTest \ - contracts/test/TickEchidnaTest.sol --include TickEchidnaTest \ - contracts/test/TickOverflowSafetyEchidnaTest.sol --include TickOverflowSafetyEchidnaTest \ - contracts/test/OracleEchidnaTest.sol --include OracleEchidnaTest \ - contracts/test/BitMathEchidnaTest.sol --include BitMathEchidnaTest \ - contracts/test/LowGasSafeMathEchidnaTest.sol --include LowGasSafeMathEchidnaTest \ - contracts/test/UnsafeMathEchidnaTest.sol --include UnsafeMathEchidnaTest \ - contracts/test/FullMathEchidnaTest.sol --include FullMathEchidnaTest diff --git a/lib/v3-core/.github/workflows/tests.yml b/lib/v3-core/.github/workflows/tests.yml deleted file mode 100644 index 89567f9..0000000 --- a/lib/v3-core/.github/workflows/tests.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Tests - -on: - push: - branches: - - main - pull_request: - -jobs: - unit-tests: - name: Unit Tests - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v1 - - uses: actions/setup-node@v1 - with: - node-version: 12.x - - - id: yarn-cache - run: echo "::set-output name=dir::$(yarn cache dir)" - - - uses: actions/cache@v1 - with: - path: ${{ steps.yarn-cache.outputs.dir }} - key: yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - yarn- - - - name: Install dependencies - run: yarn install --frozen-lockfile - - # This is required separately from yarn test because it generates the typechain definitions - - name: Compile - run: yarn compile - - - name: Run unit tests - run: yarn test diff --git a/lib/v3-core/.gitignore b/lib/v3-core/.gitignore deleted file mode 100644 index 86e6f21..0000000 --- a/lib/v3-core/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -artifacts/ -cache/ -crytic-export/ -node_modules/ -typechain/ diff --git a/lib/v3-core/.prettierrc b/lib/v3-core/.prettierrc deleted file mode 100644 index 31ba22d..0000000 --- a/lib/v3-core/.prettierrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "semi": false, - "singleQuote": true, - "printWidth": 120 -} diff --git a/lib/v3-core/.solhint.json b/lib/v3-core/.solhint.json deleted file mode 100644 index 11b3647..0000000 --- a/lib/v3-core/.solhint.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "plugins": ["prettier"], - "rules": { - "prettier/prettier": "error" - } -} diff --git a/lib/v3-core/.yarnrc b/lib/v3-core/.yarnrc deleted file mode 100644 index 5455c6c..0000000 --- a/lib/v3-core/.yarnrc +++ /dev/null @@ -1 +0,0 @@ -ignore-scripts true diff --git a/lib/v3-core/LICENSE b/lib/v3-core/LICENSE deleted file mode 100644 index 075a13a..0000000 --- a/lib/v3-core/LICENSE +++ /dev/null @@ -1,100 +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: Uniswap Labs - -Licensed Work: Uniswap V3 Core - The Licensed Work is (c) 2021 Uniswap Labs - -Additional Use Grant: Any uses listed and defined at - v3-core-license-grants.uniswap.eth - -Change Date: The earlier of 2023-04-01 or a date specified at - v3-core-license-date.uniswap.eth - -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/v3-core/README.md b/lib/v3-core/README.md deleted file mode 100644 index e4d12e4..0000000 --- a/lib/v3-core/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# Uniswap V3 - -[![Lint](https://github.com/Uniswap/uniswap-v3-core/actions/workflows/lint.yml/badge.svg)](https://github.com/Uniswap/uniswap-v3-core/actions/workflows/lint.yml) -[![Tests](https://github.com/Uniswap/uniswap-v3-core/actions/workflows/tests.yml/badge.svg)](https://github.com/Uniswap/uniswap-v3-core/actions/workflows/tests.yml) -[![Fuzz Testing](https://github.com/Uniswap/uniswap-v3-core/actions/workflows/fuzz-testing.yml/badge.svg)](https://github.com/Uniswap/uniswap-v3-core/actions/workflows/fuzz-testing.yml) -[![Mythx](https://github.com/Uniswap/uniswap-v3-core/actions/workflows/mythx.yml/badge.svg)](https://github.com/Uniswap/uniswap-v3-core/actions/workflows/mythx.yml) -[![npm version](https://img.shields.io/npm/v/@uniswap/v3-core/latest.svg)](https://www.npmjs.com/package/@uniswap/v3-core/v/latest) - -This repository contains the core smart contracts for the Uniswap V3 Protocol. -For higher level contracts, see the [uniswap-v3-periphery](https://github.com/Uniswap/uniswap-v3-periphery) -repository. - -## Bug bounty - -This repository is subject to the Uniswap V3 bug bounty program, per the terms defined [here](./bug-bounty.md). - -## Local deployment - -In order to deploy this code to a local testnet, you should install the npm package -`@uniswap/v3-core` -and import the factory bytecode located at -`@uniswap/v3-core/artifacts/contracts/UniswapV3Factory.sol/UniswapV3Factory.json`. -For example: - -```typescript -import { - abi as FACTORY_ABI, - bytecode as FACTORY_BYTECODE, -} from '@uniswap/v3-core/artifacts/contracts/UniswapV3Factory.sol/UniswapV3Factory.json' - -// deploy the bytecode -``` - -This will ensure that you are testing against the same bytecode that is deployed to -mainnet and public testnets, and all Uniswap code will correctly interoperate with -your local deployment. - -## Using solidity interfaces - -The Uniswap v3 interfaces are available for import into solidity smart contracts -via the npm artifact `@uniswap/v3-core`, e.g.: - -```solidity -import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol'; - -contract MyContract { - IUniswapV3Pool pool; - - function doSomethingWithPool() { - // pool.swap(...); - } -} - -``` - -## Licensing - -The primary license for Uniswap V3 Core is the Business Source License 1.1 (`BUSL-1.1`), see [`LICENSE`](./LICENSE). However, some files are dual licensed under `GPL-2.0-or-later`: - -- All files in `contracts/interfaces/` may also be licensed under `GPL-2.0-or-later` (as indicated in their SPDX headers), see [`contracts/interfaces/LICENSE`](./contracts/interfaces/LICENSE) -- Several files in `contracts/libraries/` may also be licensed under `GPL-2.0-or-later` (as indicated in their SPDX headers), see [`contracts/libraries/LICENSE`](contracts/libraries/LICENSE) - -### Other Exceptions - -- `contracts/libraries/FullMath.sol` is licensed under `MIT` (as indicated in its SPDX header), see [`contracts/libraries/LICENSE_MIT`](contracts/libraries/LICENSE_MIT) -- All files in `contracts/test` remain unlicensed (as indicated in their SPDX headers). diff --git a/lib/v3-core/audits/abdk/audit.pdf b/lib/v3-core/audits/abdk/audit.pdf deleted file mode 100644 index d851413d0d76e3dee9559ebad2837f438bbd9858..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1149996 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

?#Z?3Orb5x7fa+ziBdU54L^8S8(zgpF{ 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 z

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

H%6RQl>Hd%ArPn#(VL38|se`Eo#gjwB-R#x6HCK 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

-$ zWgL!e-|r8HI7P;KyyEbR%Df-4FgsY{+mL}OL8Mxc2uPz*5&L(|d%Yr$c zuu(a?Hm9i_`mQJ9>!BSE{j~2!?b#qYkCpbKYT?iUTwUVuP?ja9;O*J4D z_0>P#-)ik5P9yB>vp8crABJgQ@i5!B-N(=OpC1mxXd95SNJldL*DM0GzD)rzl+Uuh zL*yk7CYy{Pv&iMa_yFw!@fNVliGQEM(maRD*pr-w3xVZ9O3V#;XN)&-9?P5~0_Pcr zF1Cw|>0e0q-<78Z)ib2o zFr};<`R7ORbq@a`hsqL7#CFw<$>sCbQ8`<^c&-Hi~JmTt!kl`)73jKFC>n@GNZn>9FrVN`p?3!v*vu07`L}6O?GtBciO%OwT0~o3dIpg( zv9xKSF%J$&P@4qig^@VJ(e5RY(g3!BU`f)^n@->pYj@U~Y;$(?%k|a&^w0P2ZmyfE zh~v<8U2vW_QF-9_xoO@X+JAlg^x@;@hjx(En>v&?6&iWd(~(is(VI=m94B06;B_4K z=GlDwPeP;>jzLMQ7UEb+?wDMSdmcgJ^uP*(U5Ku%yz)K1>bTr*>cHDH}`N_o})en=Xbm7x~_LS zLQB=QjuAqz9a$4+;OzHzcXxO9_nf&ALpL!dNUqYTt7b}2Ik8i$U=3((oiT~PH7Ixx zk7_+(V<0A>vN5W_W0Xa#(|gMajbYdM5Zv+OHh^5 zvNnC#rk;7Wsf7+p1%>s8KL&C#h@MLDlp}MQp8r_lYpCQuCoa}qq<#sQV_vgrp`3KZ zwblZSsgr1k_h!jP2*@~+Y4LEqq*{m@5S7f_s1aFpND1m4JzS@(UY#7G_!~Em1)84q zzVsZsN4wA);&>&(++~p1VT`)K9+P+~o2ajAhVhmCm?TcE&Dq#Fi}pxq;ymYhzO!wz zWm(SijDvF94#PN@z0eB4Oil_R_aQWe-&CP#%1vEX1$!-W6Cqgvnd3Ok-7xHr{ju$i z-E2ek{2KVY1kPrT4dRbARJLGas!Xp4YEjYD>@^ce$UYOCxEE;0({S^1)|-B{qBkPQcv+A=H7*z zhMQ&@k^T}ds21dJyMn+InT$_N+C!<9YVq!B`#=BlAMdVrO;u*|I1Zh9v3dOaVVdvv z$N&29@z)QZ_Bi0N9XUrGhDD2_U|)l&)=26zGNl%>%)DS5apFA95yq#3(nlGM_&)icHR)i zC)TbuEZE3^&!o$;sw&^z-dAvEd^E%VIE<2@ZLh`b9lN&yec9@MQY}<|>8N>5 z@1y^p&ac$3Us5gj6;drQy@GUM7Xyx4*&LAOp(L)PWW}Bg%dxEMs;Mo2H5%~HlC1Hb}OR*FyT64TT5|2Vy1O3t1OgZZMC9HW~_X+w?*LBr?3@M$z zk#LbFY6bnItFa(Nf->Z zlpL%}36I!9hbo}D@v;f{dQH!CsQQ29%O;vbL{LqJo zhvV@mQmATFz}&ZJ%{<>Udqh<3Ey88mQ|@7|SV`RViL4|n&6 zZs6$cnQo~5$gmbJ@xxw)mBubD}=EypR_aP@rRns(8QC?qjtULF0mFJw#IZxSL+a9~&cs$DevTGSn#$iOG zfY;sWzgU(meiP@I^FaeFkvUUF=V2Hp4)2?2VV5!7Q`9FQHHt=o*UTUvxuPf(QA3ua zCtto1XfVSaVSg~q7*CfREmz%(l)6vFNPm)z zu{DyJV-18^mLU2b%>t_%KWR$N^L)GA?snU%s-_8VZ=yMM9o{5LF-F_=WSR1E^49ezc)@3q0S*mMFX_D%*#~^@<)(2xKs@IP6-k?$Ym8L zb8p_?-oC%Rs*6zPep459SyV+aj$=2DZ9laAeCWqdcMqRF-|zSPVH~{obyZmuA)NP6 z<21*%9lBxax}N2=Vd!lQgXsssmoA&}I>prA&ra?HPqU29)h~D+koxj=9i~NTi7c4EwrW9VbF= zq!zW&h13L|8cdFN@QeNF;;iPi7od4zxrf|Wd9mSSjIG6$s`5}2RXxRQoTk3-+O|C& zj$Pk<{`^_1D{2J|)KwLVDm3+`s_HxxF=n$3XyY(<#y4HZseKr#FrQjcR#0WBh~v8M zn<9?Z&(|&fwh-?rcm6RxoL{F}s1~{!>%_{q!A5KO9fR;eexQRjX~5_f|ecmzEv)% zjebsujAsz3UjpWsw^A+WT1Y!ygQ?6yG`p=2V1f#CJY-EGx=vy~J|lt%Upbo$bVc5Q zHR*?{BtKhHQW*51ZHHKr@(UaDre-N=HTp_gwG0VxpFvrusEL#87Xafb8%y(a3lr;J zMG|t-CKqMuPl^SMV!>>nPwuA|A! zIYjnRRg+@im7dqgi0t!jTMpsHUP2n$ zo3i^udw2h^zxzB*BL{Uib;G`(x~WP!DcymN9V3THa1zUqbp#aZ?O11)FuHL>!?!ap z;CWMj@OGiBj}ZT;hwA=xWwkJ=7U>0g&>2{@pxe+F^1LidZ^t{zMN^=COt)dxg0b;! zfxREU!BeUzo{8rev7pmD6~F^(eDuGCw4jWz*Da)dH1?K>$IY7!otE=mR0J$apTC@XT*|zKU`~6|h&Tq=;;$~A;HG@@EHF?Nq^O}ouHcqkc z`r{FsNPA@595Odk_BvXN^g)4-4x0|TAJmV};s_I6;vH;A2V&|`pI7v?Lu(aNX7 z>z;uA|<64am|UN-9CoSyw%OO%}qs*gqRC)?K8237Ey-P_^(G{xBL$le|vL z+ty@Rvdx)i8fO+8#0L`n^_qCXn35Fqr)r|t#L%|o6y7x+<_0O5369j19j}@djlT^V z+|fq(VgVLG$VduyS>EDbW?*haP+gawZ5FpwDNL4SWx&| z?XGrpRgF_T+Ia!PfLXD_`IyR5AYN2PgqtivR^+}c@-k=1!mhawM7f&4lp?#DdoA2p`lg0hHUBcW*a1)jr^B(sAqK@7qxuwCx8OKEeCH$m4JE_=H6-$?kor?sdo$>p zgd|)(0W3-!GYt-6PBy-uFxxOfAMhMdGru{DMw*^8ILN~>@;X*BIYs39I@b|5cX!9* zzMb6Y3R3_~ggy~=PYGu_)FSYG?w~0pG`g+ zSi69_`ia40j(DsQ0N3$@4V&{g_3ZNrfs|n(MExQUSU%7+vOM_Q&f;mxvSu3wJW^Kt zmls7a?XJTza_rGGhj|{WnpjjhXZsg6m5^8#{XDyY-5T9~e>m)qhpubKX`nDqkO<_8PWFyOt~ZC8SGn`gTdZ1$^Hq^_RTe*te;)<@ytqh{L}#_8YNvHNMw-u%?x70 zxSqcz3*qH0^4G(~y1%^bnBd+_wXoSqbGGyc6;5m?)2to0#9q;1#Fi%YBk2sOd0a)_~mw&9Wkg*iP>cBV3qzyIv4f<^);q^n!AcIgmLS zgDiRR$T>p4lPd)@cP1pNEKVpJ_Qs|zciUZA7A=8XIf`t;J)l2!_!?0#3csYruGr|j z&vNgI5~ZRDzATH<9F5`(>3a4_4@WyGkLaHf2ajn&2hipgWJZj&9y{`8>%8l`?szzK z$HO#{qbRQ`%jzIuD@G!aa?moTUUbLfVHihmD$_Kt#=(YMvPg%d%uw z`9P`EG)D8a>GrPx*cBn{8!%~(%?xMnscW1Cu3?Rc$Xie>fj`{hk)pP<*a_c=5OrcL z$B8W~kzHU2z-7rYj7ZdVRc)Ki?e)z+-rtr1{q}lOZ|Wi^0@ZvV9N93;uAj2c5BpCa zKlRaIFb+ZO_LYiHM4)s&xu_cAXbv&F$oXl)Jk)=g?NwA)T-h-1Stj$lhZJJNs5^;`k z3WSSgnDCBar>d&k+uOzty5>~=2hKhpqmOw7qZo+JWI(<|t9Vo`?01eLfer@l3{}Os z=^A0CiDg4RH=I<9g=nn#;0dSSyw7Hz4K#?c26Qv>5-%JMa?rAb)Yb~&p0c9*Mx`7y2 z*DrzZnFyB8^_tpFAL^Rk`C+7VegdeO;G(bNB26x~h?;l}r3}NFbc?8gvdx>uy$heL zvrx(j>z}?3O}j6`V>f>@;J#}0g1MQ3fa+_55Kw03$f?^$oYndVKz;`G0wtKpE;8!j zE1{%*PF$?}%c%;7{KtR$f8K_6ZX$|e&hRbyTk@-#A4@g?Ras1MF6;V^xoBP_PH!E+ zW*2H?Cb6Y%Qx?5gn1C}bcMK5DVdjUKPQ6#(BF7uV@se@X+f^9dCj!Ctk&Comd+tu1 z1@MD`KTgAa+L@rLVFz`t@S$)%3lw&C(L@Ifcy6AvIB%-@YPYG2GRxfOw%hkZYi3&u zQ#0bp#J&hDgCvT55aEZEy)%mX+*W=(WL z;7hhl)McJ`U3bS0(e6~^M^FdzpwMzqmSs)TY;e+uELjW~`3MVPc>L@UF=n!fKEiu% zDc}>O?WFc~_;(C;zb}?uCNIE6?Sih6(`#1V{{$Q}Rs9^|b3KKg#5m3h<2osa;&8gr z33QXlN+3e`0?oBgK*uxJ#G)wbJiNcT`sMa|x2elKl({d0@y9$5F;24^=j_mSpY9*- zA2=p01Yei=wyAfUrm0Yaz0XSXiX)Ef#5ouvN@=jY7Hr+wAKU$recfZsIGd8gqLBbq zYGcygYQ55q$;gLAulc;|2sM)+JATRqpvf%wZ4L-*0c6)Pk z(`>hMjCc1BAMfsa_9*k>(>_Lj`~ohwV~kpLthHO+yeOIl@9B#c5Gw4MuWf zzsG{;6VpQ;A7%`7>kk=6^`;2Ts~R@viILH}+&f#xfaB|`sLK3GyD~NmI8{|xIAQ`} z&m*D7#$o7KBtuS{r>vi*V>{eGJlwNzF?4fOBmk;rb{WbvPxCa`iZSDH#0ik`lp)TJ z0pZwqhxe{Je!!(}DG9IO|bz{ktMolQ8Kl#UIw-f!JKo3)Py3zFv7a!{L zGhBQ#mGH-KG0oo$EOgQWOMPK63@2DlR4`rPR|vn*{1J==%U_Rg@)Rb~4~dd`K@vrR zWPk)UsNPH?usvihSAyTfYB$uk@Zv!)b6*)fz5|IGMpEMHpO~ClGyOA!0)_yS%CuCt z{_qWfXk@ldr76Y62u=Ygkl|wP>DRyUCb&$`7~fE}m@!$ge;FVvPbU4_Vl$dkymb|cO%j9joPX%?tPUVPom2}uCL18r+W3-KO&N)$QX=GZvL*1D@t@w&H6^kJ zPc3oXqvwh!n{c)IkW-mTxz0xu*ioB^Srt6{@hwgAV z9FJ{3vA0{}a)O8e>D^M<&1O^A%`i;ILp$2uV*Q$4cmjt-_Q?~YTV2;$2BDgkh|Oov z=Ba~^vFiMi%g!nzZLqF>@tbkON)g?{}N`H`h12ZBv(Zk$VTfq5ra$;>S6AI2``<@$=`q{W#4&4^35E zZ|dEKh*G)Fs=}7qiXvmJgH7DioDCK(`Pg#$%AxJ{$G+{man7bGPA1q#=VN5~!r560 z-vk8382Qr4TSP;eHdjgf{xf18$oXC~;=d29T4V&O%Hmvx{OW4E+wMY9cEj-L{&2rP z^n`(DFBb~gb9v|j=IjfigQ6*vWf>#K!}Vw_i+HGiHZuAvDZD$iDu5IAN> zO6hjDx!&!z+f7|>IGoS97$?s@oj4A|p~Zca?H1#F?1s;G_n+<_9**5G#Suf4j}BFQ zvZ}E>k_VT~aUL_R*i0PtSmF`N2C#k{jLfW5*&5CQGdVK0x^ z%-l+lf9zv*6W#NVJ=B$SR?wfiCfMhJS6_fXvT9)!S-P|L*ew$^G{5L7BqF4D-WE#M zGwD$zWjdeq8Rf1VQ%kM!*Xs_yFD}#bEmaE>45V2|Nnoxvh%Zl?MR1t(;RiHbJZz9{ zL>>O2-@_U33WKy5Y2hS8HVk&gg2}JwF~(#P6cRI$s!gj(S$~S{=2;eWpl=b;0z-f^ zX4Q3#HTe+!n38~0DO8IP3LlWW7@)AAg^-na4Exf%UDGsW6_6dLPi-gFLe4_Nhzd4E z1VD^}m`;7cJLzDoTHqA-4C+~WOj9{C1JkA8WHr-zlt;3GvkZ3r$a5rS z77tJ!mtEKOyPMtZ&CT_0)09QTuYQ@Mi1zJKh+KTyZ-`b4B&Lq*EWf{#S*GF+q>yR$sFx-74D+uPfltDUWr;Z_^+ z;7SWyVW+1ProvV+;<4*Le*XOHC(h#Qr^v|35`-PRk-5GfSUmSWi&LBiazV}T=Ap@n z=55yw)5u5*=R9FDj5DkQy?~t}Yzn8^RCNY*%+ysC6+q3ID5Fky@k90EbY0(k6BnB) zWxB@2hkqV8`o4(oOu%4$0Ma>!eMC}&RcA3KG7?g00ck~6OM3@cpQF{DgP)&bekRDO zFzI@_$^2<+;y3XJR4r5sF_p+d7>q!a4pm2ECbT^fM4#}_Nk-C}ZwQq{lAC(Rx&V5j z>{RkIsDyvxt#Fy1Z>d_)!xz;;6N%VPR}(AEyBQ-q%h7mB;9iZ<9_wtRh{)8|$N7VS z!?sYsKRjiyX6(<#ageB;AXxzxdy2JN?HQk~zZIU-dVbbn6uVGTxJcu*Q+ZHTtmp(|Awhfz z6hcQE!TWw_$Ei1U32M)FpmJ4h@n^2H7>BOgA0FDn5fRUM9GFGZ6Ug*55O_OExiSl1 zd+ghm0JTt_<~XO}0-B!j{R~P<{>^>QVa(=v`~~CrpA*RIm^xnqYM#zCNI;aQNyDQ< z6cZml_Gir`u8Y!uE1TuD6#t|bWa=W}X@ZsZUR=|cHZ#wo^P${M!j>H>s@9MJH)MeAuMP7POu&MoF|FC~(``$R& zbH=IlH5HQn$SuR%)c zuLDOclL+8{cph@%7RPYPBEK!|1Bsp5pExb{1N4$bwK%CHnPYYJWp+TV$ zgf)3}zq)cnm0tTM{>Z9DLQ*XjvPJ~FcbP@;a z;DrQbCop-METamOxJ@~0K9iT;8Y$&7?qpr%G^yxDSEaUAEy@sb6d@Z+g3pUk5E=#B z?WQg_WtDq34#TnS9{TApPTFgMm3o@S5r-(On%Hgyx{peTL}JA<0+L{kjz+DtO|$QZ zeu_iPv}YrCSyd6ev92qZMLey$ZV{bWwutG>y99`JQY{E4RaIrlwvgk2^#+L}Rs_nB zzB+;S!HUGq6F57bOndjWnHzTlEd0+C`LhDmf^PJp@@v2Q*{jTjXQ~Bql7HSz;<_~l ze&4DE(h!N9AzHIawNMtQ%6ZsrHn+Do+fALtxo_KH>~UhB;~e9R+Y%+2v#f2~;C-2g zZBt#b;k%?S6rR0RfoYZZ&D$??c{hx0*By>HL>&)w0#pk&Qb##1EUY-6``29rwqqAi zFkS%B4bjtjG#$*eXi2>zUj4+DctJ`(0_PB1ea04)tKDX|+vR!a`{ChXf4}EIN_=KK zb-}1l32BQL;Jm=9msVDFf`^uKIYGw`nW3c}d>}f!5c=c{nC+io{bst?z=jBD>ukYR zVqJ{6_hpqgRlRAd?Ph}mC%bz*3)>lc)!5@>qwq{?2cK6igL}p3_!>mXlmef7}SRc`>C#>&hvpEXuhB&*obQl9) zfPmZ1I!Y6?s_}RaulpD2t-0in=U) zj6>h!Vm{1AjEL;xMzw$f^DvE)zyR5iyi}k_NG+@`mKUl;5f&OrwZOA#oN+9%@KAMC zaujY=xGd{B4yYQ2f#K6O;^Nd|o8Z<^#YLQ)6D?}#L`gl=Aj`hk7dk|JRkcu>>ZFBd zr$o~&FR3CFb(bvE7Ijk15WG^&|5=@mUQSE-T*#a$$xz{_R(>9An+Ep1Lr+btw2#A((Z* zocR1D34RaID{Or!G);4JeO1?W*LVAe!~VcN_z8UgAwk~0KeqwMQJHvQ*!cp^-xOD9 z7)0~T^QzLB`i~V97bTOy592GUg^D4NzT;{E&3u9UM^NsvD00tgFTQhSZn4FR8jDO8 zXCjBOyzLp~20Q=6`8@M^<~*nG;f7bl%yopa=#PEZntnmpiLR}S{Gb1Le|xiI=pnIa z6H7iuwBrK@$$z-Jf0#Hbm4adJU=(9b#Wqmz@GG$O#LN9jRTkhn^zdw&nX)u;>M9+c zf1V=Ata@#IJ%fHa!^@^R@r(Easurq+nAsaW;oA(o z&c+X`U8WjXV#f33LU9nIP4II8npcVUEF0 zx!djPx(*(5^5MX`gJcLCn7toIPQxIFXHa;kJV&MsAq>ORnbQ^#Yy-_9f?VJv+rj@V zJrZ0*)uLeUK9c0f%zeo&_$LMWv>BOS0AvwH<)?su&Q>kxm%rUM?gZ(O>V9Qj)Md44 znmNw*cXx-w9yy7whkLnmh=f&D6$L?lrg3x}ZQ(Z!;R>pPLkseN`#XBY6vxP7+5XT@ zW+s>?0{h@PZ`1ZL*r_Zw-)pRhwx&Im%(P=glgw(vQb6U$7I^ivds7sZWq3p z;P)W0bup>T_r`)9P-`Nh4K^ zP6LhxF@@QXqV>bLs9I>05N#!nIJZP}z}Dc|1PZ@<8%WuZ3#mgOa#U61Tf!V?1f+{m zMkWg$fb2KTS=*0CI|*oxt`w@KEGw4>Q(61&cpSPm*g20y$Yyh$4S@iAHquU^Kq2{b zclZDPfB*S#I9M0}7DQlg=VHVqkK9&JEmjYJ%jQ5-BJLBYp-l>6Gs!xqWI?pbibVYV z6zi|_t$x>6XOPHyhKp}re5fw)!?>9HZwJl$L|^3Oe%LAaO(_S!vawb7lfi}7#Amo~ zkG5C}pA5vT!*SVh78hjq@EijQiF_TOzX&XUz6>u< z^Ag0*f_ec03EP_(Tax`kqs>J&dviSRUxG4H8FanW79jolH{Jx7>G_tb1>-ZT7OCyU za9Wz5=fz~mUJLvXa`rwmv+-IHT<)0TtFoxfltmoZ;GOfxCFm5GHv4hxu{p2|jnfFi zE8+{jL=k_A#AK>%x~kjrk3j{aGaGa>o7g0z@j~kcdbkFKK20Isd!M;%{{Pu~6Xi&b zBkwbgyy^g&lr$W1G?YHsxBI~R82b?W9&5I?_KnSIL`jq=b^~?f6|wg7e^z#(kZ4pl zAT>4OpHg)pD>E_<4-a<_cMm)b$^xrN(===JiUMcf)e4sq=X#UVyMEaB>Clg4jBTgn zvz&HE79G?lYGmy~dW+FQJNnTK!&2Ldh}c)7VU#2T?fbUn$h?$uEDAfYtj;+fkCR@3 zC~wupP-sbn*!sb{oqx}#pLhp)(Q0KSbjQO&rrITB=TR&#e$wk~8;8{O29prF4;Ha#s;Vr@&1Ox;5SJYy zvTGpwN*i|}#3AM0&UR$-Lhp&`JdQNcW)KElYt}%H+5wk^VGMbit*Sh4HG-iP2GK42 z;dHplr(xc>z)oTQnM$?%X{8Ao7uAsEHzo4|%5@puy!m3g-8vr+hr`|7-R_8>!>z_W z`2g3-BF_RdtRaMWb8}<7f;Z0G_%x=^V}4|wvsfI0^T}A2SuUYM&t8OzLy<6q7^`Mw zT}?XdK#+y8WEeY0BdKX|oh*u*O|!0y2m^_Fy(1BAjA2OW(002+d%r)LCtV*-GBPX0zEeO_PR!bjf8bd~#!d+~2qDkw70dm3_*doi6XYas2Mj-+%juKOWnzsB2<5 zhS3)h|GFi)Z5~qrYIF|O!m*lYto3=ZWYAED*Ud~)n!>vIqFBg)$$u5De|B+{7hkk^ z@o(|?A{O8N6eg0R7g7-;K{ZXiv7G5OloVrda1q<1&(8G&2^IIpZnxVV+AbyX+M6RU z(@kfO+k##VzKf}f=5`qa}kS=FXH+#5j0-!Tnnr-8uVZr7pk1hkn_r93yd$Tf^X&oRR&*j zoKdJN(p(~y*yAb$raxxtyG+0%5+kCOnxA}33O=D<0qfo%$?Ru@eC zyvx+l`jl{g{;P1_OwBr<5(YW7qN>-nYhkg}>!z_3klnHG`feC@eLD6dTeBUC5+B2O zu3BIdCanY|+lDOR7;M$sj!;v6qaffVA{;kan(f@;CMT;8?FCV7ZBPoD`9-f|?&{do?NJ%f&s`91y5(A?DM zt1?B1>$<5|P0D${KkWCU{?u(0L>)-jz@9}>uGcH}&|>h3H-zBog3}TS*YQY%-H2V_ z*hy^wrZggmLXaHU0+M4Z17GMd4P8rr8KLTpA`<@L?SRI5kB)Nn;{6!2_^W^f9bY}a z;?tmUnJYYwqnQKzwyADzZ|Y{%59$8?{{Fz8AeNW2*BEWU^v2rgP&R7r$!FMriN!5(0>8SXb8Q_qSgUFpTYbVMjG(g%hJNHJU zRTM=T@g zy^n4jhZd?zsqe?#ffL{zdHhIm_UFI;@a-S|aJN5}b(OOpQsN08FSab60Q=>^WmuSJ zu%O@*)C1Nbx)f^lEifKc<00QM&tk&Rgt>ZzOZEwym7A&9TfX#+aSJn_h~44Anv-BC41_ zHKT=DvKo4L@=JT=Q=!TTDq~(I^yjlsOaDQ!Sb2@t1s3mI#Ny+NxV}t8nAcM+CWm`5 zR$(Sb@t2eM;v=!#7~pltG_rCT*~cs~$(KZ0z!3<}@^QfG$;nn--`gQu13794{bX5V zx56-FyoP2vlSHLY^@!@A@4|VXiUG-(#6M?FP-0|yP!faIPBn)gP;$KGQxA1fHg&yT zv2n2>s&!S@b}a6Iy|5p~Jt;WT(LAEekUw-iHr)Xg0@h|HWUynS-WvuYUD?)U!6x}^ zT}`Tm?P*|V9a9bgQ(ug+8wXPN?DxaKp0Dbb!&F-WC>eKp#=;|k8k=)2iekN9*LB@; zZg<=FY!F?6`7{Upo^eH)x_k%S}S}3p2(9GkvXuSRo(8zu=NGdat%rmfE zi_0#RG%qE#H={km^T+I3#E5-Y%Ygdx9P<=-YS%*j4^3ltrkuJcZ?~HmVoPe&{o&XS zq*h_$5iyAcm;|W`mn^FWj~jA)W;>q(ce~nrrJN5v@fBk?aJEU0Gze5B^cXfU38WS@ z5IN_=;UMClF}FyQQ51{YeIokyB~Y>f`Rqxxcoo8%<{iC`g<{*3Z#J9?=R&yOAMft& z_aw(+bX0ltK1Vc8^3p0_0W*K|o|C^d2kj&rj1C&{$FC75REO(VJ9ryI#tfcyWQ_32 z^=apX$i}Ij)OW1~&Jk8FTZSlH-vu2i;ysTPF|6upRab0?vHeBloy(a$UUG}|hqh~t zVY2a+h{wPxjWADOPYC{YyZOyGzxw)@UllHu!PU`R@T=;0?EduKcW>`^p5wpEc1+*D zefRAj|M>21=Zi9jXnwZrz2PLYgt;>X<}xXgxqbn4pnz>CxiO>DXCnrEF5&|}J%%{O zH8`)&jEm+7*I!($>f*&kh>#xt^tc2q=ug~fE_1=xMX}j5mS1dDkpteyi45)JEAtUA z)G?EW?%0j@dlDz?4_()f9VhM(bHU8BJq}f1uAXM`rY3-ZSyPLJ7-W9o;Y>xN_39gbu=QOI)7 z8A@z;vV)PvKH*xRML&&H*mFe(3kOLgA3CMOU6B>rv2e~PndC^5>vn? zj@6FCl{1QLQ50p}G<8#x^v$I-vR^*dbsb`nvRBU9VPFbNh$M8#MxXTo)uO<&MV>PT zBI7LvLjtJnbOAL)pHeN%m_ZJRg(h7GslJ76v&>m&_4aIn;6Mdm4*3x z2K?V~!(;Fx1ZQcr}%6QV6c1wtfxj(7Rjzxuate)Y>LWS_^njN8@f_U5J^ z(szIU{_Wje_A!>#nEhXVc>DW5{_*YIy^BQ-K4sHvNz}F6rT(-==nDtNGo$%aYr$i% z4CTx=Z6+Q|9jFSc2ZZx}z8LUDx=?#@N(FgH^r^9%rYv$FR_2 zsp=1Q($=x<&CE|E7DusWmqwS^rbD&RTQmn2JK};gRYTd=soO)SoEa)mvrZ4r%#?Go zaaD>{WH*1iUfpcgH=8vF5<9cik(>$jq8(g^c5#B7y*QGa`AfNIWwc!jvs4RqF%Tbv zIgb@}g_E&_b;<7D6Q;T6%x#>l5FBux4EOm@h*J1PzA-*0L-^C@@_kyiG4v2a1JV16B2P@xn5%-?eyo@>x|?w5QMDoxIW! z>^#!U1)wSe`Ii`}OR$VUay%Pj#HFArH+4O9-QE5E{?HmN`7xtfK$i}oEy`qA6rmsx zntW)HSV*0e&jFGl4r3xpgZ;RKo%ysrX<9+*2&u@XCDjM2jI3pFlZ0v^?E>GSJSoEy zFiOTNlg}nNUX?JYj-RZDOlS z^9zC4REtcI$>f^PyuJb|;Tf2olbZ&Yp`5c=kC`ME-lF!3y7Y;BWE5iK#pu{jIdeT> z^6I*79tO6p#8_ZnJ^oGu)19%KsF5fTO4T^>0+Z1JbY+Jhgo_vqVmzRGgRZO9Q~eF<1YLhc z=oJ@OWVx#LHMsuq#WEK!eiR^SlOoFCnO|F0+Xg2(Zz&UeU6TPmjj4zKAVnxi-Mjn4 zJ5G{099q&w4T;M5SRf5$hGwn?ukbG)j;m%U>!4qdK$fu-4z!5tV=dHJ7}g1M+l^*{ z2np8szLWmmQ0?ZoPW;4}z?Jx@n}2Lrto%Gu=UBXR5sQy6;`%cGCaQ&Kl(pxiT^QSZ zFXEtnc#BMkaV2}h&1O?K7^|YM%VO13by)>R+DcRlGkG4n{%|~MD@12Psb5wfdW7##LU}SoJZDXwrr(Z6h&2( zQ?AAu?Ly5NhGA!D=^Re~BGGHgBcqJln759wB_v@a|h!cI8GMXg@VqCNfL&(^VNE+Tctfv7u>f;-Ku-Nss76u%W<_1nuzpgv zh?A(oS3-Mn>}1;EmD{E)+;}(~-tCXgn;E<)xGHi0g}`taj>jV`{tVoJ1JQI3e|lJk zq8jL8VAOzb6Yr%4nHUxP>>T@7LvnrMG{uo;Vfbzwf*U=SD!?YU%hBa8x0_#n^|PP7 z*~Xm5;fQLny&cDNzdP)YExwx}wEg&p@BZ?qzkJ`09E;E=XU_+h#(3gO7trWSi$E*F zG(N>zNZe76=?2|QOKr6qlOsm>3>p;OFw+=4qHg$9sMx;)wCG&m`pVNm*R^!?{+`j5pHp82g@sAE^x3K z8>bMuX~k=$=v@OuuT6A9HN}%@ig(?thg)!j5joFgv144 z8KN#KIj<#V<4~M(`q3g%Yv6W#M$yLg`yu%BN6U`Xafej6o`LbZ< zHmJLtMUY)+`(bY$j6*^?qz*Rdh+Fi=^mYU_k8CIDj5IxlS&G$zqE)sq*Z~u25$i4O`<3P7vxgyIq_&PJ36BvC+x)o_RGCwHs&dsd+s$@W6=Qe2yT5yP zzi)?>ee|Ko&JAe{nG>iuf{k5^j1=y)L`JP`6e?<^^p#)J>toW?Ybk(JL@^$83%b+WqIh69^n z`V*oEB=>PSaRM3+QN+NI0?#x_9L6%7nOzG9!_3aq3QEd84RsOz<>z01^KW0(MeL4; z+nddoUwqkj!w+xY9ojY&#o+wi{o(h2{O+&s?ih%oX!{X`nE5l3M(R{iK^0^8&p?K# z0EbX7u>_bhCf!(KGenTtX6Z-fAiZ)@i?j8LZkRDWb{!UPR#h*sc;_OnfBgD87x7e; zp1OVksTMhpq)rKLZK?$c0LU*H1HPJ`Boi@kl5O@JYSDEm`$N~iy}SS6Epo)M$EY{Z z>yd#p`Z4-@F#d}z{TM*%*WmN27Emzy6<WrXI~TF|_#&<^6WQ^(Fm5)V7hm%jm~Wvwqy!yB1;b^sI!@ZMwZ%Ioz^?4+QwKzM5!Al~AJivVg0%eHWpgynwX9YanIs8a!(Elc4jT z2;-K%I%V%+=PD*d-{(QvSp@z`nb&$STKEy)5ywuzUqqzNOocrgY*_p_3?cg4o167! z<8nUicDM|5eYUAU5hlQS0;K{8sc>WpfdjS~PdO*lWkCXi)v7FuuIqP)c7HS_nzOA4 z1hN-G6cotZV*^c%s1ds0@?v)HJ4UrZCDQ zfv*|>HM3Zn05L%m!KMXWjW!bU>>q-Do7bNKwYn_{lt)bc=cBq#TQ|S#Ox6 zbv=w}XXij4k4FZ@7rfYTstw+1Hbkfx)5Q;iJw+bZAltosN<kS*R)7Bfhu{7F_jkMfkbP$F$d5FQfu`#-wt`c66Ev=Z1TPpGzKBy& zZ%Ea2F>n7xYa@}vMmi}wOh`B$?z0;if*3bVwO*}o z6Iie6G8TbxM2aYgNGxJV$r1DgM>_s+cmMX?ZjTHx_CtnC`UtTaZ9n(okH$H1z7{@$ zNIdPkfK9OpV#sVr29B3B?U;$6SM;1iW#ZE7cg$5#Rdp-1RQ)^xm|#3%y5XM|8mv!- zIL`%MSmv{;1-r-Ri}4453SvXfBJMHm%Py`*B#X~Rvgooc1uqf2#3;5!FPt?HXKF)Bq7`nKPhZJ0bNZFeN(y=%LXbbHBC ze~zOVT*iAKhfFlDR0}zGsUel+t{unm{{Fu2`-@I{4w2FyLd8mUnffoJnpBUxamM4$ zKLMwM)Ax_YJoM+#uwLNtMfMlo)5~kYN;SRi92$rV)xzx7NRH=sE`n7dqFN)|6bP)6 zzac4ux>s%F9|L09#HLYrBt2JE@#glnX__AAI-+)lVVL>2-VTi#B<(xrT2zY^n9-pu z!=|Y>Ym$t0!*Fc-{h>X!ZHKSD>+OtfQG(S1h&;~WUBc7G(IPcUoJ7r3b5JmFCS?Bt zHyN8nwAnf>dql*M_0aC8bS{#LY}({Ne6*ku?$9(RE*V+6$YeAkrImRrO;uf-4(e4w zg>aiqSkFN{1+Jc(jrZZu4fp$Ye;^L|LSuOh2A&sQ0o&10pXgKcpo-~pf*pw-La6OP zv1o2l`~64gX>VZd@W;dbFTVWZ=U;xYU9Z3X<-e|1b=PsA!ES%N zyWju$FMqi|9E@z8o#yV6JxUz~wO8*Sa?@gCEifm zZBtiyOkLX^@rFvyaXMJr566B$X2C&fROKaVP>StHDnkx-XJ4plMR0+fh`GjFtlX@s z?S{bjx{Sf)aTqu#1HGm1y6)Kahi+&)B(H852v#BO9{qrA4AB<*s9raxh{3>Pe%Qz3 zaktxz<0!3z+B}bC9U#$aUZg%$4_7s3m%q=3WLao61P`%X=Jn9)F0k~X<%<~h>9f~_ z?OI&w>W@_mq^qlUEi~8k`C-*UPwMp@F-5<{YWXOt#hyGtG!l zDbRV+N2L+f!gFNgs;)T7rD=3l!0yoQ_WL8ofHb6O4^Ts+vC#K(m=zjb1&4lvW*_R8 zL6nK0hGSiexXT8hR14N}6V)8U$KlEjO@mQ>FRpXIh{ZEOejx{hdHO_}47sgR?wLSr zT-dXS?B|u7p;pj8j4U7!87-?^tyVW%f|t6kzu&jJmW(v&(pgx4+gj+v{fswj%C!=p)-Anjp#=T}Pcgn9;FRRi0$ogJTs(YieQ(TACp zp1<)WnCZ>A52+S8K_T9yGtm&$BB!w`i|(+mtD=hj=4Si9|8M_uvtHfb-~aW8w|94U zKfJx$9}YQ07Yb{e^_2_BBdZ#Fq`P?i8RlVvcFBZc!Yk?ola4eMY$jtEE7-h1Mq^^3 ze-ZP>HnP#H9Zru)Y)px*JlnbWNwxS`NVV{6wvi~TD$AxU)=jf&YRno{RkHiW`HY1H zDEdHrQQHmg?(e_<>)X5g9h<2P1oQ*Ri41JHeO;*J*TqNFb4j(B9~ZBHmeDFOOVJeu zQKmj$xANCRlkU8>)bl6R;t}R9`ZTDYFYv-LuTU)@O%|l*;oI-D+sjVu^KS&!moXiBRi&EwF6!%y&*$2lP%CDO0&CQnF zP_aPL2j*()Ji8Xd*!6gF;ljZOP$4Qu_2(yi6mYpF@4lIcBM15xo2F*xceARCh}qSl zT=k>xQttY`we6k55htv!8`_~KSOu+)s#0XeEQefW;H`$*kW$*&p%|*t+{WiH8EP+X z)8pz@eLCF6Fec%^HVkdsW-Q51y=Y-4tvs&_LKm#{OwXojEsqc}E%JOEr-fTAGIPP}) z``upA%yOBNoM)6WL8>)@J=vuZIgc=m=vNk9&@@emF}ZL!b~{eS=ms*KO*)L)VQ*gm z8bBJbG{Qv;h-$vTwE^Op#5Wj@8-_078a0}a)R@LRI%2dKL1waP4W?8iW|Oz~8U3SU zbA&jaEq2{IlCh#)l$CRyFy|gkfMQOZVG-8HJg&(biA*R~hRwRkIp5vg-|fk|%)HKO zIAdX&0HW;$RLkc;6ZPtI@GSqQ*0c|E0@_ZA1jR+~Tw!WYUDq)LyqS{eRMFf*CSAdq z=>x`r+1>sy)q+dx6kF#G>;>_rR|LaqrHkaA+O^0jvBTi;b@{Bevnv$=}l{@M;CUuO9l*}gC&8JIA-K{%8w`l01N;e!xwlxo5GDv<-S>bhFj z)p}K%Lnf4i`vaCrA}*3coVefZ|N7Ur@9uXkq6BQxeBtn_J`vq3BO8IeF6IgHJdocm z@qQIJ0SU)Ptr*6mCL}WselCdX&W&ZcGP?=0%P?2 z0@7p+TYml_RButhOay{%w560#3d{6pupeSTg0IS=sY*^sfFfUS#@-mKJJgT8G3H66RQLPG#o3Sz`)a zld6}6701Y&`{di?Ce`BD?T;--{q`LGP00H=l1qyPHDkP#sO2bGD`i=hjU}cWhG7o0 z_!tmQNo^lO!#!U!^1xhJRh-B%j$_wN889^j4}nk1<1$|etHUK0-fm{?X@t(OaOcM$ z5aeKT#2FS<3ld_UB*YIRutPYF<1@P!XdUzbbCYBN6ihtMI1~k<@OHbd%JO(T-V^1> z_Mj+Jq+${kP#>PeO|l!Ol%ls-h2Wd2Y?`_(s}RX_)DPpa?G7#TpzS+eX_HZ9>dy<9 zi2`pX>S^;rZ&d4oO?+(Z*oTb)AhC1QZYRU=NY)4ThH#)}#Nc0ul7)B$lsd~18P!7N zGv>B*l~wI+0~T3upc9@28Zs&oC_*snDJKILk)Uu>Ee@PxK~ttyYmV#Hp9mVp?wTII zD9T=Sf+LL>_H^q{&3EOOvp$@*Ct{-xddpM07PK__q3_Dz)6m`CY=8aDzZXUM`)|Mf?z=yS z7#uq-EPT|`Pp1<~{=eylHIRu*ZfR621251q)YTS698b9H~I9DxPCNp~xd|4K&s%r3nXsQZgH><%EbU_ZN z9FBc=celIS?b@#EdqzR31x7bx3?F{)CqSh2y2w!Jbuco&z?>HwN;b0;H)NQiu~KMK zuh8e`f+pQu2k|m-FzRR4YJK@!HT;oa?xJU*F1-fVm${7VREq^x`xqK{vB((`O+>zG zl>`(xJiq}Mp*v$5ETUf_;g+14N1kc+2abK;kz&d83V_-`{G=qF>%&%v{| zWM;l7zpufzaF!msy38k_vA%#`YSH71$ZTj}7f(~>VzF1^1Ls;?#9EjDgiQY|u2(G( zT)3T9St=<23&^RiYjV!6nv{sN+3)vlhqx)S)GU_6422j@(w>E-Cnhg(lhHS2(KI!# z{G@_LO&HlvV^`tOk{du1Q{DKu=LOTjfNq#Sg)nOu9P@&Ey&SZLlm^b99J{_JFRcm1 zRFqcc3>UHuoGKXqLApMpPu2Mxx}xftF@*1BjN8pxM^6rYdpI2S zd(P(?5nZQgLi>>q@>yNLZ1iBXo&yvLf8eFMS2eK)(MvO;Iha9Y78%XX4FBhYsFe;m zYv|dc8FSW|bQ32%@z2?h>m28dRIe6!@Xx2>dewp*22?}F)C4$)t%$+<+#L^`w3mi| z`NhwF^XqT=Vf@|izuoP2MOhvW$6-vdD4`0rb?7>KoIba$%7yx?b<#Wyo|D?5tBRsx z=e^MBewB5p^ma0runvv==#E3~ECj9}loAm2;wRPOlVNj5W8!i``45h?hb)vutjnsb zBIjGMCb92|)DdG*RN1?h05I}QB2tiz0P6~%Hqg@RLZtP&u;yO}zqq#2cl3!t1*MT< zHS6gO6LR#^=Yj@!ZtTp~#3IgxrO#Ev9|`6zdKOwJFR=Ld;>C}^tE(0>R0$cy1@UD| z9?w=WJb^SN@Y;zxkf6F*VLnH>@MMS@%?)bkZ6h8=o!ppU77mL9fX-~Hu%wuw$oMvZ z`Z8pvFEgBvs-7SUo_7gnpfCjT=gc=ysO5p>l4tSOPv*hQR9)58?alVh?KXOUAjQsM zG|n}oJPg?m=op7INT8Stk*GvNxOtk`E)$eun+(LIG!ZK<+@C;*56JzXqHi*oH9W(PBiSZn+ zRs*o?62*bZITCD&A#Y%9c!XsqtLvemzXp%z8!`ui+vU?Dq06h+f+C5be~2e`ErRV@ zJgUJXe2i*=#v-ai@UeA-j5^-0R;%0F+qx>du6_IV?cs17jSQh_q~WQO^Xcz1NOwcC zP%TIm8bgCaRP7wu7swtE*>M|fOYP7enezCVQ@WZm&!BU7QY62>pnKREFsN2E#O0#! zRg4M~a%PMe$FVhiV15@b%z4BiN|OEiqP2pme3#)EOvVDwc{Ntd#66)^iXNnZoy;X< zy}U8qBIkVAo1WH^!j}PsOELA-Ha)KIGpsw$s`xaBMmk9Vw84}{xRzP^#dU?kyE0mw zrkOD2o~dhmAPLYq9u-ZIJg$`~W9A_9l&8kdbA0FgikVIMGe$bU{e=)4R3WOo2I8D- zxF;>E7CDarg>k5hIQHFF|MH7pfAh_u?f&CG|8uwBuh$!Bn@$V(%=t;Kn&m%JJEymw zL#-3fheARqLvErg%UG58_LdxKgo06!%VRR#*m^N^$sPL4(F)y}YBAVxMK%$B+O_yt zB-41snrzx8GSrb;B3RC-NzA||0`FoGkFl)lrYx(`z6j?CsuO~I?1FLebG-N2_+{y;EJCQnsjqx#eY<1aZXL2`G$X5T;BuJlzE87#}_Yt z1af}h5T&u4LFveXI2X(p&!PMEDGLFA*lNT@Bj2hl?MzkVl6i&BtoBMaLM#<8!skA7 zGz1&P-a8-%;iz|_FAL?n)uL2Vku-@HlHb4LJ&8n$~u0I|Q#}39d4rJeFzhYp4 z9Fbs{@GMaVebHM4Uc_;;NDsJfSH)(9zsjarSu@S~Bu3UTN(iG1ok?$9-`lPQ$8sIp z?xb2^F{NaD%M;>=Rh{-^4${IkzG*@Tok1sRjdqTK?y=ix_4%J?K*%}!^F#1~jSCE@ z1rZna!j8UUy{BIK&R>o`xdwFCbvPfmb6l3-S&?QF@{G&dJ_^}fZZdM}IUcJP^uSUW zx5)B*2|5PTe%6OE3fGAwt+}x~ItDMK<;ebb6+d_Ia z;*hrO60i~R5Y~#&C&HkMh_&8KhOw}akG|);e0CUP5jhnhwtd%fQapQNR&y_gVC6gj zd-KbneSs;Dp5$F>sxn5CK}}oL1gG%{tpHwuftdL}B%fes>OVRqJJa6ri&sr}rFV{^ z%=|p-D)Zdrjx+GA0cqaOrDp$UytFus*I$2qw>$i=|NPytJ+9XqCI9t462a^J)YW-nUr(tP!uz=pP%YTCC|TeX6W^S4 z3??BJ#7B1=hkkVXKEsN!_ON{iph;#WY94Kx@bcdK$Hk|$-6NkcZ!k6*t)f0dL<|Cv zpTtZ;No7Tj+PZ0Sc1KezI2^WXhhda-fwpfb_-O$LV!234w(?G_ z@&u%+^Y;H}p#G=c22FoiH?)>9iw!@TD!&e1IP^2-4pi6ax(Yx4d}Umy7LP!BsGQF@ z-x+M6si?l-y@MWd`qL0&tm`^h@TH7TfY?u1s|-;HJtp@@bML9DYPDKbNDT0Vw#Db0 zy#kNLQAWfLQ32RonCcMWE7OFLC@|9>?AsnuFJn!81QTX~20-eaR14Km+ZymN#9p8> zY?%+y0o)@g2+7rivoc-kVRsW$F?9$HGnvD(?l?j$ zntHveS0vWskn-S3dZ>`WXtA!@g+9A}Fo&oPr>6a(&Y{_H;SjYL#?6?S&0Fo&pSXo^AU9Iw?0G2dT3xDljmCz3C`h*m zwJ|AjMkZd@)y>UKRaJf0?)STc<#%=_wVr4jNW9}QgX%!0uY|0RuX8~@27D51KMD_! zeoWZ~Obc}^iZQ3IL%UE|6c0ZEqmd^;^^MOs&&Hi(dfc((X@^|xL$(&46pWrA@`R5U zn>FtVMn#>fGRc=xrOL9DYB5iL>%s?^S2a2)5Dl_kuQ%&e8RIYv$K&y^w>-|C{UUZP zj9KN(3+K_9|C}e+ocLJPn;L7_9v(obXtsMK(#=ZuBKg!s>C76*c!tOxxnwoZp??l z0^vC8l{1 zzEwVGj{~R46T)1XQ#qfA&#PKElQh&8F>|RFnnd)D0Yc?W%1>xFV3RNEczircu;220TgX zEDi=GpApnBJr&KjVYRaCB@xq8XO6&_-A$k$kPHw|IHsCMK_Zxw{c#EFdbON+Y^h<_ zLYUrok|FeJ!DQJ9DgigA2-S*+RRKxc^9`bGA{Js?t*S5H+}v!oDGj^b?sz=1Qjet2 z?T6G`#6=qINP#d}ZA}aU^K4$hBl{R7rZTdT*p+NHQR23{ z?$`~xLwhi@jKn+4GMUEWzhW7pU@#`6I>&JqP1BTRskrLdsakzCw_Pn&J*mV4e8jFr zU>}H)l3^IBC&A^d(X0U)GJMFd(<`2+(o13E^wL5uz|l?E*dBDCrpdW#0T=Lbbjz=w ziI$%7KDb0~;s7m)oYWzb!{|q}en!*M;6x&Q=v+qDIY(ls^=iA_dhZX1-F~-g+txIB z=8+1NzUR!{h{p`4riCG4CX{MH_%^n3kM*D*$WE3rehLU(MJUX(zqcuE8m#K}7>hFN zIpzm_$dSK%FvA291R<7H6m{VwY1slu_XG=IyL2Ei3_U|fq3KR-tYY}`Nhcfzq|JA?!?B_rG?uWbo@ArS``++lCdNMP?#xo}E3rwW&1l0Ku zSqNoxb@U`TWV3<+s47%jxU{JjboB`75XL>^wgcw>%dXLdYN5t5^!f4N|Fhuwwm-GG zB+3z(3FdX}GQ%x4Ti3N2E;(90nILhr3^D93ag-rMA)FWW63oKJr{VfOSwyx_IIZ2r zG+6m18j0B85ylJ?hQuEu7)Q_4n7_<5KkuCL@BcmUS}mG;Ph>C``}oUi;#{@RVxxMf z67~Uxe$*-@NSL+? zQbUy=9MRiNS+3Ugy2e|{dTjJ;SripuK?^5aW^xXpt?v(Ae>}FwwkJ2#fOto?+YCur z7&n_Cw#CF1?|og@P1AV)e#=6&($c6}siV~VCE!1FG5~%Mwri0Rs>M7;&P`eKbzN_< zk-4tSQx9ANHRJ+%<2lG^s46_f<2yeF+4Q>iG%sk)J6A2RzxgMV&t~fyqdMjtXDJ2~ z?rp{?<8#V+=zE6kbTjLR!*Nck1v+jf*J@MOx7$tAG$aSRd$-?nqzT4#<|2?@VYCNv zGDx-*Q3FHr(L2vM^hLz=97miWQQl6oz=PQ%aTS%h38jRAd{SVZz=tKgb3n?bsu|ny zkwawzp%PTaOvol)puU^ z8cYByqPIh^{hvM23nNEQ+Kdh^>X@4870@kF0aQcXtFL0AyhWw!t9d+mGHFgsRqk(< z`A5!U1fwHYglT}ICBQKx3(n?L(@bTAiG+fOmyi^TX?QpsLcpl`$xzR{1ZuZ+8eBpu zleGi#Q?*TA#JBTOwcxq2h%OKPs;++h@Be;tbMyP}zW?^SzYOD8S2aY;HbF*;w7xyZ zObUybnYL7m%2W%eq~Ih|<}e5_bV|;7 z!YAtD-5Oerv?!MEnG>V+Ck)mE9kq%@)OH)BR7l5AA$k$FY1@(`Y|GkUJIj7F7ad%* z2X^f2PCpofrZkeSGebNv&C$}Ua*wJZKLP$RZa-I}?T8yz1!g&klFw8N>V&^8J2tvU zH*nD;5B;h7hY&Wa>h^YfyS?FPi2HXqBy~O8?%DT4>Ik>UW2QGl?xP=7C4C|goI%wn zA~xWrs+$^X*wkqWaj-;YDyo9xE=;cGk!-HLXcxoSb|ZR4-?zii;qpEZYiqs3iNxft zry+V#(-7T~QnGCpBq8;iwlxIx)!gJqxH^oR{guhZZWgIS!0io<&qTM=TdbxK$n&^< zhAiHBdgB>vmmUAHhgi7tV}PACqamMT?uTqH?*z5uKNHP=W*L&YY>_b4!aG8!4Wjm( ziI3OV&1BCRXU?0DjB4Q=zHqCix!rCw1b6S=w(XI^DTSgW)m446HAIo0K2?ZlUR^pPKmgQ%%@}Opv<&SG$ESikI0(18i)v_~O<)Du z5t`K@3U_hzrmS*1$ogh{K)GmRK^BLWq{E|?`aH6Sx-O7U+UzGovy7qmkZO^cO^;$N zAOoDla_YO=?dCVX{-$o~|Mg#g{O+&sQX;O*J2ubN)zr|MaAkX$a#p1fIL5S!p&;8V z`$eT9-}sYX@uozxV0{|KeC!9?IO_-Y%}lkhBlARB$@Js7)zs>r64z7CBh`Y1^>Lpu z>!5TjS>jhHfmK!46$!Fq^mcp=(gi2X!mn7IOy$%4TJ9g0d_6w9Y5^}dh?%QhV!W^h z0~fE3Z2UWeG4NBh^@V9;@}vmnYmyKnq6`(no=cVR4j&*&QK!`h=zc*>W9^^Zv%%am zsx80TBC5h~x9gjm^{Q@;$HVUa?s#l54?A37x-oTw8!Q(m`CD=yTp|k7>Z4wgV6DEI zWX%{Y6)y?8Q_928%S+w_NG)bOYth9WeFfs_|yPanzdk7|KC3sYq&@HOiSCg$6#0 zr7As%$2Y58=ims4r$dQ98J7465+{J}z5z>-)EoxEkiGDZ|IC`lT>P*S9>Qa%n zrrwa;kQ|FAq|f%(YPH&|*P9hv795qhyB|jgz=u#2#NOz2h^wZN*tk%d`q28#XOG_z zd0-Lcqd7#851=2=Z<%ZOI|uJWVf$=_Z70h64stbZ_7R|gr=Yh}8K#r65@do{JY0xM zTeLz5u8IX4DR%ULZGn;h6&235Py1Pz$db<4R7BN4yPzEEY9Wu(+ciDuJ)8LYln-Y` zgeVpf?u1+6z)d0qi|wYao=`Eqm>Q$c$IuPY_9&#Z;7(>EO-<~JbvsBoDbEl_77XEl zu{GI9U$~F{kAo{7I{pT zZosK;B(Q>xl>p~alpLOn_(OH=mv3%=`#*jYV*G#p<9FZR?X&YRP7m!ROY{e<39zN> zz*rdU;8(~VdX52|qCopI%>vMw37Q$l+>+!_V5gm?@EhIFFd1{EQ778?=fw4tgTep- z&ak2P^tlCOGmoH8N6?(v9RS5ZI=}eSWejsg0iSFd4!#}jdh7#$3Wq;5NIu-aL zd|uVU;U>T&GMY6;WHffJTBv#dSgM5v=z4 zGEneq*kTCwkMo`{P$N@T_d%L4MZ0ezS!_Apm7K26mB%8f3WtrN9*8ndZ#0hJLlBK4 zX%R=-A;9Ne!tJj*^3&la*B&v+;UcC#b5GsV~8_9eqmEaE^0l5#$Y2 z%b=%dmw~kbp`4delt~+kf>J}QEsnf{W%0%B&1Ta?9}v;@yWV_3lJhA!PT)4xLZ=Eu zH>noqE>-8Mg?L|8l$+J6tV%4Ix;N<^>r zW1mL$+#LoSoITD|3!Rl#mSx+v`~4na$c(IWccl~PO@mtf5CoLcN6!J9;@KF@ZxN@% zU~ipl#ULxPG+cpso;(XEbK$0ix^tT;G zoF^t|7BSQ%0u6L%dxeakbMz(@f%2_?J9f`ff&}nC4k4`9>+N>4s;a}`aCdiiJnoqr zk>G`*thvz?2|do4&4HwC(~QHo4;hlnS?6FDu`CKgf(o{w22=~2@rd(*LYyQo#PCzj z078R~9Cq;#Of{Uco`6PyDeIh%5%NcvK!!kmr<*WS5Z%svlmRDr(IS$@go-lRQ} z+e6`bOw-xP@F$$8fFdqn8pN6C@Hl(Zd!(|6tM$66o7Ji*ih>p$_9*xXO~rdo?6QFh z3@f8Y36ARH4wZ1uInkefVQ>Srw$X$QnjL~C42n(HpmYO!Q)42x^hCr~zA;5O8$?4M zBvcEdJnlNZhZ-42W#dAK&cFNX5040c0q~R4Tt0`r|3zQ`t%F!r42!A-wuhWJ@{kTh zY$8bzo990GG_>8%fA;2o{`R-ox&QnB{f{4ZM}lea)+m(Ywn5Cdhkg`1kjDHdf|bQv;U_*`YT)!#mci;)0x`{JYvTWL7T8k zL<#hMV}&+J(W}8BxChV5Fnf++@RpPeX)3y|4EqC+)?us`eM%|A9hgh7m||RPLng3~AsWe90j2>ZjMzwU7!H8R#HfWmF z##ZdH=?r~8bhbY&nM?t#G4$wgND)|$wVv9Ie+<@g z%T9kZC~sW9^ASX~E9}Q)4zmj7`4Al6_$M4bjC=IUj=w z%O)brs3wjqB7i_Vl)>>;%#loN%Qnp>Yie0QAmfS!3JExZ(!?}ty9?y15kkN^dO&Gb zr7v!x0wB8+3ZE%Kuc^TLRQJk=Gi0()I9Wj8%yUd$v=0J?IT8e0wb*Pn&xko&bzS%T z;(534RI$l|PM~E`N^)Qw#@be6o{BNcWL;HvZGLE)COOylL~WU-33FSF4F7BiaVPM1 z&W>bYpCm~WXB4nf9g!66Z>CbqFx7R-uG6ZTrit@IjHf!@f*yQ8&s5VP@ErhSHCU^F z?4?@JM6W{%E{QRwgdSDbScTP_GRKNq>Z4%!Gu2&#I$fbo zrCOjEIHV)>GLoSI(b;Ti)+tUJxa}yY&_vs&sRN;+JQ}a*v@D(xootvm(tescb}T`V z(Ye)%6S$kE>HGcV#f2TefO`-9>!O1yP)sKqdvrF`rGH<*yHvSsCIEb>8jCc|M(u&E z(neA9H=JeWbF^{SG>v?>nACAX=YP=ylm=Uh_X$#@q=djfFsA5I4BmXBXl?Wb6k}k7 zH*p>{ei7q<0^sumvCzmdR>7JD3bj=Rd0e?vhrFrdYQ3r3O%9>!M+?kGsArE2BD3X# zK&7$vIcABoEF2;ln}CqZs0ophdQMZBaxw!v1v6eWcSL3(1m=SgVRDmW<(3M(DOibu zYr`mDjMgtP#@%+i?}#WB!@R&-+Ul{94-~Fpg{W?VAjT0RM)3#AlQJQOJtflm35||5 ziDn8ZfBb`wKKb~E7Z(@*=gXg8b-j|(NuBWHnJ|xnO2vRYfHkoIVM({XhBfPYRt9_yW@z3Pyu>MOCw# zvq4@7E}-}(M`Vj>B9vuhy`O~&cIIN#N5ZAkp*vwB*Alo z>Q0=Q)k@-i&UxSW9S8a#ZL6Gxca+l3H-}YVK@BecqNdYx`<$Lpc1_c+*PFv3+&I4T zA<7~}br|31-qLYOiYggInzV_JDIX4>`bJ>7#%vG8N&ZtuqcvH8R1-#3y!aSPv@C>J z}TGgOSO?>mz(7_uo>E}$D!XirKIp+9)e-^;0qc~w_!v+}Xt_tUQH(A_L1mgnT{ z%u(dg6Aw4Ih5==z^3hs^(qY!|_)4kFct3Iy!VK+2nNTGdGPq9D6^vn*ZD^xzlF*x> zSaTTo4);h-m2O*w{MUAH(VL3*1Q2V|Oo27Wpq)t9R13^nnIk~0`U}+peIt)k6~Yfc z{=xUZ|NYGOuf)noL<>fO%)p3rpBIX&kC=FWn%usqMx$k z#A)PJj;B(`tM7Fc_Y_%Z!oZM&^oVe|Y|}C%Z^%u!? zoP5UJi$#`-fNX4P2?22y=^~>rV4H};n67sFt6evyi5?B8D>&j;75mylXhUdheIVd3 zLtcam$gCR>gO6b)PDZ!}JRpq+&Felk)T|G*SZwvmAu;A?+xq}!WpMC+g!s*7gQaF1 zce~v%%o2IwJdX{rJC#aB(f|>25JAF_J%Pb*S+#JeercSVSbh4*55M=p2fz8--~9a7 zf4dtd%`aNDSaPsqAVMP3gR+Xb&GJ&Rfg($Bv^Oxr!JH|!9mmF!qZw9r`F}P<&cK{Kh z{^MV2rO)`dYpU2(p{=V`T{Ugf)@>cziYb+~dg7Ow!!JDExiRNq%!)z8EZ7gFUD5%tA)MfKjvy)nZIU_Tc1dldkBMjLBJ2I~%l}Yuonx+1c6IsmtN=^77*1!km{P zjYEKW%B5=NK#gJumG?DURFItXbIwFXEbtx!Dw`k1k(f>gs8nQcgGx7o4M5tq{G=hL zb}Qg#Ai+JXR;V#{Y%mcrRL*RLDT#8)4o%G%?`wcyorz6k>Cc}_ zbWr0Qj)7;$X2YqpcrJC_<>jR| z&>y5Omwo8x4c`n><$fznwQzVCMvIDCv;Gc69aIYx6c4F$!b=_*enzZXF+lQe8b(Os z*hCFv&VMwzzct6>p|LO{+mgj${RiC)l>ly|dvrTn%D}afRoRK=8-_ehbqGyOz{-Y| zT(+|$JBTX85KZ?@IdAv-i_6`v>nS}+lOP8OHg${Q73x5IQX50mi!EM>E2a{&m~=hb z6$Fr`A*EqHl!D=ERVbE?Ya1?)8Fa5jX($!%#j2?R3%&V-yf&Q&K|azUio;*B&ki-u zEmkcYtFCDn*3If4eE!F0C#S#s<*&Z_?QiKA)1Aa;#Oq4MUkkmt9Q!avdXk4XP*NiU zgUnubJ42&@l4tI9{Z8U>s&)s};>E~0p!B17uPxuMnkuA;eMWuX6N1vf%B@+!04ZT4 zeP>k*h}$5uEYwAyLwL9#;w#mEY}~W!RZa~qjTc!QZVX<%cF(-tF78=)wZJjBXGV8G z&i-Hhr-N!?_UfjtR!zm;#8tCmK5d(-CA4KQds|M~_VMljH}f~v7vUmy=@F7L%AVY^WhrKw$cNXj>-M>LdgZY&XK&HYK+lS z9o3|>Ri*fGN&Uyi0E_xm4Az>1(nH!=eiC}Z*quYR>Kk2ADR>tff%vL#3SVR z$Vq3WT2$**y>4nwC&938t4PZ1PMxs5drWh`KX2p=GcaU!a947i*%#I37p zMrd-$c^s>PcWD~?uD{&wuXei*-zBfZ2CKSSab$kYszr>ZItP?S20pzojd@^MX`q|N zp)=iLWTyuLjrl+^#Ef@P*cZ!P42rpNW=3`oD1!n~W81d!lhnzEB8>9Rqe47EL{gN2 zTOFckk=s;@82s1|r|Zq1{>kU7y8ZIYzxmDYe?QP@)K1);X~>%Q$hs_B=|De@^(W}3 zJR#ZTlYT-!d2(GqxbC`BX)ltP(1}RfndqDm(@5P@~(Ra;jdM zgTxjza!cZRt^E0I#61gt!-6a%gw?l)oc+K4&p*MOY8_O?Ak_l@id9RX_PS{*%x+bL zDWh5-G!s*@8-{JyU+sHT3+Bhn$qNR$-K0iwaMcf6o~>HYj+wol;=Cdno|>Ceu^rm; z+2U#Uq$b*uF0qt{IJAG5NST?NG?k#pu6#bKbc zDe^I8h%ua>ot~ec*LA(ybr+YHc9t!vp@^`g!~0e$4(tHIvzx_{rbdW~HC1bI`|sC9Zy-ol-_|L>xX|li*$OAgYDRyhNd~ zZ-z~V_{P%+3y1*Z5{A)wWE(e|=nrD!LbYJS4^+hYT&%NkoI+D=P%WC(s%a{8SCe?~ zw3#OMMfIo_14pZ&V+Bs)CgSP#|+Je{F5s&;{q(Dy}VbQe_7hpjPL}1ysA}Id^=!+h1I5*}!ebVk#1m zod|BrQK%}ml;m05GvBAtLf^7+oF3Y{c9CF|8(9SWY(Qls6w6Vq7ZBo2nLJ=(_Wh(|`02|D+1>i!Xlm+vm?mTsUbRgKEV^E8af{+NABt3?r6Hf=SvW5G$uU$Sjb$MwXsG4er_X>Y&n7 zx{)A6WoBl`bMf=1snlbj)aA{fx%&o+c=mRXv;Q}L{#WFkgAbfviz`%vi^T>{{C0(E zQDMt7g3S)2=0N0`ao-P@`|fJr?Yp7F+@|B@&^`!dVjYbbWnhwE%7w#vY>2d`Bn&}3 zx=5L&v3y{v6Y1oPID*H5?QCAQ9de1u@d7n6n!C|w2V$MGV;m~WS(pZTKsGV9?TRva zWOh=X2tSDvHeO*<(=_kB_w3|klTyC8-0C!Id*6?Vh@a!cn#~NhSKx#}$U>TczSmI| zc0MTkD+r3e=ddlR#@rRN4@l!gh~Z@enNuX#E2SlUOqx_mu-Ew0I_(AQR|M=3*xt}I zD{VdRhz6ry2^Oz;ktm>^mQxc$@ZvP?g=&!zb|Ior zRiUwS>o-k(vaUC5w`g%p3dF9Fx#IgRo#RTCj{l8Cu>%pWVYbL%r-L33M;eKF?6eK{g4RexYU=R_;;F~Jcb$|`Fm{(3$?Ydzj3rF9x z3d=rw7jbTM*^iWV-0k~)KlEdoEIp3WARb1D0g=``XBavPYm4s0d3_TK26q6BiqIEn z%xTDzje1JRg&sh=u*P(d2T$l6XRPcPkk&Us{X(KSw}udGM}EhCZgMrIqZjz+(V&b} zU|P)}V}v+AIp@sG;84~nl5r{`L~+SeKmO4NAO7i|d_Hvj7hinw^>&v+v}T-H4WFPR zT2j}cd|wOtu z9wQf3M`DbsNoUXnHn`qxJW_+aTYZvi>`fA<&vgN%_jeceX=iz{m@UW&1m?;i8ASFtHyTqSj5lX)D|pS^0{bmg3Fb+;#>N zd3MVEG1l4_x<9SN2525x=$az@{F+^L}+0ryiaY!ZPvWhNA)4LcoZ)7F~}2gnX% zQVat^cw=|5QRZRZ#?}bE@N%V|u1&m^M^pa+3Irm;p66xG?1JW>0FP96jn-fTR?L%1 znUwYJ<1yMqq~2^Rp*S%(wLPl6+nEUj$IGlZSp5GXdK zba{ET@32Fbe3z>hHaw!YQ?xP56GC$0tS668h3vKXcbau@z-Y}U-iPGF#P(N!lxE8M zvYe$xtZ-P_memp8EDT6Dob!dtN7Hfy0S9rI|JAHoka$roFwG>cRvt^9^tJG+j5N+O z6Z?_dxLw)HdjnW`*$T`NKUUd!F&7#*(4M4<8z0^YW;Vam7Y_*{AtDPhItoPdOVxs( ze4Lm*fqeqlFkog^%=}o^=WX08#%#s87C1!35ON67_B>$wA14d6z`h^C%T{bDXvUoJ zhT5^*$a(F^xGYxKO2dSA+#&ocBw^5vNKRJ>!=>80x<*5mYB3ASB`_LwMYV7#M|8@0 zQY?Uy%te^(CT4hZ&UXX*n1^AOBVT4FZ-CN_OO%SJb~ftqI;)~z)$wG#d3JX4{@Lm2 zdTr-yx;kQi;Z$vq+`PwC_D|KQV4{{Hjl&%gZHmzVwU@TvuL3T3_?mpJ#yTR2N-(j${-oGS9ojYhcf=Oe;1 z>Q#7&F%;jZQI&$N7+5BM5FoR{@?!j z|ID6AiwT}UNfGCYRkK;Qo2Fei75f*NOzB(mI~wi!|mMedGK4V z8gI$zBa{w~Ni2=Oc%S7`DHc8_3&U^asd&b07V$X=>s51da#Gjze!u_v z>#w_h7_qWbRiwHJ$zwvWqShfsPXf4GxHNe)0pcm&u>6`5HWF>&&9>o$()uuJy91@8 zc-+|kYzSUdhuU#4u-({|R}avW<+ZB9iqpPZ=Yqw6*$>0`!bF{mC-=N+u>^g0fVSRZ zYNhRvp7__G8)bSO+RJVl>j*g5@taqXks) zrD~xLPPnL1+#(Z8wJ>62?-T1?H35j)n$OowU01P=$j6W>JGtHL6J_G8%el238a{-5 z-(Rt_yGzNT6`N{-_F;}pBc3G;I`yNj1?mfR3aW)|(zT_XCFK} zJKt>NY_@9RYSqSy%~ZIVvEWA?yK%hS?l0NOjgcRlI)j~4zax&IE)aK`z`*jUV08jj zE+<+Z=Sgv`5eE!YGOSb!)xtwQGoT6s6lFKBhbnjs;#0rvQ}ag+1bNL0%6HB*nuTV@X?lvi$ij*}vbrlzV zYp@7W|J}m-Fu>|6u1uF$we_ZLH*Le8b%n(ac{;nC`!V$c+cdAb?rPt&YSHy({Y1(X zc}rNlQNuzg<{7{{QZ004Glr=UH{?s_3Ac~1ZU$A6TH6vnpAF@jg{|-@BZi`F7?iBi zoW&rU2@ts~O)(T?b%WkfQo8q;CbF%X0DFkIXWm5B`Ptd&>1haVceTB^yxRA}WOA?) zM07wOU}R9{gK80+OXC<_l3r25u@Wz zYI(JQo(NO}8*{Z@Ynx`??bxq|4n*IA7plc#)nbXl&S*)2Gok2F<*VzmgaruJc_QWO z&?k~F4=1VlaiBMoEo!M2dhI@V+p89-=m`aC&!uX?@NscoFhVegIPHdsLK8_9QNkg` znixcFQ>_T)ibE75$Ok*p8^;=JL7#G{LRwX1M6lG|ez)s7BAn)Z#}O`gy%2SEA~qD~ zdyyk0u{lgvL47e_U23aPMO+7~s?LtM$>6YRk$I7s(B&MVk-07f>R*VS4J7P4BFvPJ zL_sh}yC@}jSg01+Knnw`4I$)JRiA9uADo|kaDH~aSvM7S0ix%%9Az=4p&N$nw(kbq zqPk)Fdb_*0-0t=STN4|J!AE+88*D6*Aw%k>>4C()3wBy?{x40zslW-wpW$ z&zCTA;p>fJ8rAyQ{o|23kJRSF(;ds z>&<4fTA#!i$8qd9>Hg z$cILFK&XQ19VIK_N>j$Wk4I{gS5;iu>8iPmf8G{y_J8(cwsB{N$kIqmsZGIXv4gJb zYF$?i0ThWm!%1-C)Qv;ePgi}v-49p&uSw>X`UczlDb1o7> zk%5?#7?hiaQ>8w5|9wv2o`&s}c|)<)1a_m9lUcQ3$pU$TtRn{(NVcvyu8#1ITCdn6 zj?i>4I2^AK#io?|lt*%>I2u$cFl9TaN&Lo&Ln5}OsaUow1Io)wgy7q@S+Cco)l6O2 zNpzd+7zIAV8pw_FFIFwoL4x{G(38nII|?1{rcCudwZ4hu2|`NQmQa~heYJosiMVM* z@S=iNUnR~zZv+g+bCKT)kT7lyKC9Cbc)D_Bq zQ%6L6#MuzBl{5QV5L-el66~z#S*cTC0^=!Ek&w}HTJ8ziFE`0C0ubh!OGN2T^|Fg zDI5VXbI0gy)nfhL>FKl6&DnZY)2fQ0$C~DpM%ZAN23v#dhVl93_VQ}G?K&F^474h+ zLlheZcA44AfI^N5&s21>0qm83Rgz9(xs%by_5jCUtr zi$smNy|_LBg4sJ67+RiYgAv3mAwgmlrG!S~6O^a4z{8@{Zpjc-$A``6k)SSkSg0v( zpk%bXxlQ_dLgeiK`HxJsAUvXvAvSfeQ}d!ixv%QDuA_yXA%>!N-dugge#*Ok*s{xF z+zqG}7(geaK+&1FwyLTt1j6(hD(7QB3Kx~|kBv;dfM{tj^By~d)kbW290n->62@)-GfEy_b7!+$n8I@C6>%Ne({+wM>c!iSYoH&oexu&VkPESAl@Wah| z-S78TS63LAeUw#WB(mht(<+*CIAD`NDyV80GcBUKT z4Cir3)vE{SO+Huv$AJ7oW0~P$A|jX&0(RaQf{V7j*z`#=ee2~?j0O0K{Eh(9J+HqV z*y7Snwy1tzu3AtR$cfgn>0$mPcxQ5|I)Jw{yHp`ayQm{WxUS|1MY#I2PKLHo*G*gd z(*{kq8^+zf8|G6lhJ8Qm`*BY!cQ#KCHg1M7K@8UEx)zA!C>VEXO>AnsvqG$Lo_GDe ztXdG#hh8GtB}{yzGRg%7rD~hi%1Z7Aiy9&AR}^v`573v4Yvy3;1vPsYDqqF8Zran$ z>U?u@wpnjhbq!5IK7kX(Da<&H{piLNr-_xHi>ob*79BCLt!2Cg>_)-xxP?0Wq4)ul zBRh@LgbHUdyBEfgG}211QY}z$psnN!QtCFmYh9So;4Fpk&GZb*csH zwG?)-joaa5wrN+NfBM<^>E>^K_T_K>?zbcR*4~WWt@p zc07xWkUJxh`cuY$Jx!b?#WvQusT&Tt(=r8yR-*ioCdTQBb10^fy%{`WMrL|9(Sb^` z7(lrI6BJI@C{Db20Pi?Y+$*!S6E&5ssIG0B_s`GYd+$B(!}f|bhvXba)9iSw6%y9Gp! zit$oaQ5!AHmz1!QB+F_FInf-MwzM80mee;uBVQCe(U`d3@Uekb^*2jG9xw?mOQ4@v zIi!%VXoV&lq^Ic@rKbDqASmZcN#2gRncfm!6?`_v8>$7%U2_Y1vBZ zvdbgKaSW50F8F#uR7~yG`_~e*>0gg5Nd_`6*u}ti_JU<+VxK1lB^|+jGZta6r>xp` zvsxiyGrk%a<|>>x{;N!+dC1^d9T_`U?k9|E~3*ay}@Tx959+*N5#w@|f$qC(R7F=->Eh8MC z<{Lw&_|4J7Y=y_D#d>h==NBt`966Hmv$M0$KmWY0!cV{W;&;FMI)`Y{v1w9q7*Vfr zIp&}@Et`7e7?AI`6!#~m<6)h8B#vzSBU?UW`+(;n3RHEqYFBHH3aYbreb;SwyP=+E-V}gc|QAnb6b^o9|tray|hh6e%NR`a)xTHT0%hkALoglGGaj z^8d5{@L%;MlC^cE3GNnW9(a78D-Mf7{PjLWf}D)VAyaQt4K_ve3Bo>^9gcYtLa^b6 zGGI5Vt)LjAq8O%AqZksGk4H5xfAiea#A;>v8cowA^+Pxa;!{qnnTRxte9!Q+=~;;j z&Ma6Yz9^X9)XV&15z~|NLz;Y=u&YjE$f=I;WW9d>{MqU0=`akJm%FaVYpG@>0+E;x z4Yof75dr~%;<2=1-tp~}a@S!9k&Bnck4j!XN645Ia|`ximEczo!SMeA{GiWuRa5hi zp|qZS$t4arN;Jm`A|%x}Wp zF@+L^mS9I7Z4zOE#O3L854oPpw7I8@`!iYt*1lECN!0`%FrI)6YF!2sfH0K6@kr<@?CIwa$-`JSK4SycE+BiK zocYCEhX`KJ4xh|_3Jhnu!&V`jV>yWElW1soL~yt`JW70q~~6gk2igUeSx7v^;|JjBAxD(1#C;^Ye28 ze2?RP&+aT%7cETR!{+iTXgVT@$be!aCP@>+d4Tjons?&ZocG^<|MSm3Pt)+%fBn}N z7nd$nMYSj^A-?pZ%|0~iA+qMrduAuq;=ib@8VQmYHK$^7!$Af2fXbqR>Q{BV zO!MOPaAyo_EILEx7~Som(S0EZeTYO7qcYVCd~R#sgn_FN(8c$8zECaXd!1~FL;8=D z5WPI~do_pt#Fcqs;434QT*NBRCFY@pz@Z}Pi3*&37@Z%c$#cpZF4eVnO&y<|ojp50 zUp4J^*FC?uGG}q55-n3|%qzRudD_mFK3L0w^PwBY?QUBfmwEdztEoW_W=wdMiX@1| z=>7&u3d&db)&3reCr%1 zb-X-b0I=7 zDvIOOOXAX26)rq6)KzGjxL&VM2_;?E^5&;mQ$LRTktIhvrJE}*QsX#GX&kdD#dL>u z?yB+CJ0bu|7XrJ>eOZnML7?>Ia&-<#(F~JoI8tI!LKxKRaH{R&GbPqG&o$!LrVRa_vY64;;>88 zyVO3qYLX~e7D+V{qtL*al9!C2*K}2y{Bs1#Cl84AdR>mWz&XV1I}e!tH{*EKg7|yR zeeZkU`}EUKyZ!cyFTS|C+7fxz(`y*Kv2Ucl&7mtF6t=)hcpM=cr zJHum9g?0}UE}2^HPk_hBsH7=LKvxY?-K(am@)OkY8&Hb+G*I;mcS>%Dwmd-5efKouSWl>K5Xsfr@!fz$lQ+q!&~kWyICxA(IZSP3X3tx04YdCDqaaJ!+Y|iY=vx;P#|< zEL3qdGXEG-FnOfBXf;weMVY-*1Vri4OwJT5->T7+gcb2eK z3(UmJhk^<(;nkE+-_#K|IE1)aySPy`;TzI?$H1xu`}nUH3zfheqP(BOD@p!EX}FHk z!Ud$1T@0-9(P-u<%xQWSl(wq;s%h5i_T=Q`WVLRp=*>@XN}Qk2vGPbrhCR+v^Qr~f z1;Z;(wz24-;zGls4Rw>Kg`s+Ih~gkc!b8or2CZ69V9E%u;E!WL9IeW;hgbtdnJPN7 z4!e*g;#I1J2=xZ^kZ1>*q-on+1?(nLEh>DTyr~paJ}PaY64MrjuV>}yxdA`h6w zH{edHMezOyKls7NAAkJ(>)(C(<(IpC=R)-d)#8ou802&-jOyPaa6X;6TxPB${$5j` ztXHdc<(=znX4e~hDci15O?dc5nXIphh-=+pw}YSA>=NR%VkU6-7-0o2Y6>7< zn;(~-JT@MK9!i?tY^=H#nNyu2CRyHmTX?bpsO#x&gKlK$djj0En%+78XV+IPN{Z^& z=o~gYv+;<&kta-0W)`-AgeZaxk`q40JeTxYe$@crZ&R!#OR1&wP((up-sF|Ypw(B& zq$QdCWY&tn<{QL?a9e{v)ODKY;S4kr->0XCD%`5Pw<5i z)nb@fyTIvavV*X3$x7*_Y9Yl>C7HQFaE+~vpju?tA5@FMXqQ4FDBrDHZ0pSAJ^LvU zi`Uv zY%78hO=%dXei)_pNZ}Ecs(olIgE~<~(hH(?LEWmW6_Ynr3tg9=zZT__2SmcC*bcx7O868-L!I8e8=ak7n zjt5N6Y`4xuPt4LPxRX`;?CkWtXV0c-+HSX3m)j}1z*zz~Q*&g+WTxQ6u7)aBw$+^2 z@J+)(93w${hb_T*Fz%`fSawYvQfZeBm5fDcXbJE#>z$WTYF*x6-sqkc-j)+~$8oen zxO)jeN{yEcY7>>G+?RY+2K{NT--Nome7*z$zgV>(izPJQm%Jzyfj+&R0#Arx1qag$ z%MW>C4)+TO^mi7lT7=uWuc#IXwd2Sxz!-=%d#H+9n?|?K%awM+frt13rjKDvt2t)>u|fE_$UTj>YzMkIE2UvMKs}Os4=U? z5yW$rupEF!qF&J0rxy)sYHRCxELa0_E$<%#RsUg;a~74F4#{bTy~VYA8i)Xn*=ym_ z)YSE7pMCbd?|t~?&wl#VS6@vWogDKYREsyoW02FWc&AhglXeK_-89v@wH3=4oXh)t zw**K&>C{(svK1lWJ-fni-~Q_7#eLlN3zi@u1qE0DDpbX7ge}5 zppXhr2Igqajj0wY9;Gq4XNh^lI>)iZ&c%?UM}#`ttlxX@{A9D~y6*Y&=lgvR^NDq0 zqX^Q5BIHW5)T!ZGCC~x4Dm?pR4a;Vs0ZscdX=ZLlsTQT7N=10|5=sNU{Jv_cKr1?4 zw`|8$n)*bIuO~`P{bhxnp*Qu1?sY}RH9vHHu3D%amLTGmzeNqu=jwE2O|UYbWm85} zJ;WWpHBIDTQ;gqnX!+~qLP}^WhIuw`$DpP58(4m;hGH)g9ylO6`WpA1s#>?rs%_3r zPtMLZbb5Bs*1%RJ;;E%PrfC?{V5&ur(mP7Eupm*%`AGP7Jak@Us?b2C3=GTQT0%T9 zn%H}AShYYsGMI`1dDve^B6GN2rlI6pD9KVfEu(0f6$}PQz#4rc-MM89`pJ8Cp$<9{obxaY(=`1*_Rf7vk{dbi z0P<3|uAUikDXqBTWx0M~``Gd$==j+3|2~%dB1;Y>YrS51wL3F?sas|OKEL=fG1=AC zoZ@u%baBLwhdJ3RH>vC2{N^_=Uc7ku-EaT!hd(5Y z%0hf1ItPQ;DGwziV(s-a_V5_&bP!K$T97>)WjsMh7)CT^6GC0p)5&BuWlNdGi{I|H zjSbg$RUocS?>D)MG$3G8-`RaSzKa|(E#!Ww^u@7+hp_?WsL0xmL z2Vo0s^P5kF4^{xpr|0bQ&4 zUOSDmz}}@l2ugn}#PuYDZ_MhDb}N?Z-?v!-n_?s#27f!qf?`?km0E@?@Dx8EDF-Tm z7*u(wA1b3z5VbbvK4x6KCOGHYL<1M*Q8}B`&zEQC%d@g9*6a1v)pgr--gAfm1R}fy z${U+u2?j-(XVY1Qc3d`XyE7L8Z)Xe`3DLr(BysAe#f+D+G31USe*9#-s;MgLngJoq z(@aNzk6juv*+qH&@lZxmOlk7Z2ufBz33{1kGw7joHQkHCCU(+pZx1^FR#0unBN%*EWA1BK|b&=eC7Mo3~FcdDd5wA@?Sk7HWEN z6nO<#l`wP5{%<-U;3I(cKirG8-i?$Bc0AC>#g=9XU=N5x#9Dm-3G<&Cr8~o1oTuzdjAkdSCg?!O; zreyCiI0D2PObegVVm|xkn{Q^b*~{;K`|8yz4k(1?WhO54wc$zZgiNu~XKyV3xbYax zbWfn$KOyiD=({;Po=l8*Bq}0gQrGkOY%-}`Oij~m)*La4i)M_B>C9RL+(?tLQ$h8!h3)C*igaLH$?%_jj9@9^}=J|@lrkp zs^(pIlCs@1Q#9BA{NMkVQc?SYznc)r_?`L(qqAG=d5e z@%lW^M(Y!eRWU|qs{zu*HMD2~o1e_xK_w}QVm`wUIP0KdPz@f+LSSXT;#7xR9^J^O z&{fsPn=6riaIp;jY%zQBY`K`v8TaZ)cC?x_?27h3J|1R*p5hP#rM95n{6f#ohe~Tb$DSefpKPkirnNUh| z4D}7!grYo?D=nslTB=V5HTb|Z^C93BW3f|d+;P+Iz5HX+d|DiKhzf!I%2h?6Rq+o| z5FML*MDPs#34IM}Biej;R+{%<5jc2mHk~YH)AQxod``b;w|KC0vGrJY?4z(aQLrD& z`)y0eSYj(08z*OeYkjL(Ze*7^O5JI~z@N6HpqDe0f}oUhpOHST5tJ?!7^_(Iw(ctBK>DR-ui>&G3t>J( zZ&vVi4L|xyh3WN%$cLdIEVK$BuI;N}h&F>|B?&173@M+gGMq0L&(D{$*<`i4UaeM} z?asMij{eMmQ32*WN#9Nqz!j<}Lf1u`-rMYUY_8DB5~7=~c`zenrvc4O`$?>UD2ge0 zy15Igj(AkpWYGKa&YD`-+3glJQ?{HcD`iVxsj;m3T$QyF=N}pwa_LEiQqWgw4z-}1 z&_s4#=8)+F!Dnv+Cnpy}K$Vd@9F01J@l~n#2l(X6CmxoLLolUz?_D_=YSlukSP(g- z)+S;_b5UCiKW--OQ$Iz|>Ib76s}@BFv&m$+m@k)$x-MX?HH#ApxQ>Yv$*b#9%Z>~7 zBHKO-4!CSh=Z<6U86IxQ{u3F%{nH|D`aiq zC?tw|6BJ_TJ3kC)YEGvEg(x|M;?mz!9s_UQLjLu!A(D#7TKtrxRlppHaY}w%#eXcu zrUhJUl7C$Hk!cZs@#&{ufBp4tw|n{BZ&$08_n}KZdL-=_NGO{aW|+~qV1JI2{fKdb z)qGkRj_3DKf?%>2erD|gS`mJFQYlDU;mg?eCsS>9yO@wvoK9LG1{s?yB7_+Acrzeb zgb&FCF{exmq_7RU0)Iwi%zNVmn_f`CvQZ()PkpWWy3v~t4rTpRI4Cxswn+EP9n<1J z{kOmW;fm!J&6%m~ZPW(+xWZg3-ATwVYf@aFsN3j?h6jBsMTM(tJSV)@P@}FoqAEKj#`JndD~MC@~jnz>H7M5yTx-rRg@r$a_)#(^aip!ZD5D$z*iBCe;g`~ zRMZoHhQ&8>GN_#DTzXS0t3D;>C?W<4wmVqS7J|9|ml0Ny_w0Ll+U7iYu`N8D>Q{kSuV_N*j|N1}o#;tKZ>2JK&=cK_y zql*;xe&lA$h1nK^bwQ^ZKzA|iQ)Z~{m8pcgI-%y#ohe&y#XTAUDJUaN>&ik9_`vj! z>4ZJXdG=RIbKYpKg7u{$3TTi1$pDS$6cJdMq9W8)aW$clnV@H=! zdYe~MrN#}EAy&{&x}u}mSK7d>*pZ5DrQun29m)9{1FAk(*_5n6_Je7m=enxNR7ia# z(?Z@6nex2n?hHP=2Tfgjk4%Tv3MOxqlrp6RJsATA9s>N-Q80S4${>!_RXVy(L20Fz zCzjOZPs^(YH9gE@+%9m>*r&hVnih3coy}$ooP(>b+pSisX0vS*?uCkzWLvaT*Cskt zO078tY1$qlrzq26pfJpkxkA9?MtKi);fsK2%61_$iSNH^;bO~aRD)@uVyK&tr=8ZX zhubZBZPp7VVd}b;bP~D5v@y1c0|C{ywAkUhl#pAdcUpGv9flW@@7+kqMq1(hAWGi) z7D4JpB3Cb1@%AAid>E(z(H1Rr@@83=E!3@U$|V5Krt| z6D8sGqs4ar)s;;yT z-;bU`77hqxL;m(>)8fG)+CCKy^25^>>7Kb`TKtFq@;`FLZr?C=+SHDq-hx6iOioLQ zq#NKKWQwO*7j!I>*D@G*VX!VV_UKQ2uJ2?pC~-Yu7_(j~?~5E~sqe|79_t+EWNW2f zYCT8mkR zc(tIenLZkr71~7`MYJDR76t#9X_3DY^j!BDXuTF$nF`qGuB%eeJq>JQHbQo2Baym8 zWjk_8IQi7#7G;5_l$1Q;_-9BKaISLUNcO~$aEQVbfLx+B|9IF&+X;3%rqprHLA|9f zjG>n^#0jKF(*dnou(i4@my7vyS{L4JHmlWY#hEMUUx^XYbHIl2746b-{ELpeAU9gd zC7BlLFC=Y{c_S2d%wJx$AQZu_VbPY7YAB-P=o|a}EyPY*n1$z~asR&=d@#;A9#3mpL_z_0mLUPm zU_t@$0H5I|$w)e>>q#}4PZnj#D8Je5R_hf$%tW#2G+Md97ZO|wmM3b9$L{JQp?J%a zlCfHw6?5ua$$_6uiwB1q=&6w9{}@kOq8o&C6dJ(eO zUSM->>OnskkSDa9d#iM^J;96Vpb%%@%3TwcCeuUC!f zPDNF_P@)Ku8FHuQ@Z(ts#dgbi+XtsqsT=F0kxL@VrE{oFcJv+u5ir2mZVMeWnJq1f z&u%F$$Uo{Q9<|i0B6?F=U|F#b(l%diW7OI!1{k|$1LJI7OUY29izWDnqSLraHVx2E z8Tv}bCw$}iRt9Is4z#083r}<&+=A5fGC{LxG30C@{7ccV1)MerHAY)OoH4X;p~ziK z`LmapGa55Q!~BU_qzB~ZN#N`}c3Bh!5u(_>T~#r**VmVu%{marB($;fG`38O)OIvw zgvVmnn!fG4v89WFAWcG_k!Q_Non3vuuB)mnDl$cbmuZ2;(zT7np@z58Teeay-U(`y zTB7R0IUc4n<3Ytx-z+&Rvn-2}o{v-_D|%2s3TPPSIaX7PA6*w?yJLyMU~#3;7L0j( z?3D)?4BA@3xqBD*oD%Ls9b}Ayb!lu3O7Kl6p>|@v)1wL-v zX3-~y^};6u4jOMukWCA$jbME|TCXG`WjR?)=d&r1_qNS$wO(t-QPa@{fW?bo1b2== zu_nWq&oJDq;qWIr))+1&V6!DJRY#4L`SWMf;=v&bKNSW!b^}jaq7duABj*cAjbbATwX}+=g8ZpdvO*{v+qmcR+4=IUs>=0deSLLlC(+_tQWT{R zf$y2p@KsSwCN=BtUAHz@s9i&dBqfL=O7OukTRcda$jE2473n?kC?JR|uBs|S!30Qz z8jPt-F1M{Vbubc|4oba3Aulhi6qkbMTnH+huw5)N@4Tq1u8TW@=Cv;M1VOTSR4TpA z6u1@FelY#sD8s|yCXGO=4bVG+gdhYojN*PWvE%=Gwt@3`ny3ns57u=Q7$1PO#KK& z!ExiY#dYqb2h$peA1D?GqpPh-*26F@0Qx%Ru(YjQW?BFW#$yA29E$_*S~_;Q0ps{P z08NKhHSoDeq-!qsQ$bx=(?cqfRuZ&CJYKj^UG|_)j>PSkweBhhOJ<1SSh1qFRi4P) zh)Z49F6Q%ZzWHXcIQ#zl@Bj3tKhueli3o(;J|v*%3%1g}|MSO!+w^=09N_#r05cy0 z8tV}-j?whPFv%cL=DvnDJ|Z`akRfmw?ws9}s2M(l?QTm{m+h9#YO0(B1STG{YZ_Q?9#e zCp=O)A1T>mfRgd=|Mu_ie$`wCP-h^7Xu&@=O6o?^8S8>0?eK!t7@6$ER!wv|M?k=CkrBCIEwSig74V7D zRtIft*zGtQm=_J^7-1jVSfX_jRRnVa&8!E73jv3xvREw67K?dG>H7LwhgfTf)h8TD z?%ZTjS0#gAZ&z$Krf6|EhTsZx$KX9tX(Vhgn&>v1B7h!+n4w7m_Dl%As*1WQ*ec6R zGi200Z#f(rX)Gb{J731YhILyjjW#<@QnEdYs+`XkWnFK#yY+h8w!L;M&a-)R%iqbu z0hAe+B-%pFt!CvP>+QOZp(o=PL_>JPs)o6k(yrxrSh3unNLLLvQ#TcrQt^?^X`3flAKd15r`NA>9WytJ0dHkkS@C%LQKJ?UlFdZ7$y8sKm3Mr_oR4`yj|YPH1Nr_GpmIujNZYZQ ztRB$RIxr;tG0<1132Nwj&b)s^-^SC{9iIL{(}Ia>G!3JGXpzamooW1`@D$OrO+3d13*bZ4MpoooK{6zm;u(oaIHv8=L2<5Obbnprbvn`FZepS z!pl>ls_Q<$Yc?U&UG?YIro9EKh%XX?Qar74>UkByY&Kgimy^k4yWO(O!cM+J%?jit zN1YH*ur#r^-EJ9WZ8HW-1Jp7w!Ue`fiqSAvya)0dAj10Kir|XETPWMUI*O5n2pd2x z2vk~hzHmq;9Qu9gm|8SLKZH=25cEa0-fULuZ5I>vkP#X2W=%%jO$LhiRL~|*xHHK& zzR@SDf>OwRLqF-E2usQXk_$UEsDbzH0Iw2^k9VX-m}OChz~K*CxX`C&zCC5|*<9r@ zRO1_@a~_k=Ll%7kGgupC(?a^OepN&0D(HTErJ3+YA~!UoM9Q<-Y&M^l^<=ZzTwY#o zwoTsGlM=l$w1hoq*sNlv5|(#IEM0t`5`qaU$w8$P zgw?XYW{5btj@#>WAo(w0%VwJ``&m_&_eQSo7!tN+$?QpEVaW7aZ(5{O5>eT;ZS%<| zFMj>&Z=4U`e*4|)%PY1O-QDOvn-=!~Bj$1FrOG?;Febnr9?Z0O3no^|P*r`<#SlW% zMlIa!c1_zhDZyIIBiaftf7t38P6n}KaTPIWYZs;;l%epfR}{9!%U~*q$?t>vr|@B* zax#n=L3Cp}0{Hk$3;4mH8>s;g3z77x@J`brInP!C)qi}I&ZMEm2Kr(MYuUf1z9Cg! z*St%cL_O2YNcP}MY!jwGtCCsGg2#Z5SzGAcq{MUdHe0pmSSrNrLeGQq(@=1Ho$dN% zO2Hrp@w|o}ZTfP(+rhAgToKdK0E&nyd~6Lb%jMbG`T4o`{_5)L^72xfH&k(R2my+X zs7)ZmquXw&GfqV$D0Hr`QN$~Vd@cVTjFH1st~63^H`2btPqh+_O~=@+c~^-SA#u_(&3v$NTJ-X(W=d3kkp z)wYrC7rY(u<|V@$fQ|$7!x5&1XO~6AF@HLQQKp5?#9)D!B=NVd z`OiJDP)VR%dN)na=U=bBx+*=~1j%Yq>w6J{}3P>nvY z9c(Y769H8jdR7LdH)hcj{drPQs98me^4@D!MWSF2s^Bp=Sj}MbI0`Jzyn>x?qcpXF zJ0Pi80{-l?&%XTf%ckwV{r2U>HHTW5ns>O}8Gy>4S1sNT$IIJZs=O2Z@bj=pKf)pE zNO&I$CUo$=o?4W7AIccxYQ^r#-417szB`-bve`ujT!%g*)xcbpk#P)a6;ozKjILt^ zj@g-mo#;Jqus59`R8C~QQA;;@kkmlmlk~?x$(|G>wf68B<$R1Zj|bZ0J60{QuZin3 zrid0L)cj@_2%!jcA`OSCn3gQ02Mat;=-K%7W2!U#DdoGa2#+6ZB}7@U_tK03aTN*# z3EQfLV5=5iDj`C_ry z?RFOz7poOvTcstV>|2O^)SN)Ao2KdQimtO|3Pv^CR1%!`a?HTKYMDe8m2^cFEBY!6 zl!PSNWMRvu)RCdJ?6*!ztFr*LpfS&KcFcEOS-5FcPHIdM_SsgYiLY|oG#3}wm#g)T z1|e&;sd9vPBjtty+~E+FzY@_@1*#0M^bbX6Js~M;QzKN_L}#$Oo28Q!R^(e#AambY&1D-UlP#yWlIn!;i)kSkb`i=Pn_6st-ZF#poltG%b zE=vc?6n22oW>}Wf3RCxs1(t@5GV_M+N>18Va|~X<}0X(c%lbUTgAY57t0O;b3pdeI)P8&#z_E z!odmtum0+npMU=O)%E)2%kQt&8}n8bdmMn06%)o`p!xWaY4xCBd^!%dI`|!U6dC>) zrUfgg%#PxaX<=g~lSwwM2~2OMFH+9tm;?=E@Y%p=$Tb@oZC9%J~>+9uE}XcbFCy`CTcFiITM+^^L-& z4lDD$rbi7OLt3LikHKV5IPlQnNwDxvla6+LMClT%7UC^jHB9AHYI?{bVoICFc2IOS zz@UJznplTmd!XP*MHHzjHa}?O&@wt2hWEQe;Zs#37}+5EVL6|ps8!W!waVU5vM4ZI zEPTF*(=<3^Y&ILo1%|Z2w16PabqRMDDul7XN2-^ueeDcVMo}zLmiUCt*z9`;MbRIf zF_~aYspGY6%VY`aR9h8cF`dk3lj(#qBDO+^$!)jI#pTt-^=7qgw+#mw;LGkqO03YT z0Lq%ep%13)oMxrz5eAK!dRar$QeCHeU4>*IDKm|*UP2(;XF}Ce$@81K86mpZp%Hr; zWt<3HWjjw$rnSuttr5mM9f+QpZgxZH0nY{->MrW>hK(+jIjpOXh!ypMYLuy}_iq4$ zkP)lvx=>VSXJ_;IJUM@H1$G2HU{r&j1N&<1eG(T*m5X{P%xQS1X;B6akW&9rJHml2 zkr%AZ`vdQ-)}8rHtC9#Zg(WE6Q97?i5xv7= zWTXS5Lk#LHKY0Sana?8QjhsyKtg1H1YT*JGDa)E7CJLq-RZS(-kW-fBi}Q07wUjO| zFR!n!Sr%~2Rn#?`#T7mu6~=s%1P!;8(>V=nR#bMltB06SvJx1f`a6TlAgY@BM|g?; zD}(5%GGI9wY{dh$)parWSeM0uLw#x-(s71jFFIaiyXNxh`t{ZN&DDCf-YBXap(IiF zP~_BglWC&dyN;991_7r6Y4w1AMz9J(RFz*>4cPk1$_~&nL#f^3BED+J+c$w2j;$>t zL%_@fQp6Q2My3Vg+7(LkNuWCJLGp2*dR?1f1fZV;Yo-d$G-LwmCSUckp!7}t#@L~0 zrIaSq`T6;IUDvy&dG&@R3;KvD0c24WF1E&3eVJAA+z?sIKgP7sszp95c5l_f;gKf< z8r`$=o3lDh&&V|rlkAaB?5zsgoCUYI1%}>?8G~x$7wH1ahlLTu7H|w^l+y}S&Eteg z>Zb=agsvH5D&3Y9rvUXzxkbq{B&Bq5adDrrsn)ll2_1D>Tx*G!4KjmV_KlJ^i(Yi zuZ0WSaTIKRaci1}oI~Z0$p`dqE+}0lfKhb%VBdzOjk%kvXC0){kHX_L{li1$H1dpx zwjQ}}Lc<>eC3{lHDxB)}cx8Lqy2Ik{GA%3s&j{lZixmVcc=Q33KlKna0-KQ)5v}_O z&Ww5zwTMQLJ9yltZK;uDl>&+bT@kyVO`8Vi{m%AMw;i5|WNbNcYMM=`D?1(j15 zK^9HRMnb6|8mPp$S;11TmILvp&!6kW*~`nz)oPW0BE;>Cu+}lMe~T&G9alvzq63%{ zl=CR(sx#Xmq9u;Bp@OO-{|pdq`P_(*%(RdJA|mT21Gx~~AC!}-tV>@8KcCi%DV`&2 zZMAn;<_JY{Zr8;1ZhLjT`SZo~<<-^odXr+Z{V6PtSUHqFZf$sB5wtI=p!{GBp@Q*` zl~6Yto6`t;RmDISi1OU5mJ{pX>cb@a=K8X2)c(p#shkoq35Rnah=LjRV-YTWvMeRBx$oiKEAX{ z?KZHD2lG2SoW#iXp_C%0v7~M`oqYM_mmF&GyWjurcmD_JM(jW$R^LugoD6@NEXv@A zj|+E^^nUnhm=+9dNS%iSLd^Gk!j|r;BtB$SO(%8Xeb;uI?WWyr*|cp!3n_=hLv+fu z!fB9Y8k9(w%#k5EAF`0b<23!lL**QgZW4V=37OMue&P7M^~s4qB7F~!TEa(7{GFhW z{8-aMkdkekr3dQ<1(I6AS`3k=g~TYmDxdHU!cE#dWAK$Q!dF#6fe;3ykFL)=CrL3) zZ9Dlii>aM_8enYB9)~EKM*ul56;J0nDYg=-hL#o3Rv4M2eu;xM98xOJRK)rD`6thw zbzQewt*)-FHk*z7tfm&wTJDv@MruGR(qXKN_@YoKIw}%JrbSY~n|C9j-BXL(5Z`Eb zV-do%4AUwsW|L2zpFcZaRz*miX|bOF*f;Nd+jYCP+ce$9)%w-zi_5FaUEAOg#l8m3 zEJ1!}8kpVT$1M9q1rX83S5cUMa+4Va1U(-E8zNNV5^;!Hgs{Q}C1_a?=Ss{lhKyA~ zktlaflZZ#u7vo7_1?D=2N@CUOfqI?#0YojR`f3Y}OpAQ3g)|<~Q?D6Y;a5f<3n)x< zD2{|922@?w%k$^+`Fy+GzPY%(GE10tF)g2OJ$o%^Sx?ziCQ4vXM*YGt{o15Gd*H378n;m)l>z;sCE(~<2UU%8kQ*3(bQ+v zx%9cTPYDDl(>0OZTJ-vkULCNq45VvFiL5^i4(6o_?&07=L5b-4JcPJ|Ga_$ARv732yAyvw^|m8BefFA~d1CnCKt{1}&!j zeaC@;U~F0hjyHgG?*wBa^uGa;vs?svqH|Snv#NN$T>Rn}FJ7FVv)$EBQD8AB6fve< z+ifXp*Ccnn+5P#?uim`5u#*SbPtTESMPW8ZKAD&}@r9=dYGq|-4fXauKh#Y`c)o=m zj!TPk4m)B1R5C;x&g~W`3$v<*T`40-`pC2x{M=eQZP$<9`alrpXZrLdzgZHhWH6uK z6l|c?JEDw?B{|ngZIbaTRuplRg*0#VFR`DYjU8uMEEbEi<+Hl3FE1}IE-p7suYP6U zq(E$9r-dLTt^x?-w(GDq;Ro_%Nuh5_nHF?LydQDND+*517*;I~nHHWwlyrP5TxZp% z@Yar=u~&QXfoav++Oj`WEiRl*!BZTghxl96*J z*|gqaqyv_M09;}Xw||q`HK3e#ka|1qK#)VlA-d=9`VCC zST!Xg`L8~r*J6xyRkTfGrbTytzWnN|FQ?Plx8J?|*MI#}QBR2GiE||_z6Z%4r7Sg( zVZbW#lYl7jbm)8N5r8+2!B5Au07$Ri#_)B?`L^>Z2bI=Ug)N(qPK2336<`sSLq)ML zI%Jpju%^_s$fveLQt`tr9PB$!-SiI+scH-Ws4Tr$&izsK)m5UKe{LfGdTPimsGG-- zFeg}dhW2-v76;Tj=_R?1MY7=8x{Tsu9?yD5b(TuRTqfQd^ev`EQ4W%6z&&JI;ER*c zs8E|+YP)`L;(V+@n=ua_z_3OwXs}4^9X`xZ?ur&QnXp(NBm240-3-b|rD__cepT$M zs+P;;^XJc}wt@T2n>VY~%6rd=0khfJ*_i^BZ~&*-6(li?NgA;_6D=(sTL@ONun~^I z_x*r(b1ASefdyl$Dd?1p8BBGXBFG;GwX$*_-}A_{L+UnwQVq}xY76p$9k35IoC~t+ z#x!Idh0{6o`&*DVoQ47^^%~7OQiQiJJw7r8$k^QQ^dw)0+EW459k&fk3z&9HMpz;c z!Ba_EQ&$}rXzGwnNo6b5oKV}jQY~}tpy1M~RED<$r(M*fdP=u~N}SERD9)O&>kd zRE6BEx)EpYK|g&=PNT=PB0Rxp$cs%xL58zt>=@ z%$RoBw2&d87c>=`IR>qTDM!yfQPN0xuZ8!HGq604ReBB6BF0_Y+VH^f7gbf+*}G%` zFPfI>(I1$f>{6FMM3wLOQ<`5{a=J}jv&)cO;I_!17bp*t3ame<8xxCWIz2x>UoMxf z>#nb_FD@>crm5?CKA%sg)7fmM^Pyx~C>_dU=v5*WX;`%&i@~%g*t^ba?*tAsw_Y66 zTts%gX;Hj*w*2fDFU}W>s_%`Q^hoE?<-9d($ryK z+=O!1=d52PJY;rlyyvj=W1(WG{P{j7qIuk09f80G*cE*RRZabbvTlClt*K4oNl}c{ z(UPH+)Ny^nI#|!fZ4vyEO%~@>JzcFICVD{U ze7xf{ZmqE>LX_6-WLi*iT9FrMZqq!h4hR`4>tgA;K2+%7+^A^?RvU=yPN`G|g)Jk& zj+8qVE>a8S`qT7CIT~qye)VET7_y$YCC^B`0&6yOs+vAzK8BWZ>fu0#SPp zVxB!5d?+XpT~7xpkCBu0-l9PM%PmTl^YKMhQhQL!KVVwmXy?*j{KYRm|NQgauKD)6 z?>C!G3Y)GFp$(rPM*+Y66mXDG9}vg4>9HierwqS?Adle?WeiD%#Hh0f z6F5iACe^d$^4a>)B_xQyX4xo+w6ARU9;Nkwsylh21^^np2?<#Dx#}6 za}WCIBZK<5Obb;o+F~`Mi75}ds^{|0P2^us2M5LYW0dnT(!3`a_3yK4A!G^`fe9*^ z7Gek?Gfn@{dDF9D9Tz(a0bH$}>w&r!QVSTTbh$EIi&S zW`;%Qo2KI&u^2m-Hk<9M*Kb~5T&xH}-)$Qv{+%zP!;eHtx=ah))hGz{A~OSRW%hus zf+V0Ss4KNLJvA2?tlHRdOpT z*vmYN#S!qwDa=W4^bly1fVKneb_5yAG|V-X7OpK8=MWmZ%F~xeOsOSg7W3J38k~iyYuRy`B8#?N=eB4L z&DHhldb3?`woPj?%_0qC(_%byiZl1{)J^~Jki;7gOd^76I=!(K#ZshWm!zBx-5#SAPOP#Vcw%AIXtAAu0ex0WE~|&lzwF`bt*W2yZ z0y-svt`cCxvWli?rO9OS{Q2{<#lm@i_2$ibvuWG5uB!QbKAB9M;|L4pXq$d^St}&H ze#X>SM-ZEc#cfeB0R^*F3!7eLrR5kLT(!_{6jqZ^qymm4AW0QQQlRXfc9QoS{{(`?qW`H)ButppAx|c!X$7dnY}0;pGC>9*N5z#E2g`@` zrn%>^^rPUtcg}h5|37>0)+9%c+ zlU6I~Y3;n6@6bK>w&@wNNmf;6#tk_3^M525l@%n5*CN~I-|VQ!2n678H~@FR0gws9 z{Bv?CNt$s&jA9)zrVtsNzm=z-_sjrf(_;F>Ab%k}L5a8d3MESEubX@K?yXj<%d6d^ zM~}L$^8r3939Li|shb97QBIlxmB{W*U=e2Ojt^sG-iVT=?n5xEhg>SmvahIvMJTAw zZOiGi!#J8>;6yeZCZK+@9SWo~YoXDHY*fra0tW)HiXuJ(lU+enK@*r}S{!KOBub2S zY;cmm7-!JI=&VW>XcgoePH^nT;TU*+e{d`&3e`8T_)t(Jx_%50C7ED}6OC-maqODi z9R`jWy(P7Z@CX#{4b!41imvO*!pCt8E)~Il`Q;a%fBw@y|M}6^-~7s^vqDU%EbB${ zMm>~b&Q*Xe=@Y>sqdp*RTc9^*o?nEwY{Or`5ZZ^C4H zc7Smlab+Xr(j4JvRu?=ixCUQYgpgcBb3l(p#dmC9h`Pcqvjs!e;~4pmICSc8DGzV< z9xW2jBk7u;aSR{2F=P{?>HC>XqDTw?=v@9`7~8(<`aX{4p~7Kye1!9li<^`6gM0Uy zRo!>}vy01i7@SM1x-sV>+;-bNvz(k%0S#zl)iyeC!_KVWV54^I%>0;Ja=x_XBX?{0n64JwPem1oD3aiw`sAQO)l^ zJaXztsxedIq(PjjsyN=%fE4(t$X<>d=NyWklZHyXn`C|~MMgllV;9<=|NP;PfBfTb zzy0=izyCwBQ4H@nR%J2H40TM%%>nt<$BdU}>iy$ZrD?b=KWQ>s7_rb@)(Ktv%@R}$&jR*_D6b8QZXd3J_ zo`@tyc155f8E`kp%Vk>7iBHjhPlUc=vI0#S!=2+YT33d&Wz;E)+${0+(q~HCfY|SFG;IoPq- zh2%$U6pJ*XtfZBCa%sS-$@B|kU!PbCBw@tcjTufyAQ@ZKfs7Xg^C|;UO|!#n-aCNk zdFPnROvd6vmEA`L6TeiNWNKpJ>gq~u#ZeY+&plP@(zfwPDY4g`Im%X5)pz^VY8Csg zX{x{do1dSbpMUesuO5H@WE>;oJ%Js-kJ8N$0g_3Dkp$)dA08stjps3WPP?-`7~Z_x0n0DS$_s?la@cS@e@D` zv#g=DhMi#DaWhT>h$#V?CdOraB*?* z{j&>gbjFz1!DGQZhyXi8&1Nl>Bh$_&-AnWkIdvLaF;UIw@NH|URN0h8i74WuK@^QO!^b`KD5g4!sW?GP>LA66V;x!OO;XEOgcMA@ADp_5{Mnxj%Nro0# zsme%D$=U()58oI^DZVS@qM2jy;XBF2I|n-!6vb+_s;X+V9WvUs&8a9Oxn;Wz^vT?` z(4j_USq^>MG z9g=#Obfr>fNb)lirkh)v7W(`Mi;c!&$PWg!^MVr1nt*wJAxuqW0n8bZtV}^d7)#g97`+s$VI=Sr5+2rK#ZP1ia&f=t??`Ffu+m*(B!R z6SSli{b|xyP$HYAs_UlWE9y11eYC{)MVJ@`}v+jF)E*cc_1qV4-#H_$<{Xi6nTBS3-r zpe5rHX1m&CW1`|HAuQgWjYQ{&&ijC2W1mb=xhwC2?iG(RBHqpc8H`q7V~djq%K~QF z>=1FjF>a>#P9Whq!s5fX?7iLxR63d>)_U%g($&=!MShqcllbZ9ZJ@l%&q^{Qu_;Tc zOkGuR=*IT>Vs8b_S|l1qj()-w zx!9~$_wSvZu2<`I%^oU&VZM{9T65$|>W8r#Svb1uhh5u0z1lvzyu6TUF~&r%ZO8r^ zq-+S1e6@AYuZLlyIc{H@7Fn7Tx)WHwCy0RDP3Y%Gjz#V*^7;07%g^r?-Z}rj|LcE? z2zAoRkFE!p6Nl*yx=I9|3%b3+*BKW?-sT=%99PU)^idp&O0Tj2CDZSv2e1K@L#Z8E zS!~LpPeqAWQr$FFi8g5!59L6Sqwt%SKn4!rp><|92G8^b2MPO7S7lSxp(@8QcD6?Y zN=yiK;ZIi0$*K-Mb-UfwZkvkQg)*juYgS|kfzHgds2SxD&r()1Ed;Udz?oZt7>$z} zZPgXM`7osbi%l)dGYPbAXilLiSy^lL7>h{Eh(eb#BLS6NV}~p~moZTgSO$i&lkJ3j z!k_^gOyi3fA_qv*&6Wmy_6)qB!38v0)`6<`=bE%jz zEktu^vljYFBoXKZc->hGQkr2g);Vn%S-eHRu7bjNhP}9#X<^(hBX(R*zL*=J^i>xQ zjED2eyJnp3-Me>weqNU4vuDqqK7G3HdJ=vk(;`Pp$L9QKT=X7iErbv$NL5i_XWQIG zVS6vNJ?Fc#)?ye~`!7S*F~FSJM&(l7hmm4 zhwy;W2Yq4yMnSp0*Q2t~=Ym$VAc5>|fN7B>|BZ2!+`EGEdxXV@)RT`4l!4i|vINw8 zZMR#=a6Z6W1@T(6t7&r1b+!pdjO+{ z^O#oUW?Cvf35nR7dy~6@NV+Sa+utEb{E>*+ zrpIPz&Nm^fsxmmw1}Zit*$r{mc7J~Q?Beq3V!N}wC8B06D)ThRayT`T)<@_{lJ--L z^AU*V1{NPKLh0TW=5onm9eZS>nBeQ z*MjLCtD3k)9Wal4LAsIRQNxYW94fsf9#fZ-a|IjDgwiYr_9q%`rL+x`^T{+4FLfEU z*mkC5ZV@d3QR~(7laa5gp;Oj>T>A2?d9dJZKE#- z+m2cqjPyS_rJ#XX>S!tnCn?<0O=}^}H^Q868upv(L-H^ty@;Yej-xv7n%RlcmNpQk zZCPb*d4dS|?{W7OXQZ~$_VEcT%(_ndb>ZOU9QJ^+$-ucsA(Lan#AM5$v;2YBR72fR9@ZwJPaI5({6rwbHdiz0xZVxS1~KHBp*Tf}8lZq>#Y|M-C5oo>MMXlO z8D4kRf|L%BUMtKgpWn}s2@vt3_FCYCN=fyN31^j8@#9Izv_7lFndSpj^!b`^ zvQ$I5$(XK0Vn0=&7dUSIVOf($Ku1=s}3IwnJ0*GQ8Wf^6{UTO zRnv2M-5y7#g~TjH+kR^7fA-g(|LkXfeR+BL_19nT+pZ`otuyog?+utEbo;p59 z7N?H~bd#QqC7G4wmn#e3)a6N2pP!zdpPjB6JTP4vE9Yw(9Wxkwh(7dV+_mkaCr_VT zTwY;X3~Xs*tz1o;57c)Exq-@jK=GK=v}?!#=8)d<@x!_rAX1O={_#WVK`w%P^EP-V zk=zw9E&lPp{-=_sIBiQAdS$ywR@bfW@Y2){>-eqD=C^_HvnPCSYNa}LIZmjCNHMhm zZt5ORIJQrW#moZS5PVs%JbCK=O}m83V5=|;Ea~$McCy-drqIZ=5GAB-(D)gfR30?5 zkT{!fRaYk`Y(8C9wbkTURqW@`u$Uw4ce~4ri+$g1+n&W3OnqQ`umIh$eA@`dDFsc| zCNWs>LE_}m{=$bvZD0}N6%4U84~z-h@^N%=Gb98hCx$C9b_MIpy=h8g*P9nI;~?Z6 zZx|M?uo#756xayI8E7%{LK~iDHfHXj^4k0Z7Tp2aSB>u-&6bLQRlFlTy|Lwav!|1@ z6j(7s`2e4|o2il#7>eJFQuyXW+l}lZFoS~e*1pxxA{6yO3&-3%Oi$$$=XkAI3sN$O zFq0D!&8aUYF~^K{KFr~X%N&Q`^USn}oIWy8{CKia3rrQCEJ;E;W-z2EZ#J9r^Yf~z zE-o%EFE97|{a^#M1f%rrhU!Z^@anp0!6SnTTDem_r5tgE#GGJ`qMRlxnwsjtZVL35 zZWxEQ?>jbYM-rIXKfnkeP5cDyp-J+Tow-6Rp3JXvngx|O(V3B=;t<)2Dt|5z)FdQV zf7K>AYU)FYiX>m*-vCPYokQ6?!s0_^|D%FwSa?e=7g z&t+N8xBt$w78K|>eD&2AfBpGSpFDZ;_1E8Y{ZJI;UrdYF#i7l(Bal3jGlz=)qe61* z;qINow4k3!MR2RCZ0hoKvpKW#@@%^qS2|a6LTusaOxc^i9fp0^KYMoZ?DER?e;?T@ z#W5Bp1jciwt9obUea?qG@-oLfK*r+3MSEj0Osti57s)Q(kQd5R*LR`wEPNVMzQO@9mLF#+fAr!wfel$IseCXLucQQN_ zKq;~#lhGU#BO`(78Me7{wh%&#;!|=l>JSmOwn7)Rm1JfC!cwVaf>u(>swoOAALxwZ zZqM0RGH*nHH=lkhdeH(Xg#i^=*|)d6)=zOm$+-|ZJ0mR}Kxl(EmOlT)2M8i-n#)4K za?EqEJ{XFgBS-T5(E(~KB*Ph^MM3oKi*OY3X5hJLVGE<-XNnZGaiC&z!md0C#d2o45hK1)8uPXR&=j!6@0sU0SR17TS**LRq;;7p5Q z9QtA0_p#$>6lw!o7F$I#p~9f0vJfE`8I=iPOg3!6at`H-vN?b!{(3o4xnMiAT9cBm z1U|ea9Sb(UQLOnxt6^BwRMZ%85qyh2Ov$}-%uD15N3UK&z)N0z7^v-4i*a&t()Vmp z&~+W=w5bufO?xGj7tLCj+b5HI@~xsCCH6i0`Om-ltDk)K-FM&p<~P4-yP>S=Jxxe4`m84`w@!9Ez2)4Kxt@*RTYX_V%;TZSxxe#Ca>rWrE7)*?8zhpEcdsydmuYw`(uA?9)@wc=(&EFo@5h(hjH#06W-eBxxBTR3aS#+ zxX6Y-^!*H=n&Qsk3n*eK*|H0syWmF~%IyZzXsDi}DHVzksv+Edk_!VSO$ZF2d3Um^ z&d<)yPdB#hX=EHAxK-VhRT<;hwrrSqb+vtZiD^M*@d1%(;RahVtfc!vL^8fEjXX1l z-`63Mj8Sk(=0s()2S(sTwx%g2J$*z|S2ZI`rd6|Iq-4ILu36MLjOLdzn7%ec&i))Q z*$PngS(;V|IJd}#A+r|3B|GTjkfLJKczID2vT8KPV(~+ylwcJHzpZt!x6eUA&7c># z7LkB-#}J|`q^Bw#QL>22+d^H_SHv-;a12tR4(d58Bfd^E%s;gClQL$o`zZr522~ZWsn6}-}^+;gf zQ}lS(jhuu$FeAWBhMo6ctp$*7DJw&pBF{Z_q`@AG%6t#=Qg0eShJvY;aWK+ zWvDEWw9Tr1`0%R-_wW7gcfb4YyYF`UuBvKRlmi>7(XQT1MZ{-nB~Fq_L7ynt`#?_m z;{m$;2f=dQNuDD3gn(u1xO(rKs;tYRY3j9Y(kKsz;C-@XWoRssYhrVhXj{m1`f)>Oz=ybD0aL>eLbD0W!q=`Bfn5>&<4y{JHKIq2zQ`Uifnz z`Ew0DD6m>)IBB|vpuAuI`eT8})>Vohe{O-C{U0{aGyndV|2Ab3_Ziz4#x#CF0ATlA z`JbnDBSDzJo8YHsdLx})HAExvQkq%tfS(1=@KGp2&DQfwNO+gZf?11#rKmQRJ~HgY z!AMj~tP37{EIGL%rj7$Ka6H1r+{_I05;i}gM!+xQmB1r|9*QTbNYcys z!J!jC4r7Cj$*JF!?B@EWNUEx8Q1w{^33`^PiF8=JXpv-As#TyhpE9JYCxomsv*;$An4Xl-vV&XviF}U;IQf4r~*2 z+^TwbIEPQJut{eb1LC2$cZ8d!g+OC{9b%5&z7lZrdW)=|i%?)vbo55Ru{?UUTH!hv zO_qQgVGlsM60)Htj6STf1LIFmhhez9yu7-)V#*>$$G%dS(A?WfXe8m_5QS;sI8TE_ zO;Mu;-r%QD1Xp8MR83tsO|@?5DA}Ej?E#pwK(g5!EnT&J+l^h@wQSqN9*bDTBNi`r ziHbqrN*0h%Bgwi@OKFjSybt3XFl`3C%Af0v9>TRli3obGVwLntS~Lp;!RAM&`lWA= zu=wx;Lz&f8SfonL#f--Un}78Ncu_((qgo8PUavI{(zb|+Xj=@q2o=4SpJ^Oq5_ofS zABW-eWcBc?ug=akzx&6s)DHKd-|HZVpHPG!p2$qYUmpavQk25 z(&63?nQ1?4m}&9P|E^5tg3M*CE=tY1n3x$V2I(hHdCy)qLVhmiX1Z~V1p=Y-F@HUE z@GKIwVbQWG8qSqw1h=$7QOC&@F(%gG4dXbN&yKk##pKx}0Tq12IXw?lOUeb^OJ^mq zfTqZ@!m_--Y0fq$o7D=t!lkxPS~UC)mF$>S)=wmJO}yN;2D zwr2r!KThg6$66TXjIswnI*ld4!e}u>M+!=7)H>Y^u~(eWP>#p~dL9JJ#{j2}q#2j_9Mb*r%yzjmyVz$<~f3mcF;jxGYg!{S{4MO*9KH%)Md6t z)hl8#Gb}eH`pI)n*~TeIvZNv&N7jJy_BsL^2g6jAvZcm6@)2INj9WRHH*iYyCiGn4 z1xoh-6_B342ntI!52i(MEdE)q*OCO;BI6FK0(T{#q*Y(B4#nY!x z+qRvWw!m=^CQ+=y77gl$lwx4H1*yxZ&{dftfYne#v_;!hv#M8hvszWFh8c^dEDL5W zSlZ$eB#trdyK#>x-tF72WgHG;zwMFbfsT~zqod_p!*WNMCHfpMGA%@;KG9V?&l%A} zU5#7Mxu@1lF%)*{j{05MqD-+w_?&|sVP5EW0%b~9m^^G*J6j{NqOSPXgl zIJHcos;XgN`v*;IE`GiUwS-5eh03=G_;a3bHV+?uxn4ED`OR-0KmNXF!4jqgMGBel z>Ih0b=L^xXV2XDB{OH4Xg`C9419bZjg5|uE{QKhed&0rA0Gy!5mU<{K0-adF+`F~O z5$7p9BwW)p1#3##zuRiW(Bc5W^o1a4RI{e5#+B3$q5vI`IVtHqf||G^DDvEf=tFg# zLXLBe{E*BXpe884($9Qdgp%VM>xo2+@;HB`)_5_7yM>56g7R`3+&<(d4NQxF_~mqD zp7Lz1D`F?fW2}+U-fIk1J;^L47CPiH#i_S={>s)OYnV{_{UlN&`v&4q!wLEIx?x|Y z_2h0bjfpbW=0c44KJ{$)-=p(K)?b8@;iz#;w$cK~_wgnsmCFXgwD|^{A_bl z*Dj4^a3||#gR)-5#Gu-C-{LktrhZ7fwj279GZxU@wWML(GfmL%*zW|>0&gr{C!kn7GBD(_g(P^K+obN> zBoFPQ0Odw-9y3<_Bb2#Ie@~U(EC*a(##!D7LDq?%%)v;K75G(xXR@ zo<4n=WyTduloOO0$ca%i(}J}Y_*xwVEN50vM6>ilEQ`Wd z^q7vef1qk~gKztB*S5QTyW6$9cHgp@054euWt1d`$W0lz4kdbod54`LzUA<`$qx^r zNM2NTR8nfJ_+bU7VhsliUqcTF790l(rtotpp*w`~JHNgJqE^?J;FSR~7DI}dBP@n= zrcO0Y6GG@ZcCi}dO%PuYdikXV0Duwt_na7Lw5l znp7M?4>Pq0kOf0x3<|G@?*lpMj|b@X9|X&JC;8io#7BVSe3}n}m?DG*MO(xe9`aO_ zCWIL@Ff2f-t7_e>3R-MD`g)dk@5V$&88L_vKgpyX) zsYlk&9%1oe#ys_0pn9mEYHSxlh*=)#iVg&*#m)gfHdv`1LwUIkZXfcK26f>V|MdSJ zyQM@smYdT=;yz<5Wkw2cYD&^! z4G%T|NtLn|G#4!XWU?~?+v_rPEr!bu(E_+Rj%F<&+@PB&FXkyE%T0NlL+!gVqPP4p zD3~6;2>Ekl+ffBDcLN8lte8V9#-W?c#e`*;6H>I=ZF9X|-@ku0H~Fj7IkIoE|^cGf|>xw zu^*!wM$fE8+iiDy{_Wd++j7jyz&uKO2YPSHJod$MYd-?DeT#m>22PLq#I;@)Lol zw~*C0Mo#+U!J*A~?^w<|$xqex698S~b<=_x%4)vn#3NJWNcpvEaFMQxW#2X4rUh#_ z3A62XY>d$};j5NP;-}Wkduu`stoyds)P4aCK0Z(P00le3{Grhdq--cf{+Q(Fw>NKI zf*gO&#T<}p$Pbl45nyjilm&`TjF)Yf1*Ge|HVH}vlfe>qUa>N>yV(& zpUIP(RkBu3bQS2v4O2&s6F(2jl1-V`O}$w&ptWl7xTw%vEH>f^`!3@4!AMo&8Uv<&uvtAgJ6+Xf;p54wxp%s*D`<;D+P3>G zr|%~=gL1)K#*^kH`XO%HZolug`<5|U?hnlX^9IrJkJP2Ls3Vj)A$AcgJwKyBdJGiX zSGt+kDDg0l$5$1;MpFIrffABbYm=uK=Fr<2yt5(xd5Re_y=*I6b3ht~ap+vabWuFI z>RZt^JxQss1Ju;q@eWYFVntO=QyDa)wgfF}|FW#)f+dC=6b>I<;esvD_9(|lTT1t{+@$4pF;(d$rqL?)I#@ zu(~-+3#C{qHA$+8x5{XDs%fL6h`K#-s*|cm4TW+Kh!LQ)F{CmWoB(j z;m%*(31FGz(yq!*zP<>ed44^@Von#KNRE(+nPV|z2w@n8vMe{7O<9(#5W~fsMHjch zRAsK47CglZ7c2a)KKt>PUw+ZKnHq7^ z_+#!+CgD6JV0-ctXU6Las^}4PKP6#MI#OD4%zBuS!{_JuCV!IYpCi+(N}a#b4NuLq zh%xsVA0FiTfMbD_wjieI`dWB{Pd-IpTKwHF{|ko}Tf~h_q};D#k+Xjvb>lgI=d8(J z@gZZPj83vn*nZmu(V6rZy70ihP#*QRVC&hUu8LJtovu$fac0d?+Z8?+hk;h-wr$t< z!*1VhckQn0+J5Xuw$Vw>+d*|`qGQCDdoITkQwZ?r6WSX}vj^+C`t07xgVWRXsxE`y ztm^a4y5uYkKMZl-wrw{==K^C1%rIcU40w(A14s1l+V=8lw`+UR(+{=}ZA!ynC!JZQ z&~G_SnL%_`rdw4RCfIte$YONt5%27%i4YV2!D$igkZ#qzJYON19!C^$G$7j{UXdr~ zJm>Q8F)z39*r>Sr?cV>(yGWQ)Gw5%9Nn?jZv#=S&Jz}7jV$B9diRwqb0bmZLOq-7lqyaLL8d=1nX`1u%`)6lo{V>>+#g<){M0>KRZIfo_ zkSMZAcc$0WYi*T?{ckRU07DqMsG0zQEDCSiwA-wOt>A9(g$kT#5$G4ab7R!%C)f7u zcCz1hyZ!!Zx8E{n(RWl*b^~L}MGpaF8|K4YqsX4J?K5;9VQDl2?#+V{+Y&UlqY@`W z22CW2hJ#d4cFI0}UN%FBgW|wc3?5~$UX&VVk$$T|z|$~Nov>AT@J^u^jZL~$Mo2^X z3U-fkqt!Q~@&Nk+N)5_|ORS`~>T5!wK2p5f(#+5c-}La>K6wD{b+l zHA3@9)Lb7$2;*(4O=BNrSw`Ez)5U3&A-MF@pZ@fVFMf7$@$A>X`t`nTeJDnXPj-cv zwSakYCMHuzHLChxPTsr4BBNdh6SeOUDJ#FP#!~9={8m^fV~Tkx&W{tc35zV4!E&SV zw&%T}<($^u9QBH#tZl0dcEv25_3dC_Asfy9i1QOI0ewO8F3vVq1iRcjeTpwnW-ORH^#0Xw)^gKx8Jw@)o#yn3*327 z{UT>$vv-qxa#RgO)o@r)G3hikpzu?KDWnv;`4ehg@WIxbYNuDN&CoDEQ6E4QC}Ru7 zbObB_>6JI2swg861Eb_HLvn=|sAbYN+A?(nKC4>lN|hr=Wa=0c{bY1_T1dB9HKj31 z&Rxp5e4;q0#Ktl;i9yq9+7M#OF$?H{T{l@fYEp^PY>TWTVO_8v0D7dXIjNN-&(;8u zwHc-E#K&;u18pW7<}TKc_P6I${f(QTIiy!Z&I)v zNu#0|n3|}nYO^^xzjwc`R~OsuqeqY1u4i%s(lXR}JtsgJx2t6f#&MXe%9`HFh%r0I zaVn&tHaD%NuI0p1b4I>jRTa*P)~&`kj;4jTW7@a<&WwtE%VO?s7}|b}$&YLy6Xqft0zTr$G~qanI+7+s1*;lt$3WuL-cA6;M& zg)zw(5-R&U%!tXn3@gFvytx-{?vimU_K9K9;7Ds_{ebs}(OFut#0s%2rARvgZ{Rhh_l>bwO(5BZZ1i@1 z6==Eq)G{jzLNpyC=P3Wo(C7MuKi2f+_>att98a#!;+~H5O(|7{FVnbcs+09>E2`N2K>s~uHUxQ`CZpvZQDJQ7Hrp$5-0tsmzVM_-yR!)r~XTI zo+w0bAeaPQ4^;yZb88@`EO;hOwJKV6g%&3$QwpgoD#B7*e-lUR4FuHzMHK?0=_u%u z24k`OmlQx(eKKVMvl3b2_YEj73NKF^Y)eap5lAxw>Kb)H4TPp;#&O*5_u8>a`Bfq6 zV0Ga@NeE@l4`ZETR$<7rkjf&u0t_H3Q7-6S0R*$CWnWJaZPQyzNZ0xEIr3Y9>|?8^ zym}iJ8=ePnOi3}6o09VdojeI8&&1AH7QSg3&SE(|8)JI>^x4(b6&()))Ypg?jtC%+ zT!E(${O&j)7^7fC1?!%cD)Ex?ul`x5FAf=(OnLUFLwG`10XrpMCc2x8HvI$M0;?573Oi zCL|=Vi?Ith@=B79AjW4S(yRU+Qi?Sl&M&yo4vJ4s^A6O}KUCnHDZ9=ff}z z``)^Hyc`%iXUQu{xa}`ao66^sQb9a9PEM`F`^Sr_iSnq1OH|B5TDwKAqy{J>%7U(H z7WiZN)r~N(q)LS^4Pr|$=))YF7NzK0ZDXBMTGhp-E`IW(2lvm5XlHsdOkdCJ~?$$6suy~)YW?3oUED?CQMK&ilXSSWCkiTBZ7=< z7j6vRk1=*kRf>{+-}UVP87OuZ5^hCQSgGKQy4wQfVL&Yw8JS}VCQTIPDkmvamCytW z^`Z!cc_?|$`4w8=mAx=CY(&sYXU-2_1ROYSgfgBzUtJ)Lvn+gFmD7SIk^s1_<0_Kiv<%6us}Az9C;KUW+mnv7`8dg`6%OR4n&Dq8hmh}7!J*jqLqrE zVA0G=1+D^l6-mkne>_hVKw#YrJ|xrg{OTn)N5~-+xxk5#HbtP8RIiBL#%pCYO{PUC zsEbgZ9K-0Tso6#9{{8!Pv%0vr{PW`{BOY}D6=)_-b7UISypn52@gZOVM!~CqdCwgz zqbH(70wzQem{&v%Y?^h0n;bTwr(&dt>OGj*yt6&ic1+^oP1v?whw;z01}rzE6|s0B z;vEn0zX)O}`Sg^auH;X^w&bm~Ze}7dD(DIp_7ryJV1QW;?TINdCl<1I>kJ)YCHMT~T0c*wEk{D*AlI1~M%iU`*v#L~i-Rx;TL9 z`Oaa@6wvnBTGNHdw5{kAEMG6gP17RAxL%)p`PIYo^Yh>T{`cSg`O!$N0dJsuOGu=7 zh^m*M@Vr#eNTDUcUcZH+8i{LqO_EqonDu1Q7dPo~+dC^sQ z%+Oo?%nZ@zdYHr0=38s2CAfXxhu|NaZGQHX2lq}-o4Sm2YV2{3YgAbdF}1_^`1_~d ze)p%V-L5EWT9-q!nUQIpBa=GEV#psJ=w$!lm;W}5F;tu(z`1KkJ;muwVVUObZeWQ) z$r>gK?qYXG%Jr^YO)^Wq( zBPfhSpJ9xGMP5ZY`9Wz7DB^x&h$!?2}el_ zw)<;V*098pc>og$6Tm4^rJJv!_He}|CbL5iGxE=Ta})WMvTu2Z#3Gj%696D~(FNmcQ9ZPB`8vT^gCk)>43R}s&FjbviL_@5O6djJ%yHB!~X`JiCIy2%QK znQ%+vT%C?~VC)9=j$=j8yM~q0B$hW#3(UfUX`x2-a19azXob~@EFu0NauCqS9bj8& z1<8#@O8h(EeU(veWNOY~Y|4^}V(k{CGJ+sa-d}`8)8g#x?5l@=Q`hxxfBW0VPo8Ao z$Tv{FrQ%Sorm=~t7ZI}vG5!PK4RZHtsJ`9?e=#j?hedhNE{iz=YBKwMySfNfU6*xT zlqKD|b9*+f(O@MyuRdY-?*p=|3Ws{l4R~p7`tVQ%&pbJ_T~x9BFyE;53HhFiYET)iXQNz%8%;hu%TH|Gs*VsX|Y*VRL8AcRyEL57}m0wxP+-=^_AfeP$B6NQM=D-k_s ziBNvh?bL-gO+&7Xf#QJoer@})&iBQ_ax(&CX$ZqGgaU^#HCvPFY~rE1txuFkB`WBx zo-1jhFdCvu{YZSgegPDcKz<>Z-s%-}5C(53c329`T1YA~ZCH}FJ{21>j;s=Pg=PnQ z9IGmvot~bZomEw}Z`;R@pI&Tts6nAbo{0PynJ`Owf=9G9dB~9=MwqLy8SLKFTB7wn zMCOYz_Sg@a89&>iz_awgf*}m-rsVd$c?R1enT{!@QJo-T`es_tNBY25iP^;ufL!lX zxcoWvMwVqvi|OXjOQ5m`R9>`RWG+;!tv8?0gz%8xG4)K*47-jUsQXdYg`$6Fc!_DD zqAAR@kR+=`)$@5lOOmOZ))0*@*@`gQr4*gjU}0j;2QV$NKx!r#M%T4-xJAkJ(b{v$ zZ^x`6$+HatIi<9Epyb9kQ`sxGV4RZHt{Kd3**I1MX zRo*!mbh9aa#+WKBZyKSZ!2MgMh3%Sw0+W*VoS?#cDvOdBSz-iKvGs7VYj_`+lDm#f zp_Cl{KoRvT->b&u0E$Of=?3~FUj@aiZ^Z-!m?OtIN3PoXY8ZyiX7lCeKmP3Ogpu_) zFb?Kn<``pHmSaqzuA>i+pFI2R@Bi@q_ZL;Y&Mi!a2tI<6IKpDcj~D-oy*K-@B*)VH zjJDm~-NR$ah@9HG8r4(t$7+G}AOU(Gbqf##0X@?i=|wD!lwn%@&wu}azkKy(z1;>5 zDRU;UbhXM#eCl`O&j5!Qba>T5Z=$RWFfw(fz^R)xiah6jGATzy&o`qZL3d%X!262D zgzbhCE7@z&*{X$>AQFz4X}s+PjHZROG;Mv>aRFJD$*+dR_qH8p$!t_E7PI+uQgUWr zF`Z(2Y^rLr*>0Pb_)vM7=b6ir6sDH)FZQXPg4qD97+WG|JqVcP5?rQX6 zn1)QXY0pt~+(+;vp($&<0$NSg!xlhDUNZs886fWST~WrA<@|kt7kI5=A75Yq|gt1H|I!W&W`xsp0borLUhv z5=U6D%ZPDBCL#j`5{$;9GAiUh0gsOo|XE}V@|Zx1%cG) zvYypC?{E&bc+6<>j@(0_7Cr-D%mDh6(i$1uB=DRjfxSoZZHb0$0Au1)7o##~t%i`w z1T#=Yci!9Kfc0uqBPSYmt2a!Nlhnt;t)_)-f&!{FNH?f-f*OE&gwWz$$1Nvec2NfP zlz#@(g5W9!b#U!`D~iH<0>mkPl!$*1_DqX3VV2?X#*P&p!J$k5bZ<3HGDrp5B1@}hw%k?yMykP zg`RoO#KcdZJvu6qjIf>fUE^H<3Et&7%kQ@Hc2hOK|Ni^$UcAoo@fXwLR$yBE{r~&T z^A|7Qo?q4ksYhT1yez1I#G-g|Aoh)v)DErzskEnz0lle;w2=krUF5jF*bx>qELjs} zS(MBavWteGne?a@^}1 zbq^NP`IJxqqax2-G9DH488HFYRkd1fwoU8uqO|pTh{b0D7XlQEw&k!q)QWnw;b<`2 zr_e314G6NnLxxKv-g;I({Hp>w0~97iYUvTXkZz>INzWz3oGbp!)8R->$&jn=C&2|>l2 z>1_alc5sfQt|3WGWkhiwB9=&m=^7vIVNdk4vnX>pt(%`@r)d_7pA0fBSe;3n$GwXV zl?FeVj7}e%OsCV$X7l##`L?dRgviJ~;1#u(F9>8ov$N1zraVIc@k(vgf)E852=GH2 zf$b~I8Je(jsaYn}i0a+y54Ia0X&iLV&WD6mI|~+tRJHuZZ#((_(zF%+Z@4kP2c79xdyz#RI#~}5@|}k?xbYF$S#{W63;X^3Z8xy(^iH~vxmfk2qR`}c#W=_8h}Hq5 z7L&V6dp|nkK!lH)%Mk3ffM&R1AO+iPKYZc>u2V49Qv>!Q&|;M7;j|yIi)ye{V_f~s z7z^fEftSn92$3ppj#~h3?${tY^`r*@BDCA+4}!8lZ#6&<<*k44#z@VV(rCu1lWyGEl~JftFz2eM$I1zd&xl> zj3xA5iu8wL2`d$R<jt7fKFgYX#j=2Ug#ShHJG4+!*UYG>SOJTISX#m)GSp)>^t&ZRK9BSw3d)`Y_|Y` z0d&_LcEi0*5`<3n%+}X5X=I74?pRMY5Vwk~BUBg&J^cq=CakiaeXn##xqC+wIx;Il%xuBShVW=g(h$_u^IJiaV}a z{Fy-YwT}?o|MnmM)9HhU%k}2@^A~65msL|IwvELnN#}iPo*C5qbsR{}$*wru4%C|C zwJb8z4CC6qSri!p9n-?5TR{k2$JXJtBmCB;e=EHDRP5Z>xcb=A2TOH8>)LTu zOz5u(n*B`)a(5^lDMPVxGlx>k7KNU5ed!czpeTy2>)6H}FfC9Isdzsdj~<>r7>~=k zt}iYwR;vx`GHKSfU4nY)yk{j{oQ&w(+W<*|kDD{QPP;fLdk7hy^4vMRc%hcVVtEQB zMq~&!eXk02Y`?O}@L;pz{W=`U@itUb@*bok1UG#C!RT|pft%0!GG52Bt-{Mz%%kwTGL-ZB{GJ2V8BNt$ZboGjPx_%V}w1K^0HXVQnPz(IynikM(2W;ngP9(tX)@Ecu zWT0-MX`%NqExOj%TW=G+KmF-XA3u5e`t|E?zx}puJDaTn_fx(llO-RlGO10~?~e-i zE8Q(HsdE>6F)cni(w%KVnDX6r#5~6_LK2`i8{y$?@^OdiwBW zl)FGQpwXzD%_bp)^=7l)Y)qbHNnWfr)py@LfARV(%}UAVAwCLE{zP%O>>;>+`*;7x zPk-{0$z*nMdG+e`>$CIoP2ISH7LA_J5&DM;xsC(LA(c>v4nnPAcTFsQGti{6K2e%B zKL;2q5%3*8Q5}cYVOp@&g1OZ^&q{Q*grmjK#FEiuHXe`5vJ4?q?3%!TmpNdA=EY~| z4U5Hm8oG8{t$o+dr_+<;qX{eXWwos@mn#l)<@k-l79x_?ro$WdS7@1ny%iRu$c$Xy zp9KEShrzf-0cr{FGdS{mDJt-|1LX5sSlek3d; zNrxibbMhV#2Sk-N|1fgk=Z-2W#g4pT9R(ka-kBDi=dgKPJTb1q>G9FyM-M~jE-o&v zuC6#HFG-UuM@>vPbisQImS^ecs(d3a#aNsMseWLtF*Gfi7Q3&AJ%W9U4--Y;kO#AZ z?1Tzygzy3r!NWtHI0w5_UXtcHH@tWqDCvIyl=8hHZrJC9YPK6Z9pQk@g_lJ(nM~%h z+3{?GX)$8rBeT=Tnc`p@2_dJq4ae-P*41iVEvvdB_BBv5XZFX0{_njxrac#0d*6^ zoS7oTQfr&Gu0q!oMe(zr{ru#?>2m`|shez}P`fpm4}zFU)98(AYV!|ld!GXLE8Q({ zNW#0|i)r!EA^#kMw77If*Qx}n&cT847P>#@8X!ij2a4Uf+$zB z!y`P<&b+q(O`UI1=so={P0K7D6*+!YC{bxSp1RD=nyIR_EmolQw*7=|k`Vso=;-Kp zu^5--cC*=RR+$UOM~er?#~cP;6q{;$adov`Z%nOBnF0^K^`U7SPA!8%{;g}aL}Fer zyNniSZ4`ZrI~&;SMm?OYQwqeCwL>fP%=+Sm&af(rLViB7MsyZ6f(9Mn8u0rvRZm?p zUcKk+FLfmT`C$39Ax-Iu?2Ko8GhSnm)LA=6P1J$QgLjqcT=L?J4&LEdGo0yWL1s#}X)%jx|FO=3liSvJC{I`g2346n$hB%=#&E#Lj2iG+mOgoSdUA4HZPstz zyk4!=7MeB-scmM!v`Ad&=qW@*z}jYM%#MJJRKsFU+;>`I^O(cf6?Vg_g-j9am9UIj zux{7c<_Y={hu_iGt%vrUfkM_lu)+7NRcio&c0RzTFfG)E?g9!$CD2IOF=C+Gm@^*x zvUaN$i`is4D#s&pc21cK2*J0FuhD0_x^7lmRxOsB?XucdgxZB!u)v{%s_HHI`{9sj zG2Clm4pAUU>_{G}Pc?|7i{59HRcXriC>U+@fSxYon1mrWN7< zoVmPaSw<(Ws^FXPc>IfB{Ka%O|MuH&U%!6MMAYuP`zha&Bqq|SR@J6R{ZZk5rMm@v z&%PaBOpA|?jE%&Y_%?c`HcVTXY*%C~tKu|Uzqy{?MHL=1gT`K zz(rn!GE|zrxf`qr_KH%d=rf7W^K3dQr<3t?JSy`nxTI-A-8Ad)7-fl)kadJFg%x9y5;Qp)4=8X6|>$=0Y9GAv4W$D1Qc_w|$ zP2NTv7>a4Zj4c|JALvag>>ii&5S_-iwnZ0`w1GiPkX@m? zAnPZ=GyTe&$zY;FnGVrG!S20Vz-h!1a}gqps3b-xbeS0sBbdI@pmC*qLzs z@drQ!k!gXI2)yr_(6P~6a$m{eJ)dJ+7Dd4!tW`w|a~z1D(P$?RPmaqnzq-6QJ3HHM zw|wBTU_nAyU2tX_BydAe*1Jr5BuUZ|b&dKYci&+pSjQ$xl9?iT#$q50CHx**sph<4 z6Y;W;vapyP_^7|UmL%3!tYPmX&@l!Wbdiq+(XfYGA4Z2LZBbG+$+VcyX0yp?%1Jv^ z94!zNH)&cU4XS8p=`cN2S`H*g6 z5KBKaollJ~rp4#Muql30Fq2De3_SR5NSk8Xh@fy9BTDp?BDjLcMYweL=sMz{^g_cX zP((HdNE@sn1HEI4})bA2;mfP=I(4kpV?FIQ36Jz#gqf@iahPun9yFW)>X}FL}RgNm592WmeET}sVT8)ckx@Ra#q z8z3>m5C}c`ht|o}^!bMgW|S}vi?<~U85L5jDLz@gGtW5pEu-)8p@AFLa!6mW#PJw6 z_m*qm>5Ha_dI15u&`!oa7 znZzYp87x7p#IG`Z=23-(SVwU+K@xBnZa@Irf&gbCSY5_VNbxjLS!pn z^lwAbalnAzRh3vIYppB?riGo{;#p_QPft&eX4CDqx;Q^uuUBo0!Ow|xFd$7_mb33D zWl3zu6M9L1(nKNQ;B3v=Z2eEzQci?_^qp)Vyi1O?k~~ zLbl>Nkh1;yu}uqdyn%xc`=)Xo!#De3oBqg-W@)#I5H*_;K5jZ5jX6Szpi45+TAE4A zxtVRZuIlA#v*G~qriMAjQY$rVwn???nST%tn-(SssP$-CWTtZv9m>1`)lF1PjnkU1 zp%RnCObZYOs}@n%{IN_6QLDX1T990=Rw9d5YJx60IcTC0^(xOp=(g*X3*GVY@n8J% zmr0WT<~P4tE|*D)hpccv<(p2C(r0(Q1|mhwj|%rI-7RqMMxXcN%c{jk2Z0t1n#%2E zRA4eNMP(wcCJIAdX2m2)nFFG0+gKLY`XqcJ2*#7}FhXL=^0_BIN?#C#adJ@dN<@l6 zNrreo1WyOhR}rzidPUUgSN#-IHZj7(QIXE_>}WANS}abEj~0u$4}mG_YE#wq+w;pe z7Z;mtjc-WeIFaB6l*^wd4wpRy_h0_^|8A7!zU_)Ud;09Fr%#_IE_wO#FVsDYkf z3L!LyV9xL;fy!5a1gPJGCBOG9Wl9sKtJVZ%Dv6-0e%-d6vcz|dO!Ou#2I;^B+#C+| zvJ#;zj$~2w=)oA4R(tHpL4Qh;vM8OoPN}>G+KkeXF2#13miT6>5kAcG!V+~^PSCX&RW<5OsjM72wEpR6e4G&85bpMEmtX@CK>@Rf&yp?#c97HJsWI5-7!|CQ86yr!lTCK=~0f?prbgFdDR(f}xgOf(7IO+~(OX{tcVVD+>VvP)nZK1Wpv>+^p ztXdjakDg5Gl+Qp2?1uUb(Ec~0lmHv!@z^=HUaxn}6@uuB)|~Kr^epGfv`7-aU9Upd zJbLu#=fC(x+xma_hkw{?HXp^b5WERe@j+z#n9w(pkBl#-#SMJ6s;4hnZ?`22BrCMg zGwF}a0i`&-x-1)wry1Kpne*-J)6|gxH+mz!;Ues#I2sx%*ES;kbgl^5aw5&!WDHevPWiNj?N!Tsld z{U12R3^fW>`|+d44^AJ9N5$%D`TOs_y|`StoM=&OFMxAQTTwozn76Y4_$YLSG`-Y3g!|Qtkr*{P8s`OP8i23=;Gy-*ubK zX1QFhw%a zhfp~v7qFV%#-+cvKXI*B7fhMK(AIDWMTDrw_1gY*P!Br_;|)aK0Ho@ns1m5JV5!JB z%u#S{zppnnhU_J^tVHyB{umk6pw<9Qmq zEL@7egCo)bZ4F>BQZX*$KZ1TZTTU^mnCs;v~orCo30+0`RRj` zqobp)3+Jq+U2r}qmKF2VfnkQ|sAOc;Cwi!Xx~CoVwa?&UbMsaOW-yW`G*JE>=!^#H z0t>PCPVBnC(Res365rW6FH1+f2KrL$V3lHt@1EQO>5F28u9gKH)}QgJ8$tKF{t%2A zq$5&wjnJR8HxkB5D)NGJEk@;hoKK3>T$^$0hmY2}I3KXC*Bh2bJ+Ci@Yg z(&;LeTK!N{)Huy76o_D+Qv!p!r$8$(bR7E0biVz?Vib+UK+-l5Acp9ke?C3rv#LcQ z2@@T2p`$Qk!`QoFODnNBlXkn=tgim@FaPq%lP6cp^>2UsTfDyzJ$-e=Uim=~!*vx; zV2w4T&w%^Ud<*VuFvM6OLwvTfe@^@f6-x6UG)QDTZF@9g9*O}mXG5K45C|=3h($B) zAhTyZhQqwvE@FR2q}-^0m{h!pkkk|s^BRcV1X2wFJEtEh_8y}A*@Uj1>)V)`9*VXI z{i%}ZK3*jr`R6)fI)X|e2TNHsN<8sihYTc1a(r^~;pyq)#}BhK zef#$9%U7?Ln+=+MmWC|XygIzz`HQ5sj0f+XxBbCATZd4KQ8jaQD0nVmzp0IgPKsIA zu^E?ndyf)^3Qnx%U`KS*k;db(#vYxrR8^JD1%ulA4aWde$tgQiU6C=VJDZHlvY1RK zv-z|fmD{?$yjotJUlCNtxuXRKa_3oU8+Y=}c6)w#b#b-Cf12GLfirA7SnqeOL^~pe zr8B(G8BBm^Qv%eZGTBr%8!ClZS*V(6@fh7Oi8g9RiEi|QNsXOKfv%Zgq776!X&6y~ zF!e~CpU$8}cxn)BWUzx?i1`koltql@=B1!33;A@ZED(uC|)Qt zmVnD5=U~!2EBQAoGt;M)B6>f{{sybGm#{1ln<8Ir8<}lb1E!GWS=!oa6-`S)fl6dF zxfzFb1|LfqUDpuikJMU=WNR#fLL-vNY%+(zNpOWVX^KhEz|^rgl3`t7p4h3?#8B?= zy@7G|CQElFoPske+DwbC?aU}@(xhEXN{cx=*=(wdi_5k7pc9PH#4@p*Y(Woh2J3ZJ zmE_SI69e#wm(ZXMYKjs1)5@p@Mj$VJkCjFE1S}2C6GE60W*LFO4M|y&w?psu#WxJw z(%$pZ9Yxre=$HiWX%^(ORORj+H`B#L}iq~pR)@Eny{nh`Fn3k{8m5DV27$y04P zy|dxm8EW8W`hPf7a9vgWSYHO0xg=-R;#w&pOZ)1xb+R$>Q@g=PcJU6zWL@GO7_LHxQQ>O z#SO&P{-*-T0bMhj9g}GxMIuQOO^RV%8&s~;A-?EcHde7nyTd!vf-Vy>LeTBw?p*Ra z1xb>Me|Avk-Gj6s6-P2hdGXH({T(F3$PNF;J5k!>7-P-__6Y!aC$X9_bLHNjsEKdwsx@A2as&^KlS@ z`!D|Hf5D7{7wEYzNsi`=r_Y`;#~;G^#pTOauU4xSvy(;HFms1|Cn^lwOPD^jn*{mQ zH|QZ$yTgWs9+qZQBhi%tbFjAl74YnLs6ib^RiIj@X_@C!I~`F=7TS43cqh)p?hkNf z^J~*Ijtz}jV&N1r_GRM&9at|&L8p%z_}MzVilezk zJ&Z7$9-BWtiHK=hV(hgjoGwAfU( z{=f=^t$C4V>f1VC{=jXil10I8pQzSI(ZQ(1wD3*SXv4Qewun^Ap^2ih+C<-y8*o!KZ)tY8`Y!uuZJ{}EFEWVR3sdlSJ2mQsasCFXI;CNHDwx! zU@ZcWv>K8zR`>k#Sr7@vEy31uHF=~1UUcxkN`26@=$h@Xe)X&QVsUnM@lXHsPc&EL zChdxX+^cFtlCI(j#O;{#sc}D=ZvjK|-GC_D$7d`1=ft0Mp)!V0=JjM}pnQifC>KU@OZ<-5dtcv10<;GbMI}jcmxd0G9X&XC{P=O(wy$2jx>_yC$hpM) zgb}lt7G25{4q!8~2v))kB=+}&Iz=OXCrJ76$BIuv8+$GO`rpF^TknB8KFQK-I-Ndx zc>3_+!y?b#yngfi#f#0hO0u+-v#zy5WH_yo?XD;cJg_;V>!3ocHAvY-rA9yE&Z+^TvMgtl@$q6Y8WC}9G8s>&(@lkGaem2x z+^r96VC8@GEpgwHgiF_pXh3|^G>4F$s&6%LMq@o#cM_~O?SBh0<|O&v2DW%ZeHlx2 zHQ|vErLH$F_IvLT){{w7nMyMgF{EpyQ+B%NAA|CWP^YD{(Z{f7P+ zX3qLlaF)5WKNz*cNsKKVf!<-vwQ?IX?E+~3WjV_8ysqo2s*)rurlUs>j^?w;c3Uej zlq0Np&Qc%cV6o7oG3B>2)4lzP_2Q9e@WwJEgIz`7hHKh$Us_G+IyXwy!h5fH&^#g#)U3U;MH(%5Xdr(F%po8^B=Sj ziX#q3Mn$ehK739ncZ!gvN-NWSkY;R@{lfe4pA<2fAv>?RhH$e*Kfc5 z_FGKN1SW|1`>E+ewu?U^PicN?+>hp4;1E`K!WYxxPXU?D1!~M*TD15{leL$iHJ+xcyhutSNec+}@(aU;MolEAB z-W1}z58uBVIX?{2QbfP54EIKra!~=D`MGH6;rPLW$4{PARrTuC%XL-p0gUcN5T4kf z%^X4|by#>E2|*QOJffAqnc#>Tb>L@Rf1LOvw3%t~w+^F>`iAMjwYH~tHlKa{_18}x zJ`8R9;^oV;v$Lw+65xi-ptMQU#H4pa!-Jju#|K0h6*B;>B;|~6c0c-#ts2hdnai_m zlovR*bnLcB6K8YP<3ujDL`Zs;2%Q(--y5N{xR8VCQ;Z8bX}bJL*Nc z3OvI6Kr$&cZz{4pvXovV#`;NLp?XGDRCkV>PjT++6SMT4ov3LMok_oCNoF%Y3SgTS`SYNU}W3vm(oL#qMB^o7c&R zypTl@EWJ*R)N)AQ~umFiblg->+M?6pouNjp{cxTIZ6SQ^}LEpf=3`lCWC1#W8ZwW9Yi( zb=Ftsr$MAJCNEN{9c%y2c^sl>eqgVz1?cs@OI*j+eYA5Z-$Cz)rLj`t&F8@|I~`jg zZAk*ZF&RSfZkiU=CePik|MkBPAv}Na>ih4%$A9*VX>k*-7vs0%i)ryAM(ins%{1AF z?$l3baX3t3qCjrF0t)XA1d=!Ch7@+LJB&exs^0Gu0Cm8azHW9>s0XQBha{Ngc@6P% zXfPm^EH8cX9@y&?Jien(B6Eh2X(1@nc$L7{SA7^3k9zXp;pwBtk2jmmix)4pO)X(d zNi}AMkR@GjSvctT@Q^%hbihBGvY?t!5wU=};k_Rp#DtHG5Zr(D*ZV%<(r^ zU9w__Z+e;*SOzKgnJaBeCC(~E?gJCj@=Ia*xTe0P)5uGT%}iOgMa%5Ey75hG@ok7_ z^YFpxbT-ZMd|hoWuddd1M7K+l`53!mKAmRlAn#_g>3lxlRMp$_OEWF%rt@{zC7lb_ zM8thsn2m75GWI}x??0C=MZ?@}BhIo+eV*~YGmAICdR-%WuWr-;EJM=9FjZl+%qCtq;6w}yn60a=P~AO*4MAJ#ZJPPZc)dm@(d zj|~8cLy*a|#__M9F}HSV_+&gfJvmy;CSB8BUS3sI#qq-l%R$)k^qWAmDXdexJ7rp^ zIVo{6HGZl+^jDTTQ2HsI8G#~3Rjj)1-!x~NT~fVi!4eTRtZ|R-&I{PTS;jxtp_czc z5P707g1?RCA%+j*ua3HZAL0uKZv>StUR8W+07=SffXlPod8wGV=9-x; zwwix+vGe=#i%z#--Cgn+iRhge7d zlJF;2DEjA4Jmwi9$b=RBLSvH*@}gia%zLj9s%zSm@Eg2LH@6us!Y49r@Pvm-_E6Oe zk}c|?{A1$x=2hvClO;I3iMi+}B@)MoIQS~N2)%q0dOjo|rhgO4OVF<(Owbd2X9B}& zmSv}p9zK5ZWVKp7fBw8_8Yu%BF-`pXVdM;yLnaK-G<+bgz0?Cne#T95RO#MB;U691 z=SM~e?!WmT|5sa$GIwoQ?ee@x(j0-FB**i~FTQ?udV0EAuYUjCcldlKzUlZc5Vf&4 zEeM6_1E&;{!aJx&1r2+gEs%u91~_UIUB}|{CoG+e^I|+2H6j!?*^DePGo>>a3>oGt*7ub}QPT zK|Lfwf0~A>Q@al%wg%nck;b6PhvM__Grc3ov=Cud8en~fPgGL9uP&jhpyxyAiLUg& z>oekVmDaDidY5=a7le#cTLy;$=5~ugFEXM_=#bi1zOzGzh+~>N+`&ARR zEsI)1(}J$v$+T#-K#A6p;S$Ai0^OfBPq`i9f$RYcagOCt{;?$#X)`*2PfEE>W|Mf^ z)@@U>jE8^<92`N?p=mK~WmIt3JU&J&5a><5H`9XOFk@U%j_FM+$-AqVtT%_R2_no&bf_~9dV$KKCy;MNi;bTj zEK|`V@@Rf+j1GCu&Mp?;*uBkM0Ly~3USJgp7l=OiX%MN6$y1&I@b+~^!0uuHCM(MQ zJ`y($*&>^o3+B!HI z;aD4NHnwe=wra#jWF74YO_$iI#6Fvj$FuQdHk)#G0j~4d3Y@iW z&4D*9&Z%yOO}uHEx@$Mvy4r3-*SW;yX*wxKv)Syy!_yFwO|?C{yjZSRt$FSiE}4|& zgX81rWZbdl6^@P;I7DqWug}iko^d=%>pchOnQ1{8ZUa*TNw18m$hyi2l64i+_Ow0G z!?xQ&3NQY3H>-tM&=O37KoxKN5zEg2&J85#-Y)f<=C|Za9TBf+xh6HqzF-(U1rLe z`TRaFk~Z+1jT2NEdwyU`Uu5o+gh&Op@G3~27IqSFQ6Ry4ThVko$JrXbY1*n`VT}zR zKIw@0iW$(m4zi4jCW}dKvrPymtF}CKWvAY1g*aE4K>J)UXH7Hf)<- z&IuJJB7?W4x1*n2$OQSWhl7d^F696g)wLRAtVgBRf8tzGFiB&j=GYl;KPM^MxDB+S zn3r-K!anSIu3v|4PD8{tFvP)!5z1Gj#;&Al(nDSKTBJ&iGeT5p0#ENKDQkP|eo>!o zS`M@}YmroG7bFk(gY7!-`BQ_!So>7VffR%M*5Xe?G9nKt9d$tu9YP!!ej>yVZ^hl; z{2(Y=)MPR#ilS+n^?I$fBP%g57g<+t)=!^2`sFWwd3JvOo8SDlsw!4C2zS%-;T~!_ z>ViRhj(>illHSBUXucJ_fVc~8=$HQj@Y(9_Q$Sst_O}}==^eIev6r2e)-?+z@tXt! zG;6%jwX?Cv=F|~)Bw_0qsC8OsqB0^F82wXMS}ZNcRttPlVXSi<%i88N z>lrVY;$+@3?JQ)DprWbNp88;%JD~dQ)xd?Y8ZFmKy&; zNV>Yr+|kj|!_$XHN5@^)y?XQd?CiX%Yno}6hBSq%3DLWpXOD!kj~rwu7yw5=j-qRc z%?bTJciFfsCZq9UHl5FAqfyBzW>?GQ>S|lpRnzKB<6ZmO!Y4m8d%JRTe$jmKrz)G4OL(QGzbSDV*w&(F>; z)>}@OZZLpYwNQ!P3#M^dV>GC^YLW3O4Vy_&BimklAJ7JznRj;pO5{5*k0yQpor~~3q#05CiZ9j#CxU(n_WTN(jS5-0WOR(mY#~dz_ciHc3cz%UQy`B zS#MeZzwSI|nQgc1a9|yQIS`o^C?&)mK!hn%(WdHO zTsuCyAfQlLs;#c zG@F`IwYHeEb-lG^3f%L$&ddullWd`agi%JI{hiogFi0>tXoreg#RNC5p>eMT1v6V0 z$!LbI(e@6R?aHvEnA0I|oBY=M{h(xk3L6!4qkFX_-D@a{*SjEoID{zF6Qw_dp6Dt- zyb-3Gfr$n56IQ3aqZ@u;>sN}?UC!hmfx@gcsmRvJFslUCJVW2EJ~h&m&L|26WRvkj zrPg%_6^$xkQwT+l&}({O4+kF}#NFTgAZSD%8KP?kApi|Yf|F#PrOkHp^vUC&{p_c2 z-=6*Un}6JHw_i+)gZN@v9AwL%1SGqn@Kle>GkU=g@(H2`z&J|5)2=VevXUe z7&j6h(0`eBusP+MhNZ-Xz3~n)UyTL&^``LoAutdb^hwkWRJ4x>lNLSVU?<$jr8h0g zvV8pT(dmN+S65drU%o_{VImGCj`Ov!-rR^$I>B?_F@7gFK841dAlRjBrUmnhxb`@2 ziiZXl6_Bq!3zXd+?w&p!YmxPSkD{ljQ9N*x|}tJV7a{9<{vj4GE)x{M&o*?cyC z`t<4P$?0mne*OB*+1a^bMkRSsw@pY`c1UciU{rEcjJ|H&wc70hs}Q`JgmGCO9UaZ4 zQ?|`=-eJ4htkH1)pjXod$|7g4e}8oNgk{#jE9_|A%vvJS*)0tQ86BmCZjU7aur2h*Z%d{ z`PtdI6ebq9wIiH%VY)ta5o5sG2sEp(x>|9m2$SJRM{%`)c|c_`invlXLyFa7Na&$d zP2$+G%o?xn%o^bylO%~yc1lxMk)eD3u{IDN4sr0|kmnKcp+1RM-RvR0OjTN;bfrW) zXdy*!!b@)xcdUuAnMbo2_|&nw#ar|oN`iqAEC7fZb?>RHda^NQ*LA~OXB#>@ZtLR~@Qyg#avVIr3l4t%0SLkUcYpi$$BV^cF`rB(NeI=Z zS}j-W)v7|8vo$)P*o4fbrw>kl^6cyBWVYRIU%r0*=Iz_MXogWJ18fZB^CvcDt>J9L3xrHJj&UR1UP*M0C+DaYdslK-SK! zsx?+7z8uADIzL_Wwub7IS_z^=JlOE8D1J9&LOUhUhBT92+n zsO}^JZeHV?@ij@PcvXU`6oI7!gE=E6y^6Mj-Vvj8FTq3HFw9yeU^p_bV2z+G$}Gi> zO$q3aTI@rpI*#Agk_Dbl-W#Kp7*h)!{U5X~`we9Bv4Doir9t9(im)|qP(L1Z6bdN~ z|J%i8j@jhk*dxRWsgCnwS-}3cI+sj?Q7SlxW7ONWX`7aP*pv<)xY=a9n9pX@$#gv8 z_zueFQew&a%jM>~mv7&`J*$X+#~w4N#4?5`)-ihhNu~uIPt_qQZ`3kRZ-Af_0|Rr2 zH|%FMMM=G|gIGozMr=ZA2o7f2+XQbgo_Bnql-?mgUk~YI`eXR~CL-BG9Q-8MxTx3S zS5_nY(C4~R@*Pxg6+!n}v5EJ#wI=1X%`C-9AYgnpEw+^vh7<@v$Icll03+{nAr@IT zyDQoE_c%B3r=a2w8a9vhP*;_jf9{Kz&PRky3(dl6H(j3Rm4TYGHc*z#GNg(BSI@qB z@ZiCB-+%x8_b;@p5uCHRS#S?EUF}x6s2lT#ffPSI?m_dd_+nbz%Ay}F_PUsQdhl$P zh_YG_r4E?{V_?ejyvXwDWW?ZM3lzTd#JAx<;?5>U2x`^LI0%c4KS3hLrT<5 z#5BD=eDnQ~FqU2+QLK5%_kVRqh!ycFuWSY{TbYMDjvl?2noF2N4H`j@>DAKaP4VCh;jO4T-TSEm&?_1xmj-NjqgI&v}IO2 ze)Qh+t8i;LE?R6*_GcC4XyzW~zYn7wTpq;^QkJe^D@ELP0sX__`z z6x+>a)3zLZH)0-lJ`hi#>5Dh!e|os6ePi=)YSlBU_k)$+_v zGA5!<@ZRAoH7kmf*>paix+FB)D$mjdTP@he{rc_M*~NucE!r-m;lL{40dVkN-(JQ)lO^YOp6l!G2m*l^DwgqAd;uDBfBvM zIBq4h)Ufx=^xM1i=tkny7@%7iLN zl8nPSK$7hCT38HIeMJn1o*#Xtdr(Hh#_&Oil-z{M2$6kZ`1O~tLQH7eH-qC7 zFg0O-lsfn^q#*G~3sYNh)Q$xVgYAWod&OWlAmZRSX9i|__sqsP*<*Nv|R0%!=S5?*X%d637G@H%t?(X1yJV`SA z4@WW?&eyUD94(?|U;rbPA3P@AoO9UZ+4Wrucc!g#b&nAQl7WM4z>1BDergbuD&Tr0IAxo=#4TvCXErpUqcwjhz!(WAahM zUHvFcPN(B>RR-tUW}T*Xg4yFyy0gYjT!mvfD1>&PiUsupFQ{`NOt zrAhM5H{aad&%DQ?6Xs4B5ueXECrzq(`{JLuK(ec^Z?$d!?l2;i3 zK;vX<5j5b$Yn(C$$~TyU^O(1iDKP9%1=ok?bPRk7(lEw5Ownlv^J@%<91$4L@i@Mc zpQ;ude?J_opI9L%qeB6QF|$Vxp9s$s*OlIlMx*Cf&qh`CaCd)ye~$&z-FiiqWo2F@ zsZNZC$%G6rT4Yw#VF;Ll>RsD)ZPzxNw&`7soxhM&$+f^lC?bCr988Nnb%1>25~HfJJUcr(Jw3tphE%Vc`u6UwS#O%Ush6uX&7NI7`}(V|(=@xj zzW(lq@7fODf3eUe7JFI!zyS`u5tMz*A1NL60X`(G;CDH_i zfWEi{*NAdv|{~o3A%8h;rUr1y@wZK#L+PIRq#xb2wx{IP$S_ zXzch-9JyqH#m%FZEC}q)A4p|e9Hb=SRx(Bl2H$XBu$Hw0&?{X4b1){@WcUQ8MF1iS zq1m+TWSC1pt%#T^VEp)$`hc)V#GsTm20mvKoU@JsYmM_rR8SHcKF3@KUr{3XI=RA< zhqKHGjYdJVN_lL}5Ap!qmP#+qxEVkJUg-lIma1c7Erfaz)v-a2MG7EPn7>1LfLw#q z{Zd6{h! zv;i)fHETd`Td`NZhoB3{BdA@dTDY-5{Rv>agQG*Ssa;mVu`y`}3@!>nHX935_5qp4 zd_VXon#Ko>T~*|xu--S!K<}_RPw>ee*sL^h*?UEjz@NupkUg+ZvF!1R{2({D8OEkH zG(hBEss!yWR3Q|H)`~IkhVfw7Gdi`{>Vtmbec!=`6QeKU0qyOeqv6d@j#$Qc6RU!i z^Cld8JB;M*I2il`0p(m)DzO|XMty0TmSxFB@2=~-b2u^Im~oZ=_P4(^#{BV*f11q~ zQ2)4myUoF{vEC2h9lLoG62_+}=|TLeT6|m_-*6(bXqY+*_Xb-KL(@Zmb2xOd?K|A> z#`N%-FK8J)jx(r!6WAGtSFY#F6I?I`BYlmnaLADS+p)yNnp9Q^L`-5RMZ0vk_uO$p zrA^yA?+}rI5$yg9KmjH`Kn?`k07u|;R^ays_=u_nfwq&#ae{)>&f9?#pD={GQ8j+? z>{(ToJJrI9B{uX5s1`+$;$Yl>AyN1POf#hQp|)XbB@DCMuH9_9rtep6=;d%N&ft2p>Anp;wH@lRVFR z=io>O25A_!Szt^*%aLKQyb!Sx+w!^|FEITKs}6pN=a{R8bVOpZILf5gIH6)XJ-Z0X z+|L&?xP@w9Poe^p4*)l(qv~Wb#zw%dbA4;AnF^Mx)vKGk+xv(0rp5WSAs7WR-NPQO zvKJ=_ghEbcgWv=h2!)=8zlLpd+T6#)vE-$_wX&2zMn}Mjg4pC>*R|}e z5jht=Sp&F2rDE|9#Z8a5CK@CNE!h9Gor^kOiMyY3|P*^wq}`A<76QfdJ{NT=V8rZ4Mq{I zMfU(PL3$5ReVxadX&#&d=Cg32C+~zTyb%i23P*Ou28lW64SNvpDG*1HG4g|WK)#XK1WUJMpS#My-RE{x;9N^TfUaw}eS-o0& z@3Sn0^;3b_TNrf&oK=kNwzMG;B7mh@+mhNKQW}Wq5YHe6L1=_#E!bucGnLsl5+Oa9^_=iCeoyM^t!-qdxgzzZyZ-$55#bI3#`3S*@ z3W#n>=PBeiHhKhk!SErH77>9lL{MsEP7okK8|j6K<6gk$h(T6VB2-YBPOy(%#tAL6 z^ICzB2!=%GM`2`Rn?M8<%NkyZlxcf^b3ebmpRIe}2MtRyEIy#5=ogq>!%8mp z?@K=MWC!kGiPZ&5(h!`(jZ_kP86+on5cEM*5RgT+S|j^%pVU>QxHF7+6+~TG?BA1t!|p8Z`M|(ioX2f`HL4X=8M(u z|MbUo(`lQ+i#%FVGewzo289MZ**-i5EJ7rwUsa2r8`wY}7fzdii6@Ya2~G!}8gH!; zff76%lTbeNa%fS9V}=3+3$Khpr&G(@xL(zCW+{Z4%9!*3R#~Xgb>u^S& zPsqVo1NbAr(>DNQEXM~!wU7x=YYkkHh~0;$)Eff-k7FLjhu5(phXSnXi28ICm|PiGht7)i0~q^hu{rJy zo7u8{m@n6DkBzgin*u$FS09rn$;o&$9amQCu4{bXrAacKPA8Mea#e3vEgI}KmQ{&Wk*URByLU#5Ko75h=vfuU-O!uGh#8{1qiMXNTt8Udf4M8fYMclT?hOI?J9`u zQhtFc01A^Rdr3#B5g&+BDr{Yeyp4~UXTBQd2bobi)i~F202o`5ia=vBENqEIqoEiZ zzsF(T8QNNVSgA(9yP9@z|nh{Z^8tdOr`;-WD&1*#p~X_-bf6#kWK3eaW9} zAPl0CTb3H{1ZdeoF?r7`<41i;^MU7JoeV|Vt)Om8`Z>Y8?SX~*agb^_(9jXh15MX%>SgdQOVZ!|=F7{Ai`)CzAOGc>P1~C!RT>Am zhFw8_RV{w0_%Iqf4EWp=CZOOcsY|rNj?f|>RXDmaNfW3Ry>Gj2({!ulx`l&L=i!}E z!MI3__b_-+wGh^b#SQ4oU`+%*7>trceE1Z@*~ww4c|YvejP@X8R5FPLf5Rx2TFFAd zU?9U-k8ugwQNWxPI37;d+w~)8TaWPi#oNIwF{_A0fH6rJEJu^4GSb_z7aNn{mEh1H zKYNPd#{v{bmYBk1GI{ar${KTX^Qx}vEJ?F8f&0dcYZn;|qO=$#Lq0%r!$bwm04V~? z+`V|7Z6V{X`t6CUD5T&mx%%k%oM{~ZwsHT{f94CwRghQE4=`m34cu$r8{ey-Y+|#r znoP!%(HJ~FP1;SZTz@(lU0t48_kY`#EAcN1TJ}LN>$UU2i;a8Rb@jS##10D0 zKs#mulktQc6C*$#Wxmv%vxx0IK5Y@tnY601a^%H?w z+KHdc59fyY-0i@0p8%5_Ft7M~084ZPV3)4JA-DY&9Z!JP6lsqzN@p-+hY>%ft7YyV zGb9W=Ob>hyRT@D#c*qyXL`1Ct;qK+r3&F(ikpZP}RE7*7a)CUl71Urv1x5>Y${<+d zz#ySv612@QND|qQV{y1QOHzRjLnV{+Agmk;20j*1UWmdwnHti;S4Db-Lnz0IQC5Y~ zs5n189gT{<4-d21s$SQ&8(te zQthl0=D`Qup|a7}2$u9IV0r}}@EZIEr5ymJlRCo0+!2u4eFvB&jy-!|p7$OSEH8^p z+C$!?=BZcEYM&o78@$Gk83WWoVJ|e!4SQ>NafLB5r@cVDvY3ph5M?GVAV4alC0-AL$dU_O}#_G8Hj zfNI(S?~cYWHZpw1%;)6!@tzrYCk(U&3}w^l^u@C)6~guPtIcL38!gftD;9|?U7+St z5CQ>nO{A!llS3^q8`bx1*SAe0s}`Z_G4$^Wy3N?z z#V8N!Y*vc3IJqoM^CCT)PNw53Pwb@3F3-=bR!!S>y<036P17c6p2L9324jOZ_YaGE zEF!F%7U*~YffyUm4ndOI)&;~S4Wc3PBsCiC$Ejrsa3m=jZqe&hS>&VK6h+~bp3Rr{ z^F_UGTWl+bZ%`q=V6@7Uv?>ZLz*J@MuGy@8-(_if3c+r)tn2HWd+fDnJFIfP!5}K; zkQ1D|f&qvqLy433EY}dAUu{0cUcFC&a4dDgXTl@qBVce4lHT@z5$<)emDIss2>PTS zLf9y;fc$)Y<CuL!2T2dfio0+Br+q#_OHW{&M8#(IPe>5v_uSEigd60tMUEE$U9l5>Uzos3aIV zq%zqq2Vr3xu%+!`Z0vL~2H0asayZ&Wqp_e`peMoCP4KSFlJnD( zaaHD7IvSOy({WXnw-2*F|K;0<*>bj8way!xDp;LbbI?nkQ@5sZyV5FF`Zk>7-25JGE= zp-P3*)6?fymwne=UthOvlO`~Z#erG?9MI-A$t>C#Gmcv10fm`#>|22u&UVIJRxRAd zW7Q%q@-ur(@iX9^_3&x&RJA|_?;wI;um&6yW3bFIYY%C@%9E?J>6g!+U7ep)MGj3) zDR_KZ)qU@?vdqiMo3wYKZo3~|UH|a%X0cqgJ$BquItid-bP~AR#0m-N6%`^Y4B+X; z=q$+~yK4;}kj@!##FU74S1d)j-e_GEMOhY;GS@~e*BkiMsn>1qS{JlQpb0<(Qbwsf z%SNMOQjN;8^nKrKYS*_>wOFmzuWs+}?jJT??}MybK$ks04V2-S4N@wlkVr=Ajrc{b zS|}_yp|0Kt){;zzOVet!J8zYOD=jby0c2-T+%CxAp2UeiqKJZ$1Uw9p4?#fkmH~N> zKLT-M3mDAeY(-KL6R<-F3{`$;4No-~Pw*{-P7t9KQgjLdoXlEdVE@OJ4QMPHWJxAM zlRuor-8;zQSO?LNnY_-xgn$TWb$DahhA70}JG4l~|xQ&_Q4Z;X5F-W8bMjMMCZP<9k3RR2PonzR~ z1Lp1LkAwOAkh;7UHMV8yb=wM+Sg_&ZEYmm28*Ke1!w;~#ViDpS_+YO1= zIeQnFVTl1?@*JXmv}(af5Zx1Ckll@Cdr1$$S3}6E1r!XZ7MGW8+gx8?cU^~hrX-Qg z+X;56U{klrjGPaJ!QPMq1f`%_c-KL-fO$V=(0kVfoTEjPHiB&A^B`8mPlKUq!D7=M z0CXj)t5F^%BcN%vDd;M}X?9(asQ>=I`|Uq`^_2=;nWf{ZqSZm~e7$bhT_1Gfw3#jH zA70)3aDBV1n?87v@Il!qu*6FV%zK~bIUb4}KrxNTEb7%YREyaL z{%W=J${x}yxY7bL+u2Tp5ZZRT2c6Z(VTt!c1k9wNn-3rUY;i1g;y{mWA%;Pud7r=s ztRu?oMKm1ZTG<}BzDyd3-^chVI6_Sgp%3JMco?yl`Zi!dqLMC*{tUJt!%L}wqKnmF z=E1-o3S0_$DTooF;FruRENyHT@l2AW*5V(Wh)C+lkcU!1M3X-xX^c)XuXW!wzT1q8 z;>E@J6{ca!GRsFrKCUVpD!*DSR_k?8wNp2DcR&2_a=us?lfazUK^K=C@(LIo61a|* z`yE(zR#B9X9hT>M&QTLUd6>FHUz(90SOEbpyva@4?=2mA2A#8h6(ZG z;gy^Le}qLa^N~?dwP4dQdn`Ub=38PI=bmc8ZTiC&WQ0uXvw=DM`Qu4Uu`m4%K$OpRZQ8cMq%8 zx`)MhB0IM6m280n`T1a43>g@@AT1dd`FZS6{Zd{MhN8N?v8*2!EBJkdTN`t8KmW_$zT0%pBx%!h z;#d$v{vJqhLm14+Lb1mBfYz`J6uB+Ksm!U-8a~c(D#fI#sw6d7qr9KN7OHn!7f*6n zGRmofY|O&0tjT1WritsiX1(saO`4|X=jWr*cGcqkVYcbOD`4M_eC}tJ^SEh>^+Z`Y z0eH~(F!OJ~r&_gmN=aoMFV^DKE36{bQs+!0I5)@q{y%x|b9bNz}}rj88BT}Ui^X}R8LpQsJgagXhaY@cu2%OCvxjw4JH2V!O)?|scDpUoQ#+A~qZtj}44<_+Cd3AUH*S~$=wB74~&_cm#jzr87sbY8qVF{HY zKVSk7Me*a)Bc}TZhgL2Au5qxKY=S);{POJ>28sNK*uH|pS$Nw^t-d@z`|8EBvdDt# ztXA+pt1X<*hR}<{NoBBbF<-84@9*c!8fFeYV08i%;b9OJg3yQQ@OR4qKNhwbJ_1lJ zpyX@;uZK!;VHWbVfmu|RVM^XwWRgP|Mly%;VBai^qX>yaYYw%?fb|@6%b#($A2RCr z&D((;xiVDqdv;0QKLuV$hb0N|8o{5uS_5s+YIS*eIXydFtyVWTcU{*pEgH&FP)W2J z7n#924@O(Gc2F*`-r#ae%%b3eR?b}Z@L4BdPCgtTE1pk|5cEI(*Z)UEH4vN#_ap%P z5#bNwg{b2@h%09kT#?!HlgVUUV4t^lWs;1FysRpv&0@8_pDz~cw)e{G@?T&d#unyRNTq@9!S4Y5_N)@Wdut zn?&P^hy=%DS)?BV$Fw>oJhX`;-$z7{UbF}HoIM=;@^~DI(`#HN31yC~TysW5Fy*Dp+qPS(+xsYS>T5eW2@gBP!u=v)cT1~3_ z>g@D%JjxS09*xe<&WzUc`TXVe&8vsy+G}lPfw1q_>-D;>p}vY-gHu)wByuPeFj-Wx zJoEEtQ+r?w#>V1XK9myR$?$D_ z#T#Ck9R3WzQ0#+|V<1n`1Ptg!=h*{aJq05aU)!*%mBWt!&NlJ;H-&vKe3VFj`3PXS zEGGG+R-w$(-~HyRtMhZ^JEMGR6buNf(m8j1bJqvuG*pY(V)e~mzO6Tn--+E|-3p!k zNW?aZR1wLQG{$(qc79bYJ~m?I55b1m!@(~PA_k8^c*Ezs-yv9|5*@O{UYwnN@%*AH za^;;B(^;@wC480cJ|JP6*>9PI_F#;9!)ImSnvM`7$!5;unrw_UqXm|)vZy<=COQ2tTC_#w+C{5p=~Tn6L_ z!dFL@h!Jw`jM(Ow`F;X)e=ViQ6vN>gS}U&vRbXKuW#G7v(PD_S^#2% zpK4uVP8)$B{y`?yN(CIVhP@V$0ebAL>^m3w*IJo>lC>X+BP;5sM+o|V{lEXem=87s zb01qynhmNaXh9@D?3?v2wd(w2a&dN&811?y)8T9~os7rY*wuQoSk=o-*Y>_w_T}}> z%j?^w4>(waJySWv`GQrMTTjbezR8>Wxt)4IHWxbj$ zR-2}QvZyo#L61YVaoRV|6DW%@%%>(;0cgnn9^5P<~*3XhBc` z47QIbY#p)Cb(u8B2HrHSr)1`B&?3`eINbqh3St>K*u*{bZvrb}4|@+;MZ6Nj z`v~#}$puCig4x(Z3^K&QI7wQ(V!b=T9`3G_W)(22ZwmWf_$ZP58-Vmvlv6_<5SB3= zRlob~*XJiw*KUk*d16kdlgX%Rn#~Wdu7gf`Wt>hoo%_?j{&~Kry?E>)Re&w1W3`Le zMr`-tHO7Vr!SW7FXM7^WTs^{0efq`VU@_SQdpP*zL6BYW`(XEsmqK1elt_R?Pd^;?>RVY*E9xk}{%Q$Os251e0B`L&6Tdj|>*) zosg_V#YTQf80ZklCw2-zal-7L7N792hd0Keq!5&8ODk~L(j6oe#u16}~|_@kqvZBL3vfQ^ah#HJ6u{hKNM1=f|%TgAlAvx9U#;nm%mW{%*c} zd3`fqta`74(p~R5@3aA>Z|g~F3#|lE=@HO?(5vx}O0}HF9xUw3O`fIW(Fi^qtm(S$ z7G9w?*udTP&_4ng3YrtUEP}N z9ef1_FV!XfDwHf-0Q7c6UPgOdlzafqyL_k%99;5GJpyYyh z^AukC&bHd5vEnxj6|WqVn5Fn|Z*7V(@a-OA5_>?!320LrH*j-YWx?MR_Py{?BKalZ zU^8*mVmHyNMYZtL(dc)-`ReRs>>8*RMQTq^CTG*>X1)IY)hn-TR;{4t9`(L~`)Uw_`5|`!!6xWlYDN#sp1bH2hwU%Zsy+M?n&LH^drB82NTQ zLLo4XqR~4b(kbj<79lxgiAk-2d({Ldc)$({1C0-udZ(y^vSW0XvFsSI?U-BgZ49iE zdK^LC5)T8S|H?4L*vR4ItEV?ZNV94_iNWJdgvMDqeQJ}dtE+0n!HeG(xLm;y35o%pru!oh%lmUj2>O5i z-~LZ#H#T+z*R7-suy>&a2qbk`L2z9+E{iXoUtOJ_B~}+!KRY`eRYlvoy50mxX3283 z{+GY}_2tcN*Y(OKN?F*Jc!$o3m;l~LD*F(Ug0h%cV=Xr3W zNQgpLTQI}uV>@p_tiWRc%}sw2gD8~r#{$iO-mwn~b9*?H5Y9&5`)oiwj}czm*Ttw< zvybN8!O-RG=v~IhCMYoz3=Vz?wgV1A&c)~Po&XzF+F;5BFk0g*l(MMGVpNtzW?>Hn z)dCjw&~vgR;PcRRZrwC>-E7)+-FAKN+74T5T45!~9RwNCjfJF{H-bqMSm=-?FdclB z+Uckqm6=h#+0;gbv$NCFv$Hf!yWZX2-T(FF-TkTyK4hsKmHDX5Qfpn;t=H>y)2y4e z55bruO>=9}DWn2WMo7dvvSfZFi_*ke2W_#+^G*a<<)XTFU=d&j7C`v~c66wKqn4h4 zO+fITBMP4|WB9|2p%MY!aPlICiZ?XU#cwGo3KlTt#ZZimLlL5T41Tr;8t)SH${^Eq zn6Kk{2-Er~IGBN7u?G+-RCBOdLC{bws^5M6)#-E`x{da|)nQx}=cgwj_?!C&=S|)D zUYXXZKmF^UF^dc0PkkwipDko&_ysOBxW-4`%E`aAfhRT6kq-h7=GTW1BOxBW4`ot2|T-qq%Y` zLnkJoc6=UOQ5Yjmz;NNslSyv|wKz6J97NbUvAewq3?=P@va|TSz8wrQybcj#FxW8I z=V^L*c{Q4h?;jqZT6CSUsfOYOaRBm!Ea;@hqiVKR0~q{S4CkRtAalDR60{)T^cl19 zfrxqjxg!MqKmODI9&^cj537JrXlNLWn4M??2W*&Kaz=$wSzcb8UY?zuj*E-&xX9CW z(=J!Fd}dem<}crV_qQKjVpnyNA)wu97l<2BLM|~6doZ#l1%oJSc)l16qr9uCVlorJy>H%;fD0NE4^*utx&p1{RG{vvZTKe5JeN`Nxd>fa8O$YVU-)|-H1 z1NkPeNJy!EH&ZYKn?Py@y@o%TlfCP(P5EjVDuQm=_%o(X0*j$yH)L{q7=9K()q*Y= zs9L~VaMxiVb&gxc=fAG%*5iChfOY<>YVmggHr5`F@5=|lILU#@&3MmwipXjJ4aO3D zuY${r9##3pbTS@|Y=Qv+s)bnD!8>LMYm5lXyZiZKz3DwB%N!(0iwH4@Xjv@KN;~gy z#)bN*2!{s2r--VB(jo{U7bpjqsT!yj$gocnob6y_Ye53Q`5`$f{33cUW};9nM80~O z+B<;Smr-~Z=XMZbu!F6Prjp@f2o7_@C&be)Q7#G2Yy8RD8^)vI8LZE;?CR=SIjZg- z9$sDFVjFjo;_wO$5fG7Rn*?u_gR|OQS+IFhbS;dA+o*Amow|CP3Lhhe4+f+9I{;LR z|L~ufQB;7CY-~{(^}P=cvJ+Mz3|z;e|6mcoYSnGlUDuwTO#b2PufKeDc`+RoMYdY4 zAC}AD(b>A*FYEf7KmWPwduad|G&>bq*Q28jz&t#K#$+XC79c{w6cQ#g+WX0IU1m=WscqjFZF2=tY6^_mpWUb3m>U(V46Yix}v)@5IiI{bS=P;YvHABQq)7iVB2< zy6vwm*bdttJ4kQ_dW5G5Nvt2FT3|nn%pUP7we9<^*-i)u$QqbB2{nSM1;Gy@5FjF` zBrYQk(xT8Nt=qodwBKFd{p(-+nc zlGfW1v&2RpUiXL=GTL!*emG*T9s$!dzbG6mCYxXn_>wK~4nQ*{;>bd90d~vC$jUg3 z^}Xv`t$dYd7w0Eu)02@LH$-@uz;e#bSIdXl;{JZVX}e&O5LDO0PmIQ)5s;fO6(W2i zgrBc!5$iT6pV+W9k=nYAg5xM_=yL@VE<}gp!Z1DmzF@V>$i8LZtaio|b20=uKiYZ# zw3!SdL$Ha5PljORyi!;pcn>X0VZtKMvP)4d?(XlmszsV%)P}+(EsF*X*5hIW%90z}5}4OV*sHt241i{~<^A^8sjqxw5Q2>RduhexMzKLL82))o%B6lRjZwXx3? z8-RktndW(7FV4@NU!8q%buk`~XN%R#o7><2^B>PIFRrd$7;9z6{j2$W&b`-t2tLWM zpId-R$4oAIEPAe_@*42)1lxCn)!1xQq)C?Alj&qMs*F<2X1!W2R(0J34fA(7wZ!?r zy|q>-zy_aKUFG@7WL%9W!P?~#v&CJrQQnP5)!F&kbUIy$o9cV278+u0mcbb%0RoX( zVL0k}Lfkmx=?GpgRQO3Cqzs@w(Fq`RX;df-1aT*<6Gaet7=F9o2#(wUAN<&9b+Cv7y3h55w zFbZvej)T8i!^atTw8sW`Rz5^(M zELd(21k^f(O`}i>EO4bowAyrz=DKW!c*S=EyeTmhQ0OqWCK3gMMpPJ!1aQY8nmh>0kKB~ zS9NW3ayt3y#f#}=gf%)R6NlO*+SoM9iZad1`}yJzfBNR-^&QC3rd}D$7>58JC?WtN zeHWhaz%9r?NPCgfzM-VY;sb;Kz2F0j$>5Pxcq7xq+Xm$m+TX^e!AV0fWzpQHDJ%pa z)8Kxpc+X}<6g#OGhXp0z31yK_r&DoDof>2M&bM8+X*SE{vg^90ZTsE@oHm51Ba-fu z`I~J%hhU*THI7`hU}h-vLnDImIec;^R%fuowX(4mBXQStz4xsPGF871HpKAi0`_WP zV9>(JA&+l4IVPGhYrU=Zz`;g%J~AOUvC~BidHXP-h~Y!t#~>_b{5b^nT6kBL#nshS zT9kKpcel5<4q_)Jv-WrbWRqcFNK@O$nZ)pVBpBqU!eKe@!+@=w|NbBU%iAK+pielW z+^$+cwZL`@@dWJqHn_gb^UI5~XP0N^(@B!0^TqOhw)p4Y|FI}XXBX$^7neq67ZKFlCINzxjH@Elqvsv3a zt&^a(6Q!h4G9Y-i#tICmJR)cXr>2L7&(92YV*rc=Dm0APfIz1Za9jb#EWhzAKrr3* zjn`Z;Xl$?1yAJoL+hVeR%Zkv2u}26rI1Wm$px~}U-%lrFs1`*IOAm`VkC(I6->&EN zy3yiuS@sKI-+3uJL-H*1u4|g6ZQG{z*i4S*LJtDate6=Z^2GOT&v@Hot zOpy{a8*wKM!I72ED-oMaYUwbB-=o$7dKQNwUfGUFl9P)9-s9;GjE7f75@X{}zS;wm zNRlK&yPLl6TZjt~JNCY0B){UFctb^jLf#3e<4^@aX7m`YF&+dhK0wE1d3kwpd487X zse_v}Z*d$xb`WWstm@78FJHa9xoMlO2Z6%4175KMTtph7t9N49Wrh%rgaL(whh8l| zhu^#}-cV7$G<8{!*=0wDH?ZDy>+Q*7+kVj+SZ zwP`A@kswHD3@;9nRqIqwkF;RO*yoLIiwop7xyV(?UP;w!xTMk+O=Dz8M~Vmvvt16C z8m);y+qRa51DGXzxdWeQNg}58^d^3=&6p&L?*=y!at?_bZB>in22$X?_g;%?fgs4- zHZyTN8iJ|titkw)N8^3J|G0o$@^NDXorQO*7BYP=8(Fw&;lcYA4juE(b&XMeI+{|0l0>H5z^K#g`{1)2?k_{qX(l;Q?n`CTXWFXF6dbvg_jx zySp_CI)Jtc{(OWyt=N+se^ z4%@!RRauQT&aG-FBz@DU;K$?g;vCz!S1YI%53_mayc{V2-h^rra8N;aaBh%600v{Q zV#min70?m40B1zjVW<+w_0V3@skU;b=owV)gfGZ%h^LPLjp+!ysbjq9`J2G+w}ntD zOAJqf=ZrNGD?joMmWw~}sk8!b;ypeRwiSZYkkL(%rBE%#<8f6L8QhN<6%uG2nDFXc z-}IsN7>eMQVAEpBVzF9n8tASteZw>r1Rqc^$c%VhW5HuHANZ-ZC>g5Q;uw~^8jtfl z-!#o?g|qNf@TZgMS6{rS@}%#Y9Ot#@o5kkan}_9Uy(=A#z?Yoc630GPMUe&XH=E6B z-PD_=^WK45L;AsRhY5a|FAiA-WHyY-M}cjDk;W+OQL#4aNK&oT8sK-g$BfhK8b%nQ zG+r4GukQp(D4=9O#CX{Bu^TeZ7=$;x@)ZNdD_`w_G6Xj-!hxU&4NvC|VkE!forsnH z7-+|%pbgAUuvnon5uh;M1lKFyr`C)|!&SrL17aPVTVJ1B}%??h0tw)X_=$Rv7ndBGb>dMrLL_}>dYu$TwCEp{GjN~K${Ba=-H zfL#z?%tL9$%*=2o*@oOPD~3AwlZ+@1Lx=^#=C){i0gnNLe`_EgcwV+1b%uly+j^ zvQ;f;lY$qr=#8090Y*oKL3{}0CLmhmcz3hSGg83^yonF_6MqCTl>FNMe1d?%I=IQG zy1cwhvi$ny=KlU3_Qcxq<1ka;`#H@s9LWUcQ?25`9sq=mE{VP z3*h4rx}>*4Vh0U?QrR|;Y#^73l%_&r?Wih7qtUaAi!?EP*DRNdO}+N63tD&4AgXhn z^A2&U;Jt-KiY{>i#%Me$^P;TVc2%!8^{Q)I9sFcmUEo-MQ7!HsX0v(k162!V1N~_S zKG`FJfZhpNbMN`5K%_zvF0brSkR8#7(bI4*%P6pB!Gmo;ELjBUOjxe~lSSr%?Ft3u zWVQiV(-Vl;x{sKv9|vJuTWrgsRBEA2auBFhqkCRDx$W7RN8@;Y%^dmoyvuh*OTd?i+QUFW^5fonK&)dm&CDicK2A_NyD zatv-_n31N*s4UB>f<;rkUaeMr-)pVTrlMM8rrE5E6q4>;-Tv)*Hd`zatH+wMHJCUO z?IIafIPW4&lD>!cs>KT4p4+y?GP6d9!VQEu5Tvk0;yrjsY*35_M*6DOiQdXsLQQCn z-osf6l+qpRj~#?h;?FlhY6kg4YYEWn2S74AgaH_HoI_$;^SYNbfAZBHP$;o{z&4T) zdQmMXh3tLFNPfjT@rH^5FFgua5C;)sY`_^8u;27J8CPQl00iK(EGx@0OVgm#X0xg5 zT5ElBdUkqtrnFtIR(B5%%jGio0M{c}OT@hEF{w*uIq>DLs>P4S8|dN3Aa-GcO+6Sy2iaw@jbBQ%y+4S9kw4ASn{Y7rXM?o&M+Owdw;M!ZJsRq* z!5vhK;33|?O_TRs=(|ywU!Gq~Csm#%Wu9hfwr;!iru}cf|3mMC(#8jMb$M}hby?>5 zYPr0A^~1w_8LS0+5D4jD$dF?UP(q=6-gwxkDrOnE!gfpR%$lmmC!=aqmT8_Z)*Gl6>y_(Tt-^FXqH0ms_3iy^ zHeYlO2J1VS8`GuaOmCt9nHJlw>U?Shfz%wT?(q#230Zl>;0)0g+i>xaxk6BMRMapw z!fux(VI&&s+)God)|n7==OuB z(7RgNaU$&7F;*wm7HNVb^NMU-mZ`OneVl_f6+-V_Fp1Z?@BOB2>l#NuuGX7P+x0&5 zT(vS*RxPlH8nFw6nF3TT;3FI!ta_+?*5-Kz^Q$atyKcF}W^C`h(dy#t^vf5|vqY~~ ziz0)8@1pVF-Olf4b9{haU{EI-g1*L%qomA>JkPDQz4z;;l@l-4ZQqL!g_&CH;udcB znk@!!b>!y=uq`A}Y*^ypP1OQ`Zh?tF=T*O}00!YT;viuRF&r(J$`GVOhXD-WPhJ`G z2dWm_XhCbJofnktVMoJEDy2dQN-6dKv-f5_lI%#nAL)CnxkYBx=~nkl4+ewj4=V`+ zz32-F8VS&Y-h_LlD?JF%lORElchJz>Ia^h(5gD6rBrkqu5ni5=QB`@iI;T#bKdP7> z?sPg=qZ!R;Jh=NCoCgS7u!FX&l9w*jxvBf9uV^Cr zQBA6Q_a)F*erjL{$hf0K!np6|sc2snqNAV``WRyrrb}2&g_Y@&#g`<>#7(C}U?yof zLKbIU;sQHPg~1>}^o_c zzi#CdyF2~+2OyuupH8QjmzUl~Z{NOMEEaJb@65FT<@x|LV_gKz+spBRynO=D-aqzd zVA?+>TCg%}u%|(J!MG(Oa^OSoJ1x@1d6B0{WUwqr(z0%<#{I{C`Adx&!a5&{qL^Kr zU(GJ!D7t^Ry}w^9Hyb2ncpn%QBo)KKx@_k`fDO|BSV*_{O{354wy~Z}PfkvTd0yAm zX1&^O*8%3tGXF#|#wx9A8dtZ@i9r;L&;hqU<3Tav42&#J(&cu$-jr3jadmAiqQz`> zF`Z7g+wH^r@o~AX+g8p$pvj?9d%VB?e=3)<&#@cx0xEC^6In(swP{((#o#QGrEWoN zVFp=OfGm)R53XBC+g%!Z)&LN^eX2af~9EGm9esKJI%9nG#chvlChVEo*1z(<6C2# zH+9pNWwl;!*V}DbBUm6>cu6~oO=MN+LrVxc(E=T-Wv>oI$GbR27cmflz}RTB*{pCj z)dugA$j;8rzIc5VTeE(gW2rS7lrDOE|9E#lcOsTh_y{sA7jS8!zDTn?Pt!DnP*oLs zj>@WSon$1U`}0PZHPF?}N1=5qvkjst-^B(OC6Y7;`am(gHL@=OzFb>`+DAq6vJSU z74F{ZzT1aR8TzOTyYGG!FOT_CfTsGf(`Dd&P_*E9w@CURi?fKk>Uqh>FgiZA;bbzo zJU>rj6I(Ntqqw&iW|;r@m;YaORwJ#pZ9ADvzIc6gG9FjecD`7C{pO9@m&GYP(gT>CG5K3_jRo9gmY~T#UCTZ&sD(Z&ruA&7?_+qs` z9u(u@XppBiPDHfWR^`^Ub%fSptfEC(R`bWl#d3x7*?>!GB~SeE%qZ`xf24cn&Lh+3 zj}9fH+I@9y7MTM6j|;&4*x)52-kY-MLWK-CoX46Sq0D`YXlB3g({tMppY7cJC| zi0pZnrtq(#vPfGOR;$%&yU|i4Q8YV0`{LEB$h52ZL!PCR@u)G$^~3V^?p~K&Wg|5O zWC1Bnz4vuphY&bSd@#^E6`MD<+p=UGiII)!S*Dd8O@u`5CXA0mX(jLPwHD$b3a5=A zvaB9Es)!Y1nMA8PS6Gl=P+efv+Q&q(kN-Y9aYqrU7PMY-X8i>)70yZIOvNSQM*U? z=%dhgKLOq+TG&X}ZGkRYwGO623!)_rOsrB~nKg8EEJ8CqD7Y|`<;6lGQ8lpxrD`|7Kk`-iL;G|Ir@gM9MGKmKtt9Bww7+uOUlySvu8I89&{ zO;ij9%p@K~8{?neEJBTIW6XM@JkO`o>FH#WW!Xkh*R{wMv?c6_HLVW~?jzf(X;6n^ zJl|$XI>^)UU@#gD(j;!3UsshFL~VT2MAn>~j4x-ilarIGs^*L3;&D}0b&KJ(Yuol^ zjcpxA{U65N)!~l~N=vISY}C>Qoxcf5gvL=waFlY0IaPzV2f1L_1xF)_pI>F6aKnd- zIBH9Gb?ej)osiWY8hpQq*j;P6G}LJQI2w%wZx$PmKwtbo2!e^>jTx~W>CtcLPI|H~ z&`Cuf^+TnS%qmiR%^_+6FFT&Sj|?Jh97Wh|CrJulk|fgGj4^dn*A1>nw{?ZOqIEvV z3VjeKX(*V9)(07t3`;i9m{AuYM8W5IK4kB8;k{SCv9$;&hAk!W<;B?-udaftmk)O~ z_>+@qT#Og%^7`gxyAUo0t^!gD;5~Npk$?w6^mWez zkEMrevXT>CJV5s$jjZ8O=-0bX%Qumfa?$+gE(^5$BD)?<;WxYlN1FgvL(sKyN5Kvt zlz$Jqcje4PWQ=8)cL+8yG5kt|@aYggSekOf!QlMtbTk^q#;n(?o9pXk)!I0V6NZDT zJ+<3B&+7X`i!R%S0l0&9*8@CHlguCMx<_Mv*6=!Q2)Y_OT1=%U`e;|1GT4>WLt^&g zgvQir*HGz$E;=ajR}#^E@#lgT;THv2NF!s`U{bEttCJMhV&I^ivs>NULEaLI&gcu@S|_rGiFx+*sp=ch%Hm1Sk4)R^c$ef{L5YQ$)a;$<6mny?9ER21XkAc>>a`Q>)YdB)Yo zlY%*&PB{ztRL<^~YU8(^3Aq{mH>vy|Q@jOCT ze6B3<`$VLBz0YKH(TwqSe_n*%)KFLG5f21Pq4d+xN|7Qore14E4CE@d^Y9Mmi?V?S zG0fUDO_C^1(&**SNN6kTBX^SHS#<8jyz8un+k#vJgcxq)+4!5^IX07!HR? zk~B?&bFy;l9J~@nQ*m^8arXMvRcM>V!(HUv^kkY9!{xTVy}MtnR;ZI@qSazb-lerf zB_W1_3DQxXhY+@E>{nMUhJuk{vs0kHge&8F&!EX3Kuy$WFAIH-q++As=~d)rr?qfw zF_;Zf+<^$|N*1nPD+VM9D^ z%|Q4~wD@7@w|EDLxln+9cr+$tXon!vjt1bJN)W-G9TaTXi-hVrrV)51&J~UaMb1IW zqhV;>e6g6XHn>RcsqaWZc-aHIkB6YwO8)glMR%u%xF3ECa#1sST4+G$3 zZlO+%Y4EeY1A0PWGIlDeXptgC@RDhrZ{WMo`tm^=nP3vjvKr$?h^?IEN>e(d3kJGm zf|w+1nWlO78T6@k2CZZbbuen!-Ra}#&F6q<#OCbe zZtou!5A(+@(zj>n_k}P44TLRsZP;J5Za>;(5!#Dz0sl&gct_A(bUoyG0sD6}pBlNlue@OQQ!gM4`?-SD z>1VEA{i&~Z@tr{%!)_B^;zLA*^0A`BB20u4lcAIIR8%@F zWK$uqGBhz4f{%(8BqKZHvLqf1*fH+KUF^25tEy%Ip&#a`zN^{!>#IxORu6Z#Xf39b zVmRJb?*8Fnxm-5hB}rl}W?D{ij$|bbiWeP}xnUrpOIj2mV8pfEmfNz@S{2v+G&KHl z_Kv#yK+t*$o!zxXtf*ghkWC{3SzDl9Y>OKJDp|ojsavX1pcnlXp;`pedt-hJBs$Qg zWv(PC4Xw1)0kk`HpU{{`(e)FJEZ^UW7I7Rm0v#70NaQzs6h~{XbK}@=#G^5hRiA-b z=ouJ*LiqP= z{;zkmTlTwCA4dz-FLj5bF+Xeci`kW~yHIpLp|vo$J18mWQs|=5PBI_qgi8`XY zcb@^`^9j)9`4fGglcs7NZc$0wtW7XYsL>S%#^kal0B9K|pA@iDeO! zSpf9~)20FoMBdtjA-xqjdNS)eJfT2lCH5aQjKRjC)4rG+qc&E-~ax12n>(Q!Eh9%**D+5y}r9=$w}A_Y?~a`D5ocrR~NJCWQ;BB z!~E_6Yw}>R@i20F23z*5g#+eIm$()`p`-EX>FHoF*lxG;`MfMkIV&+rvkYq=;h`-< z!*W_=-B#HDF+NNPMV1Y+bXZ_dZ-X!EX1U##Rjr3ErExT!j%ODaCnqOZYTeHt=8J7v zwGK;?j&bQ@Uo-E3+{N@q#e4!VPN^b>lTc*DiG)qtQ7p1Vk|b%2FKYdXKMlznk`_uK z-!|wgoN$~CYx1teqiPU|j*z+&A>?Rrx*E`n_k}`wo8$m)x9GMPM{kO^A9r5^}7 zGLfdK+yHu0tAfu6B3WPOF$TGm14i5_DZ`u(zZuX^G6f?7D-w+5H2>Jrhm=^!ZCSz5 z*cJ_dRQV1;sHMzU0&rpeXC+12HRudDmJ zn<%)G>2xp}H_kjhE*Fb=*)$P*XRPR*X&T7=?(4?-)&?iy_h2|0QSKAohC%nNBOaDEPYpn zKz*GbQr#MAUGe8Bx)G|;G&~CB1+}+yvP~+`;}P^MbIr-o6n?|^MkiYI@x0>+yew$+ z!3smy_Oy)^uTlF}q-oJd;#FVAo%b$HlJRIfos0*=Vbl7@)%x-Au`EmFWVMxbsP-X) zy8F~S&~J8Kp06poJAEAOfiI8wt3g)}dZ87lqg980cSkR@inL<;bbtXVDp&3bl$ab4 z-VfFruY3Y%Nq?Ex?KnY}gP&&!l8tjwqVk2X4N|eF4INIO;Qkv{)pkk-_Gt%P(nbb3 zAhJ=CKtHn#tv|d4rxBp(*Y-lRV6*2A!A1_F5+?>!9KAbktYpHEIs(_--Lo9pYl zd*?iCw`&n@t#NIeCei75{KeJPU^v`v%j?@4)@57QvbqZQW@8-h(4S0XgUf6f6@&43 zGL+K*9v>eUi$&8k!5CKN(-i3$HX1=3?ST(?^{JYsft`%3EwXHwXM+Nh>fqY4s+MJ0 z*RA)hoRtyvozLFhJ>1Xd+p-qt&6s~YukwCHDMZtURhItj@Dued&44DZqD2xRS|CY4 zBVyg1ysH_ZAWG9Q^YMX_w`@}O-eY2}VbcVbpM#QeXHXpB{%GGNI&^pRq6_uHz{div zopP$$ug5!xb0o`cD#*cT<#&o-isEI6v5g|x}P4Ku&pY#@t`Df2CrS@ zHqX+_+42xw2jYAZ#*PDljhxMkkQREFuXOaD&{t6@_9lJH3IEOA4udk zd=y8UNlsbWp{w45wpP%m_F$;;pW)nr8vwnTuu3v2MYP~EoRvg(#6@WwkB6g^)03`o(X!2D30-BBFAl`t%rfK zSf(JC?*sr&aDqvYW!4s1Luyi+*q8*n>m<*TG>uc1cnwSg&Z0c_%myQOR(xr2D_dbX zf3|L$rp2fP{=0-IM zzPV|d<~Pyehv2wq(KU%o!_Egz$%cEt6iT?05RxRiI6J*KJ=w08*Kglk&d&e%hd(Tr zi`%>Vv-4R#7{0l_eS3RX*Nu(h;9Z2pj)ej6Z5}6A7w6}vXGxYVH|vLohsWirZW=@h zx*%dTy^(PcMoD@y9*;&N8`-j|7IV&8r9W94$yry*AEaptGlyZ7shXDU7B!2!Y|_p0 zL5_5hrm<`4OaBD9Q@ksoC3yu0uMy@3Nw?eb z{{DWs+8`+zgRB&c3))P4(Qrz)Pl7nfF=)Drq9{hAEX%C5P1BZDT~!sr3|v#(=kPj6 zW{!YL4B?$<5!sXp32m6ltJI5)JJF((<+{pOXp8LXN5IGy=vSqQyfPMi@jc*k&(IA< zeNn@s2x{*yZK)keNry^(CCd#p4R6VDW#~PnaEc zPktoU%0wdF!;6sw4yO>O;yKPRJ&3e7A-`~)IZ|y$UhxFFnefp^2Xi2-$ z_3`qUpEZ;YYh6i0aNP~|14tF_8cs=sh8?sjo>!faO??Qu3V$ARk6!Gb5?xMyIoQ>S z7`3uC1b1Lrkd2~L1Ou)GiE;=A(V}Tx-Eufs!)|#541@u0K-*=EfLN?~(Y~<9b2pn^4o0Il*S9yfx7(^# z5+il`y*$6Tm|aFm{4k&2-Q8`rWy8u-2+|Rm_LDdR8)+Dc^%wJ2B<2n541-!JwB|b= z*YYYaJC7*Q6~Tm^UPR;XGQeMDar{wUybqe2|GY##cUlX&IvQcN31!2aT^5_oMwDe# zGTmG_74LjeWUsGgv-8t>yS=-;HoiTXPDhhTlHwHM?(Xh!x%R9lg@!{Y5%L}TMW{4B z5rvFGpv4X$#7UAD1?r2zfU(fF8=Mww#fdG;NWAtGnvq7j`KIhX>Wtjd#Dt`wHGwomBY_O8dJs^`eXU40Mc70L{iP3e*X_ z3HD1d96sAEiXu;=7@b4PG25cJfK_1V$7>Z=EJ-BSY(P z4<){AXxc~C=lxF{ML$CK3fb5p#F08}U|k}K<1~&jg3JqNk=tkR(Z6mpDwWL`>%s z*m4j#_##KNxVku7ua-A&-&kv>)5%Eu$$D?@<_|Y_4>&`P(%?<&#s9_=P%QH_!*Lwr zQEfWOvb3tI#qx2x-3I3)n?$mH%%`Phv>s_csTmD%wc~hX$SZbZ5f*poyz>NCTC&cC zLJYfI8@C*pL>FqAf#^}jMA+J)M8~xV-yFzmvg9!D6C!rZ6+VPythntRU!xrtr(h z=aSE(XalEAqOXA6XLm#vNAL!5QsgiQc`6IE@KP)p17jL7ZKxZM(z|hG>*@x9-LcH9 zeV;!ZnNM@uI0{9Y42x_!EJnk8l%;tVr*UGUto3Z8g@a^2t!unfFD4vWTsKwCCeOBk zV^Z3prO-OpFX^416p``6Jbit2l@?tl1k53-^%;lksSFevUy@xxK!*TP&AV)izkeBR=%0rajH2L*EPefIHakD>M2pFEG9C@`JaaxgEFQ1#9yWCwOdL4Tg4(9((WvYo zl|V1s{kCxM?C}^5hQmP|$5mBrHtVWteB)RjvhQ-MnU@r}))YbroQq+R;&jtqY)ulQ zG*8o*jU)6j>}%sV3Q^3IL%;DY2jRDk^KI*EH0g|0A<&drRXQr1`yTY8FNe0Qh9Br- z2hcKVA7I5nnnryYt7xIUStE3j{|a%m>|OV!YJ_BIMQJPa!=v~P%|uUmDf-{-XY2q; zuz8Y>$K%m>9LI54RgbIXwk)B7kUC2-R1Yk4T;0htL5^|n>R_4{Nq3VV^I`u-n^O5=T}!(I6XT#JsDYJ zwpBfUT&>n+BWq1!y5l1Jpy3=TP17PzCpk;?Hc8mYEe27o!_^?Hc9x}C8Uo9cWm&Zz zqbWRAadJYKj)$|0i^*iN-EOb%?ib4yucI1K5rCS}Q6&A##&kBoPag7=DhsKKFJ%^`@0X4nPWGp`rKtarC}Ubwb%uC?-ilX<-4Wirp_UloGHlKo8z# zh$B{@xTxg{ZqlQgRO&B!A)}0;W<&F--_^OcyQA5A4vlbtqc;_lN9sW@;+TD5daZc= zT~Z6wr~(OA3Zd->-q%05argW^+#``V?o37=e2Egtouw0A5PdpqB#^Z64 zBo*RCS#B#Q=QgP7fb4oQ%v%CYjT3B0fVBV>EmAb*ah60`l4NX8pm(LQ=xX8!xx%5g zK%&5bg4dH_@D<|8t2CTZ?u{NMoSEktBb~=DhV~EzdUi?VCD5WNI?*CY66ai9lj|-5 zJ-e&uzdjr-yL9h&k2Fr#7Tv}B@Ew}zU1$6_^t&2x`XImj!7*Sb7d5W?k&r<%OwMe1lk;ND)1Wtza zDq46%iyHHCy!kuaI$^YKWbx4%Wr`3jtj*C{B-7DwGRntAR%9qcBAWygJL$>Z1{ES| z=xwv!*6U5RtyoNETeo9CX;o|39|Au$BI74T{_5&7PSe}@!`=Nu>+ueHM6`gNlk)sb z_?$$GfBGK~EqXIY=&FvU7B1Maz;E(oXT~}nk6ypJGTz_af|HYzfB1)gu-1O_%{R;C z^3|(X)9G}x+5FqrUzcUoQPobg(6bNKT~SfwSC?0((~}UwX3duFs;ZRpn2aa0*?FGD zRaGz7o8@X#){WzMfrtaX*=G|Xj0jDdCPkJ`hgr^YeWuPg8(17zD7>Vlm~n&#~r>tu4Zt_P5(qSqBl9D+3RKq?*U;y|wvMiG$TZle7RbzO07{@k_Vv1k_ z4&YiO3IvLPpoqgLet1z?;Asvp(PGxmbr1co(}a?}?*wHsy0YknPM-?xiZJN06-^|! zb!xW8v<|vPT?XM#S!Lw7c(z`M*Aa;09{n5=Q(Emi<@SY;QcyWa<`LW4vLr3?EYCB} zve>fUp=nxYVs8>7-H1)7*cyf5pm_c2>il%NS}w2OzBMM`wP1)xvtZ-(w!FEY&sS^o ze~ zlVHh{Bx5sAY%OM5PIMG)i^8yFPQoR+bKcQbtn{!0!(ay`a)|4`+g*GVQptyS`RiRw z=~}p#)6MQ}+tzsLg~e3-A>6*|IOs2NYR+^gSu)cu`Io!Y;H&=>KtOmO6r?t|R(j>v62!lEz1aEBPeBH7q6V|_Ro2nM`a?hr2C^tmi_e6^*644@0PDaD=s2CU7 zAWyR-i6XXLuvma6DBpNI&pOW*j`gNmZOZkw!kH(VF6cBy@aZc&HhwxNuC6X^9NpYM zJS-OP6)k?#TD%M>c>d|1{~aa^VsN5tU!UQC(8~csA%r63Ea5ng&(BWJ&Q8nC=Jw`h zxm?a>v%mlQzi-?2%P+s&Y&Nf7zdqq)>+;{e{(8ff>m32|7NRV0G3G8Tb{ZchlgVtx z2Aa^i#bU8puQ7CsqLY)8)01i2*2~puwc6la2kmuaqgb^T@aP6kJxh~8mW_v5kz)H~ z*;>l3BZt>qz{w7A?0wi&Xf4VLDLlBwdly@KG96#4)}k!0Z|@(M%er9i$Rq9YPv*uOCJCw7XCsI7q|kg;=Su zRepD2p(z~JASZ3=yEvZ}3IPm4qX3D5^?q5E5H65uQ4e>}LUnzk56wJLk-uJqZke16 z$y*0u2U#>fgl@&@W_N{=nxN?Nj^5PiUo)@yRQ}*F#UBGw1SlhmL-sP1K$#VI4eSIB*9}NbBBFpnMiqo=jxAXb^d|9{7 z*d$OOVBtx2KS*x}@&Gs&X;;!DiQuS4qb$vQmTOwi`hVlkvK54V?Lomg@ppY=kAt7xTiwO?0|Vp5&^&0!AP>6{aexRl zoK@aE&ajM{OeRqrl^6<&�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

rcL!ek2`jG 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

D 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ⅅK!i7|DoEaEx$<2f>4z zT|q!Rz@sp^Bpmsu4SN0A3FD6LUk{h#9tEc1sL2}uDrPBs)2wzsZRw5wAVy7w;MrDV z5p$u^TL6*bCi*J~0GOr~JrOg-e?xt-FwHS`_=s1LyKHniLzos9ALF|^the`QT9#X# z>p&asJMeHaeEXA2C%MNcOsd})g}H)mv*plJS?#9R>pUcK5-A4rhKMN~p)eHLTzkbm zF0JhA&By_sVFc)PC^Fmzw6D;&-6wiYr$F!`7+`52naIkkQRC)1i;1;nP)4h$NgxCS$1jBqUSvC z2>R7An2Z*DKhv>`j17CW7PTZXc$axGhLWioln`-|4@8_~FyEPU*C4~|_scAc%$=G^91ItI^|N=){%#iy*Yb%nM>vS{9oMIckbPPM*gfR_q68p?xe z^6>4=!-Ey9@`z?PHT9ahbJI)i1O+)N9}w}Clc9WM@$xI3E;vtehy;A%Dv*los@>}_ z0;wNH04Krx9UmZ))E4zpbnEVb>c6HtlYSQhl&tRN!iwYnZ9w7B-q-tXX{l;3iqG&y zALsB8%jODDu*HY?!4HKRc-WwODIDEx_|ex9(-Gb-sIY-3+*iLD^P_s$lU(QT%+7d;YUQ|26l!suNWp1D_*Op)QqVe#~qoqT;h6Cfyas@fNP$I~r z@kSmQ^mb#wL&d_WyM^87hd=WdZItfePl?aZylgs)7i^E>nBYWWR06sp+6~IS8x)e8 zs|CXR84-FD<5*_#AiMRPB5P!5u9~;^z{*CjnE=IyqZ>Is{lFL7t|)@0?gAQu1GvyY zOfqIu-y)3oZekdbq+hhBuRkn()r zaqwLaRKp~b>-PLc5D*_CbRn!bTRL^Esd=gU`!lp=2#oP&#ZQ<%G(RaHsyWmO8HqS_ zsY^6Z^;d>(?7SrFgYM6P1=s7boFq~6%g{H?G)FjB&#b@U%~LBvBfhG0J(3EbTd%>S z>p`3lzJ}i#H}Y6t_w}uBEcj1kTMK~(j>M1laXVSVtzm|Rup4eP<^=Pw`nGO}%7mgs z{#e)M^mMWkPL$cX`24;fW9=W)uaC>i>@;5^IsozoC|t0W{hiO{fbaeF#-epI0id0e z_d49Fdvr3V-Y$OR%X6pu=pwboXekzxcsN3spOk0&R@e$e93;X`lXw`kkgWx?> ze{&x(ib9f;3{1l=ykNLNY7^e!`WWfa~ZeSn;K?$?WD5tBwWa-zJ>&!26 z7->yn<&vz@hg!@t*y;7^E4okc5ep&CB0R`z{V4H?yWvKvl_B^6YTRN~x(D5~+12xy z$=BCqK#v|L0d7=7u>;N4l4m1)f7xYlH7U-B$_%wOY$~p7%wPMidmQjn3~^|?{%tS0 zfYN00i_Z?CuuW@!0f7Rw4W&$XAALMAvgb5beqfVpPM>Xhz#&S@aG(1(f}|ymS{s^8 z^)oXw3=<|^^U0i*d7B87#g|qHqBHwoS~rK!uDN4G@|8!{<$Yb2mqhHC= zX~(@xq{S&2)`*VSJ_JPa8mFQpKa$6h!JIC4kNR^-R?c&Sjz!pFH^#Ye2p2#O)5k`*mBahv9z=8pE)&9V( zT?PLv*9^iSAc9EA4X?7oArZHjS6np56IEC_G_jx6l{4vc8KPEX9iI1_zktzS438X+ z7Z|HS*^qU^8-bX>W4KRm5I-o)_JZmRo=GfX6~Yw5jO@TmOkcL0J?mpa*__TB!9L+q z7x}lS(iYdfqoxf~?7;S%4g?51X#}t}Yzs&C5@3^EtR1m6`=76E z%H+Y=52mu1UaZ^_57IHwTu#E7BwJ5*VML-XM~!Wh_(a^!4=z$A5Mm!}X9GoNvl%>m z4UipL#0V6O09=*v0176I0Emlf%Bo@DX72Og{#Y?53W%D!9~NnnY7FAn#=A*e67-7| zQah5j*q<*3p7W+D)pu4NEzm@$E2Xv5NQUGW>C@!59=GOV{-uZ}gZ{FQSR=qD?9X(u)}HrrHN& zEs8;YvdkUCI)rh!FCy$8;mv{`jUPm$RAg$XhhxxmR9)P4m~ZJZrme<20-ANIII=p1 z$r|kPZSq!na?RI{R;7heVo$~DLz7|Luww&kESJ58xx&EXmdYiu=)cCUav=R-itq4) z)ykO>6P7ptL?aZ^);0$xKYa}q75$NYwc*GG|7pPsV&tZP@Gz_3RDsBGdc0$xHc8!d zAO^V?3*7NZjJX|_unY5d_N`^+hq#>0@8zdN05uatJ-*E4l$OUpPSZ!nX-8o;x;T5z zG~sjw)S^pxwZ==dwEB^WW9RvMhjms9!U*0mhr4gPR&RS@D{Vw#rU=+ZuFltqp3qK^ zRCnbkZBCta$-~M^MYpp3*j;>aBIs$&$X^gV(w1<#_H*4C?&Z!zZgM*gy!4~!=z|Z})tWFWZtCynK!Ol)6kH7i! zMj%aVGY-9(*gnUuLinz0N3NxgY}bdsTZ1ksXEy3A14kf^N9;NK2(feQpfFhl7#Qew z)s+xtSv8%u^+-BpIdc4P&9WQfyS-pBW^Lu>Ao!Z3%Wa`Dser;O~NX!%zdHF zQkoP`18J0hTmC_N)?-p48c6kzA`!udc>8&H`|(>Iq0^gyk~ZAo+1?6Yd_L4+e!uQ~ zEZ$oxo;|)TpKH2rapmD0zk`UUS=nE_ryQI3U&DHZmpT>=`nAOlkb z3#pqAem6>?Ei`kVq)cQKI&yrw;)j(JSI`lN}EEy9ZvU$WChcQo zlNazg$F^4&Q;3EPR!AdQ#pgj0Qy6yK?FIWZ?aI&8DpHgDS&q1DW2P{|7~xvB)f+`R zz#-?B`bGA6aOJq&oloZXqV~)<-oHArQpW!Q6;ySYetB5t@uFR)Me7gqRoU_~Rm}t9 zsuJeUq<@vpVME48oo$zLXZWAV%XsaZ%pldtnVs*+!62$`k6Z zBkW0eV|{CTifhlW`k;)-zIPWN?Hj=G`AtL%Xe%dh8_PK>A1xM_{(1gLZB}ZLr0Ab$ z$d;oVsjIFtsC{IjO3H#FA0KQblJzr!x6g8(VhrtW@4b$pemF0-tn(;{jA~BIQ15`* z5Wnaoma?gDy%-7{kXRjc5Q0W2H7H$S<1g*N4}Pfrm7z9qkcf3Hg!^JD1duwn zCTpB04qQWV675j+xzHWr)PI>B-9Ed%OvEkMyhQy-LQJgj1Yd~RA$@9DuoS@y?I$ae z3!pV0*1OIxcOzMWc-HU$);2SIM&oQQpU=ll)Ae8_=WosXc3l4@c?8o}0A23KC%RRA z06)N{T@cl`62|t{@MG|sBWJp%riP)mCclhM15z}Sjs?^5MEr_K(C6mvbdd^4k&uAs zcf0M`v<8*5=L%U8jhkN%ahdZkw1Mp_R1g|~A!NkhYuqajTtC2pnLDwhu1SdQt`EL%de538!?8xSAI2i`W#UCsAU3I^c`TCQBjJdc(=42KEEYZRAq~Y3@ zyo)N4@{1JIzrdwhMH*R)W%Xr*66bVa?bS-?%}xLKPa=4z<;9VaF+=__nlaoL7VQg`g*E`QpQ%t68=n~3MOZNp`Gf?(9S z4mGLz?P0EUW))1_wfD8{F~yK07rfR3)mT7eEBk`R!cnpWRW{R!;=UHc>!c|5h7_1^ z=}&*=S6=2rkOY!K3Hk&Zk( z5}ZKBuZkDfbFcN8<6k+p& z-a`~CkG^+=dXwr0>WpC5pZg zZ524^G zHZZqzKJ9~1H91M^C1~h~IqAOY(P6&x>=)OxB;gk~&KW*2#~vj(;^H>rf!%2mU*uY2 z{>yZoX0}c<-Ln0;j=L|0@V4Zd5u+7#($YYN~=j7|1UC%~c5PxKG!|(;Eue%(U zf_sqJ`fi{2+jmO?FL^b5SdF(Y_r-%ZTmC9uInBe$v5{kgFWIw5*2Cof)n99e9Q__} zHX6#Zt<#EV`tqm(M1xcX_ELD%hb_^n8-om+L z!R_<#@zDi=mC>g4hDij^=QKMpBo$@fpULT51l;CvEP17by-E6?eXhHJSWk0sgxHc2 z*8BrniBr)Gsk=*Y>K(jh;lJ<5)5R0HfUM>@4OBvSacaF_E=DR=dxWgsLk2gnEWu6) zgZJ3M=kNTe{4n)@jq6L?t1Xun-FBNC{E8?JLCKe32&A^Lq&aaXvy6z-vbA^1V^RTU z?(lK*l@41anr!*4O*TGZ@d=wNcp>Aec+?~=yUn;zyLD( zs&EffpC1ujpp4(#c(=d$BgoRIsHx*aPSn7@VRjGkP`5moAb>r_goFe!L{lSCa(ItF z@q@9wefL0=_ec&Mny8Nu*fZ>NozydOIh0Q4r9ye)LAtXRoG9Y{J7a}Ipa+HHu9W7-c1e~P59(p6W+=vz(YV4k32@ALzr-0vpPi@-W`^hB z@q@EH#n!OEw!-9<8b~dABMzbr$}fy*PQ6dC~g$_?lCx`%oc4x95W(?2K?3ye4+$y|P&)IT$(q zGXR`dg^5rhe+o_LoUjn{pmaZ}`?o#uQdiiZe)J9@>fgmUPJxg)SSNgWeYFrCK^Lu$+QtVUkCxnEj@-KDev=JY7F0IuU{H6Uk zUIUpmZ^6+1&`7R?XLD_!+5cE?kuB>{^r&Q&Sw#-k ziuXn`-%m@nWVIV&MOVwW8^T_t+HnE`%x}ZhW7SPIWkH}%j#@M{QAl-Bgrx~p>6Bxe zDUQlODyG6u8pausId*s|s6ZuCQ|4aiL^oBdCm*t@l_)v*Kb5?fnxvsu-89cNaBEX6 z;9cv46yt^@%=kA7`y@i6*nuxztvGzSZ`5Pg7ovJV^M_oY@jA6_0cu@#gh@t9hU93Q z2viQTrDq*x!Ohj{;wX|r0;l}_abwJK#|kO6IukKOUw%)}{}yoSD-(Y1k>q zQGp(sRXoqf?AU&}S+ zNr0P2w}GJ^uzN)y&wS2ucsac|vk9{)&t6cKlTH~?W4)$am`oZOoM+ilft8|$@VeB$ z`CAs;^&AAr1Miy$Fl=abeo2WibxcBSx?PxM1f}qGbD*765%@W36#ZNc^?rt^dP)lL zqEN_J55l&0*kf4x#IXLU3?1C*wBn|}Rkb?WxZYT%Sk>&f-PPXK(b5(<#bRjYL{dZ7 z00XM*wQ-Y{n_w~%I5gH#v+9l)`!kvro7E6hj^q~IZA-9CIy8G|Yv!ji?fY!qRP z7=2qfs^C&_X5Wl7aY;pyaP~kc7;F})-`Qp~Ke3*&sm;Jsl`rshhdUoXB+eB?RO{d9 zL_-xNYYsmLUiRwAQqlsx=xnB2iSl$>wHlDQ#6I&vZVy>rf58~L<43gJBf=Z_%>Sx9 zH}W^e?I#5K>G5Tt$bssll~ApY*OwIiQv>FybajJ2<4;EBS2(tqt#XLklau^Prdt$Z z{1!vQ6x`mc6PbCuk;u~0SDVZYAnQ+RAR0n9UER+Dzz_b$x4x4J}4LYlb%%>-S@Ze4f?+;!|@ z%jMwf@bWSMamUntE25FR!Jq=3HWWQ44I|MdxedG+$rqZ=LAKOKU1~V6=Ott9on&;~ z580P!JL|##|Lfo0nr<=p2E)RGAuNw)frvxkRoOwv3Kq;1>=rHb)6 zVmsB^DRq{?wri$lntIxycsSBasR0qubS|Gix+&oE?Q!|>FLzh8Fx>&1Am+9@MvWm$ zJbs<7&@~J6v}2}6qjhkUIk&TRi%vCG3`7lUvEo9y&9;5#d8`ph7C*;PhN!V-J|7a2 z>R0O=N&7RtVPz>2HRv4^5E&SlVFA_<^YG+r-+_eZy&KKb?XWK^1xEx zg`}hKnaWucjnshohCM9~in{iccS#Rs+j&UD#(U{_@S>)$;2m>9z*YG8JRQ|~=`8iMyX>iZlpW?zE`OjtV7twdZs^iS6{5d~| zI!bMGB-Jg#dOT8DnPl(#*E^76M*Vk>tXBPzzeOR-qAoJRQ}jexPhVCzV z$NIYamQC|Oo7pDLF%)@By1#F!(L`Anf{1qK@YG0wTR|ZH!H>c5E3&h#F{^gcQEE$d zc_1_epn*Z%3EcA3BXu*%9x$CaG>yqS0gNju(x;X7!lxQ2pGozy_o#PmdfGA>Ga)Z8 z-BEX!Jq;Z46cwjiFby9V^6%AFcKoKr-oE?PnnmVJ;bxM*r>p1WH zQnm~(aGQ;6t)EceNIeLGh7UfJB9{FSU;h9Fsu%4G|3;do&o}AH zMyPgSV3VcH{F+u_!~td-L`*In)x4j z;=fCiD(+>$D0ln#%oe0~2I@&0631s4c}?Ufs(xK_Hw&Tgx!4$ssQ;_OOc@6>e=VNh z*H{wCR8~do(fnq92pX)*fkEmkX#V|q`ySSfFi`Pv{e2q{@Ob9V8(K*1R6L=XGCdm! z?yB5|#hBaUb^AA5tCmxWNPBalq1!sM<2=q&fHAYi_IyJ$!;U0|pBj8ZoAgI_f5~1~$~fXiQ6ww3pHI;n3xNJsT^7t(iCwDm)z;tZyy=I)mbQLfRre!>=ZoT$CO}wH(h#;9nYR zDE(Fq4Gn8o&xN(zXzp7q7wVX1SP1RiruL??Cfr>$^99kW*l}X{o*!_!2P~ogD3X)e z=0Gl}gGpIl=F=k=+H?C9kei;6Gw}V$-;5|2<9R~vRfb8FC$RBpB?ZS$nK^_lq!9qw@s6a@#ml|Ou+ThU1z_*RiY;D{;Bj-yg>=`Ga=HlX5o4xVAJiT#wS z`~^mK^5>=K;FK2HgpgcRD#tg$ix9SJ$1^biQbO)((*y5%E%+t~UzALw+I-0{L{E)> zi>Fo8lO&tL7Fh^Z1XVOK$(TQ8?(%A1=>2GH4)Fg_%xrpARZ=a)})r=)j*n8|T;RtcqUF2`)%RgWlsPWn?=8 z!)M*xP9OaSiMx4$)jL?gZA0o)(t9rSrFP-RPa*K%&j?N-ZAoI8)y_Ay#~rLY!G72p zlNEC;wI8G_$crNk=F>_PQH=WJshcNRI%udf8u0mg`BYR5uMdlFKG83drZzmcRKVsP zE5AI|T&feoEKZ4^vJQoI)J*f2d3dKW{+>KPKPOD#Pj87FiROeNR%KqBsaP<4_4}D0 zM|K>P-kp4apH4wA$rEy}8*QJCNz8wGjf&bAa1mHh!#v#=D~b`85t(SPdHkqvEkyS_ zlL;GeyO>^qpJ$%Y);mNO>d!b4s2^cv?l3;-!jomLz3uVYvE9TJO~*vr*4rAA;VHeW z82B`j>IEBnplSw6(b|+NGI(GcTw0_V7XDb#_%i^p&mibe>P(x|gpQryRZVs|()sUw z4&eLqL4w@eoh8-Y3pSZica&QL^EUC)f%O*H!;lkw3AX2S3Zqm0F!ejk;&-V7@DJJU z`4U#~UA=pCW{U(2pgK8A5~y8$-t+fA*=*~??1d%1L!3-kzgQ`<2~oz#e#>bkF2W0s@xyi1eHalH@09=^?9W2lF#%T0jbQ`* zbDm7D<_5JIl!$^~H-nSE6gRdAd~}VEwm$Mhhqbl z+rLew(T=f9^jI4$_WiEJr7=qfy%NYHqdU`25Ulr~Y0}pas%P~;hKDw!?kJC-caBAe zvh3LEFoD0eJcGR2jhgG5@k_q6uXkf1YMDqS051+0l?mNcl3T(;};f&Cw)WX)H$ zxcNiYX+O@oR`~zCx@nSV^R~2uRHBPrL8&j;z>kC{L|%3IYwJLhvV%6{LE$%MBFJU8 z291E05dLErmlvMtUcmdBGMzNSQYdXDKYK(hS%78q3_%VNhrZ`72OA6^ z8H^}}tFDyya2H8sD}>m#&1O@#ZG*)KYcnjBM{8`J7nAACWm(&G96Tb67STCD5e8e@ zNKf5@E{RW>#`Qc9?Ak)nUb|S+Ddv& zRZf9B>Yi>%uVfWS-B4pvB3~Sg7=dP?{7fp({lPsf($~b^>T6Hat3rE=KCD;8IGnII z@*d(Imh&@N3tiKdpC4qGQ0hpk!Z5rQh+zFN_;-K( z4>I#PYfazPHioJw*30?n@$tX@SARH~R$Ye|3-7XrkDkQn|L;Hj`Rx3{7+Xy$pXY7g zHBDno$ehcZ%lwwLP?}zmbY!=(?8Z4^402RdA?()ZUo@-LYFjyd4PpTDPJgkP3hUuA z?~RFNQEbiUz-eUO*jeU1InZJyUnJ&1{)TfswN!O;Iwj zy$~YN*tY9eb$fO>UpMV)y{6=rRl``@1sto@O@nBLffd03)e!LsCXjB;m7*L5edRVZ zh4EEaEdIQUy(#RC{7h(JG-bUelIWA6Y2H9ee2l%3cOxaP0o~zHZ-z>6sLYZ=)4xG* z-w6!g;Ri+@;%qI$JDz%1==;7Aguo8E$IzM2y|*q*i}JgdFCIO7(D(ht#l_|Id{fuU z%_c@yVwV8kr|a?XSa)pnvq5hmlB%khRF#XN@7oxLJZE3OuIu@HUN@b(2(ZqB6e4<6M;KsPyf>DAC8vKMLXv$OrS}PD>Akx~n zu#9hG@cR+bq1R7|{Cso6a!C*Pu`30sC zXH|vlU628HKMbmR3+df-Hw6^wr#6d5?rr=rQmIn~h(=C&-$iPicMu`U)2$S^jd4kC;6}ZYK9913nr3?D%R&dKQaM_}ApQKy z=JNUYg{uFp;CA)t7P2j(*BeOBYe28xDDGk5VFC_oO}4RaJ*tC_yg|O8A>69cdvSQ0hvKuVxd*To z|M7qMcd9BNTl$E0*w9-O|L}+3KYRM9t5#bVL6=xg?U=bX)5W_-q$rfi%- zWEkr?j_@(`Y&&OJk!1z$i;<8jjqxnn(c!<0#0!`gj>!Tp#pBS2z7PC|tdzkGnX|AK z-e=yHSstV9`vLV2KC~N*-E`e*(_Al>tM$6=I@E`}XCt}mHZ_t`m`9eS1A%i{6!kml zb?+p#7yA5dXbR)25vGMdBkX;BZ{+7g3!{nal~$KY`IE8t^_2J+dn4}#T~LarSGo<} z>*y>ny8WDt92vD4Ts)>a1FN1vuDqqoSq!_JxbV% z)v9g!<$5#3$lxk6XHfWQ+P;fe`DFJ!M(u}2P zKGs5Er8Ux5OFvWBvT*-Uc(jO6-svh2Z(EcJJsRg>SG=4R>V|?c1Kbsz77eK17x4!3 z4s=e?t)@;qfrzOE+LO7W$AW^I?p2F(d5(&_N}8Ers1R;M1*6t~-rD2Y^yQ1EnYFLZ&)!@ueq$}Z zAXsw$qksQD=;|B7fXCl3*kO45==2YN@ndGqYH?lUc5*Z;i&@u)pI%?QIlBnPR+FjE zvaavz2D2?L^SQG*%GU6XN@wUKuDg%QN9z0zYauT4#F&OJ3$`S4yklcRs@~vhc<5Us ziLLKVhDP>|o>n;xItMb@XkXwvZ!)R!yo`o2AfS%Z?xNtI$cLb4AseOmagR3mDz_e^ zC3reB(L3vnnN^bzV&4Z8M{u3ttzcA&mG0rsr$W=bft2_ddn50Frc5ssdRk9Tb5RFU zN7TYuK)Y5<;1~GIM!Zq4Mst^`^PJ zy1rg4>ZWV@0r@J}8Qha&R!(X$#;z70h8Fn7bK}=j>uEr*X=sdJAHQ{XINhbPY{4;S zrk*wqd>DL|n@H)8iy*WJ_n;AUBY* z(<*$;QwvlC1^T@bcX6YHzdBMA{RV}y7O7cMAR)!1z&DC}SpLsvEsS9YN}=vn#l8r# zu!v*I>M!#ZXXK8D?a9&X<@2XDhSzV-&*sYr+wu-RyP>x8*a6r-kL|poKomhy%NKZ80qKe@%A6&>X z%VC8SIA`gJ87`068}9m{X}b`k^|{S+jApjoV!6CpELQ6^!YPr{{b2}5b$4Aq^wHRX zjc-gTixl7C9px@4%_p@68qmcuQ571Qe%?U3JBEIjPlmp(DeE=SPoE4;^9EAlW9*H* z1KM0j@H4rvxel?5v>Y3mNaV{-`Rx=A&j<@<2Gs^3BM2Z(WO1`Fo6Vecb-ig@SY_u> zpMW#&y4<@bPai)#J+14_<>eKJ6-9~bNyPDd9NMnNzH`$JQKWi$r0z&O%iPgqGMkjn zgwS`!*`lh9wTs0PyUBGEVsJi_lQ%G)F||_C6x*xz9Bn0GezwG-#jfaB*|ppY>X9Rk`W^dd;=H`yy&3E0kk9t7e<4rgn>g&oi~*I ziy`QVQ#Gl?mra>vt`HaF-e)e)t@Cx=UC$Sn*9%NUz?KD$JrO4JCI-Wt@D8ZjVW5bX zLXMGMPq#EMzNV%iB+$3?sj#r=i$pBvBtu3u2EI_UJ_aSS)UWu&^?AAAwkLYEsAbrxmrUOXj_SqnTIA#iK3 zu6}xS^z!*r6NaDPyg6U2#tWt5vm0tVi5-B$JJsQ79*WPd<{m%?|C_)3+wGkg*nN!Q z$)gAV`j5XKn$2ptU=^QEU6yyBuKh7Qi6Zu?~ul)kV$Vj(^7v1Kefk&qO5 zo)=|NX8!4e2h$=)1H`)_46S(gYZ^9jje+6GvyyJ-Z6CV4$f~?3bDxVocgDIKow63f zGjw9e(>m`wz{zKgFTUE-sVdS(h}MffAkz_{n= zGkQ&U`%_+$Z3o_x*SYXN7n0k(rR^_}dvarRk;spO;_V!-F_?Gy8rlUMLqn3j+UqoV>>~;1BRC4 zaN1=kG@@UJsElqZqq`0Lh$)MRK$M8q+lQyeFP=Ub`r*~t`NeW6XBuzuC0gn5etLLQ z9iHZ)_!2d}2`Hj}^H+aQw6wSl!_lPpi{Jh5{PF4K+3PU$rw<_rHlD;zFsd^bu@0Ub_lUm0V=HA z49rLH7rRxMKENLEuGcsXc&P?AzZ}R~TJT=s@FHm^xq-u9A598S_L@$z+GGu08a$3p ztj`PQaA<`P4h~Nch}xUc-pIYc)|tgpn2=h0c8BQz+^|e11<}5*=#n~*Nf$H-3Mc`dn28r;WCCa{TWOs?IB)aHoW8NAo?&@oq5hJ;WjYxCTjzu-@$KK&Un;$Y8*O*HjSB1 zs^i(TtSawqh_!S-5QrlRGz-lR;oh*#S{qhdk{_Rnl=A;)fLF!CDuZ;vVNa%Z z*3Y3=jnr_u(ye!$JYjF-H-y_Y`kHvV82`f1YO-}DTs;0P0Hu<#xYw;ic<=;V17&G*JX5#lRp8WC0 zANpo<`R3Kh@$rKvPnT`KT5m!KmzS5T)v73~EYI5xO-cluq@jf-VEOj)X=Q4Ks!l7G zPV2hQL^wkE@LQk*SoI=8#1-PCs&If+6m$*o53pLU>bgdfHG??!C~4sNZaRavDDpfG z{eU9qmRQuR>10@y&8VYg`Y^^+MOGA9Rpu4eYhCU!6;&1pa1Vj=2i!8Fp@EV%Y(t1X z%cF72b$zv1UR+*x2wE89T{OP!k%{kzE+XqCbx|hBZYRJUoj`*i5h&&rzbt6GThrpN zj>C(j^ZN}P{`%dlg_tOXXl8f3s93;6wns&7px5`|z}#i_w0vUPUyK|>J!6%u$g*iw z%%;<_$h)pvuh*-#t2>kjLO+yQ{^R#QoSYn8UtXQPdDV8!bUHnGaC~%hWWCvJ>iP9@ zv08USjLrvaB6G|VLhvvxc2<=~vq@$x)V6~g-?Vt5Tx>SjDvJhg2Sg(s5UH)me$TCW zk+x@42%L-)qq8vE=-WGYw8kB`66l}C4g7|H<%|#^C2I|=yZ1EL*038Bh|97(%Mg;x zQR2cl1QLvBf``JpX;n=sw6lzX(Hbyb9z!s7+vC`C2>oDI>*oCO`U+O73%ClQHtf0| z28t$!UHZ8GRHU#5lqDNKoRC_EfF8~s(4?~br8GVTWcQKK*)qMPRZ9~lpKsI?Qdl4R z%Fs;pdPsZH(_}HyQLlwhuYYkQ)$Q@y z2jK9o_iN%;{`AJ!fBRQ|tK-KRb3C2=@%O)be0ucrpZ>+h;pL0xSv7fee!W_+i=sF` zKX2Q1Iy(v>)-A^ZkY%FQAac{z+bwIMlBNlozHZw9V=xSsFhDSAJkKD%0I!lkU*yNL zqoTmt%x1G$EEaWL8-q#N>2!K@bfhLe={iHdSuOD*){4|bmQ__%h>55y!^wu`#=P%M zm19?`!gwvG793f)Eo%{?9YW{^w6n2;iRen(b)C;jUle_ao2JE3=xV*%G`IuLiXldE z{o9~(N-aYSLS5csEp*<@_OTXJ|4UC{Up&E&#o+}=Q~Vf*zkUa6!A=I=50HpM*P$q* z(C8|@Pk(z)v%fF?24waWqCGNsdCNaeEnr!FRphe?dI4b=mdoXQQ?FYxHT^Its~>;( z?&RqB`s(u4tDl>uo*f@Oe0VyUO`UU1-K;kCdb6pUzK>=IF_{0Cy*KNTB-zdbZS^gd z+^c%IeK{Or{_TLz^E$*Vn0XkCKoOuI2m%F&7t#YIK@TD%2qMILySplv*nPD{_|A#2 zii(V?&g!hHtnAxgcX_&dxSQK<=h)d~1mEjr^v38>o{dLko>@pCVl+1E2ftWvmg^eK z3yXlaECXg#g`-u9QGTiupODbl`Lrx@ghd> z2qd_cWM@wtg@#R321%wVbLd@;%VIJfkE+sOiy@Rn7Nn3-x!~8EcDaHpw3L_8GumOrJ|9_rXsdfP3TTVJ)~gCl% zyI#Eh@rU33=9|lli`i=Z!}YE6VKf>o77OovUX*RuH*Lp$A(^#M63%DgYH2I6P~6x& z!}6fzxs}mFI*h0SAjdta5&6E7F6k$?UWm%MEnPnL}qjb(Cwm}Hdw(WYoZre6E z#InP-uGV=D-h+MNv&}Al2!y6m@RMtGS!9JZ779`DG?kJ2nh>SKp0f8L;$MIqq-lHj z{nVMsa;0tE_IHcr&Fx*?brO!GRG{E!j>16FtLS`iOA@!l9d&E$W4%ji!PSDFKPsNM zd+kV&p9J@o13dio_p=s;q*4YPrjgn@3QNL`^`1|>=cfapo08T!%*fc5Kq(FPWy)%k zTU(a76tb>2i@M%)eZU?{sEYhgzWZ)E9^c*Gyn6Mjcm0%Lvkb9Q!29^2cTLx|14Jtv z?i~nTDOu&&sI00gH%i42w6V^|<)&V&5I%mNwIHT~Iv`k!ZK&gYaOLkG!6w0){IEkF zt&^iSIkkhIcFpu=#ZfU}QyCl&k^TYh86<_pkTCd$nYT4M$2c{4Zi_shj;oWC>A0#g z8nK8!s1Y#4`7mGAw~OVbX@#_Fil#rCFE?EegErdA!KAiq(f|(Gc@nK5pV-gd0_uJO*9z>$ zc8y5@$@pMG{65eSJ7Or|k!e024=>UE%u`z&*3!FxCfMT5Yz7+x0t*nxf?o%Lxar(X zyx1T8^ap(%6uSg>t>Anal2)kU!KpDccw&rYZnG?R&aD~*#S0FeD@H~6+wZ=ejK;S& zH?Lp63L>7Jo#jP=-@t4`a3`f6oU1#?&B$MXhe*sjrDOqPp&TX$*1$`*HbIDW-QIHG zJfU`kEabne6Ga)-DBIgW4M5C>8Izj~e17y|OYsAEM!cbz_rb3m0P;+H4{1^(&@_PH zFM_rm6iFvgX)#8Psly-w1yt4yWS-zFusmq}hP5zSBI{>EsuKr!CQ&#rU%z6_%+-3bSS+ z3~2q}L9b$1Lc|SaVXMuH%Zsb?i}iB#hu5z+gZou#@ezR)_s{>&zY-!&#^bMET%Dhu zHJi<9zIgHC;`01#Hk*C_>a~k;Jee{zCWIKA@B5+c5%(8Fz>c+03dXW%x!q*S;5nVa z(`$^vMS&fC!tUl4JOvPYqO=GmhTNK}swRYjyxRADU)S|&wOX&&%vWIV)7b4>S|hwx z2G#-}BN7LUtbzTm6i6^5sYPy0W+Xh+U=cva3lUqjK1L7i4A7uH1eCYy`@st(5$G>3 zqm)hCFITHMD7h|1sBnZ3+5uD`D8m@RS`alu2LT$7kj#ts!G+(y^Fcs;QMK>mk!e02 zT=@^d{mi4nc68WJ;ytW|Qm_WL8mxuVrXOI{#a0$vKSw|PL0^|jfK(A)N-K#= z^tIUcy|s2+RZ{DwZC7;-Pe;y=tLnS&z8ROJo15$F>uYVz`T4ojdeb1>TNE%DD!I;~QN299947g`4mD#l2&3sn3J;&EWF(kwSLIiYcFt$)W!u>sP z=iz$bIw5Cqa4E|-`G{2Z*5ibu&4m8H1ICt=@IEIHW*cJ-jRFBD?Jy~A;D`;o5-_yj z-vMiIBs(rBM@cD+hIA1+jx2;yBDw+2q=f99Ti0#f^*nh zgD0gD>|YB>tVL!lvlh$w;t#K0H?YSzTnOHQ2R`=1c;coPLjJFR@lT38dvSGjb$O|! zTrL)wG2eXiwT$uifB3`A?W`D8lj*c+8s3Q{BHQ%?C^M}5#z18nN^Dqaq0melln_qE z$O^{zL)SdL1|ex%AJ5=6gcbk~dp?2|QOYWLIw}ijH{nuGBD%T0&%{n0MKq?*20r!l!J>>2eNJ; zg{KfqjvN_l>$<(2%@&JA*AEnwK*C2R>Dr)BR0z}oinL`dsJ#OU`8MeO&j&trjJ4nt zADQ^i#>2mRKl6$9dI*lP78>0FDO*Hs2hA^(f_4lH^wB`?|HQ*H59KE%u<5=fi@|6F z=ixQVgFDq)Rb^Eag%4p>Z@Q)q&QHhXZ@&4aDy!@3*R$CyFN(>@>EOe1z3KW6&IZVn z0f&c!?4pK%j-znEC|#pVPe$WORajhu>xHV`95Ed{k@gsj7fh zhk;?c8VB?V~;u^p*$Y?bTQP2_$s5?Pu zjeP7>2T^$n3X1e2h%>Mp^tlk>Bul_0xh`^wv#GW40|I(G-@|9L8xX@n*S%Y<>zny} zxmoutM1*?c*2H7Kv%UYE%finb?GKo?A}VA5c!2FsJPGV7k8g6y_wXpzf>Zubppa;W zEz)^PjZgTPN|7G>)JXNrU*ux~U-I!FhYV&dm^V%jd0JaN-QA?h#w z|MSz6Z@>L^JQ}T+tFCRXuC6AN$$Gv1$KU^cv0R^DT#Uw}uItEGQmC7@>jxh|IivEh zXA6LcL2=Niy!NEV#u-hld;;P`sz|`2Op@%>Es&PPmMwg7=GnL`3^p|39;a>Fx~{vf zWBcqZ1OMQ??+9(%VmA~z**OP$@B2Q`J}X!t0@56nC456!C`@Sy?m|IdDl;Hp!rKZ_ zJrwmwQ_sPV86vDXFOSxN5|2bk#BM*iH_zRqlRb923^H)S=pMbWhVV!7#tK`J;_F2PpkWrm>g>-BoG+4MaLb}_Wz z7HT{iO{=0LFRjYhu6MVK1FqMVqA=gS?-0LvB{aJa)KN+L~x@rXL-3Phve4t6IvKMGzIl(ia!Sb*ZJ zps3?8#`DhguvE$Od^{dkqYC3623TO{14J_t;W$HF*UfUZxm_;nw)GU%0(zXJxW?bb z2WcHjNS9n#ejtH+IJf@&BmbI?M}d~W;UPHATJU#25xAtBc&Z8%7@Y@5Cm#`yOmjca z3HzB(EyA6XFPX|u&wq66_n#!S;5mVh+_gUFyN|4>FA&^Jsa)KYF>ZCC`B!eQ^vpg; z)S3qW7gse>Sh=miybgTC8lfwt)9eQ(B-zkso0n#2%z_1oPe2@MG9n9A^N^I#^!mJ zu~%6HtFSV_qiol8P20kv62=lmu1;@Edg;M zi=rHl%5jxfMP3$JW>jXhRiL|=5>2dy^LVctT<<7mGpxs5Kls7BNF}f~ud0!;rmow? za(Qz%6A@+}QcCAT*8`GS3-%aAuC(AIb5~Ix7d)9BfN$KB zODT-id7c${J}wJmj2rs8W(T$o78jsfRGt^p65;c#(b{H%_jk+nV!Z+L?_tXg)&gbR z3Cf}dV=M6=W6bTb@1}ZoX5|=DtV77u839cUe zLFs8*K}4^j58%*I`%dI_ZW#I=smF*iAXE5UUY))=cK zoC)Gn+CzB^x|-`vvu;`lh$8{nKxL&}2upwNVLf=5tGTO2({-C*S7grDO}E?_#o z3up-(9)e$4iwA)_*};sj!&B5Cjr+9 zw@9ibva^LMM5>?tg7Y~a-^E&_7t;xY-{K=<|NPnExn%xnSql{ftQ8G5e1$|TwQfLU zBvy#3%If9C#dJKL-`)LiecQtx@o+ME2Ojv?=ffA+A3!?%AOG}kzWer@sw$giGjzjv zG96E*%XR(z_dl#wh{k<+b!m*L>zWn5!CE*EVFdw$oK6zOd{EB)%l!clvr0)js-U-# zMgipTSzm13Itd{lNa?$_Y1*y}-eYf5%3&A;ND^snRul!u3_6MAscF4l*LCf7!SYy- zi>XW~nUqCUT0|VH3fNj$=;BKsSP}az=d)4t4!h4iY-pW>Pz_$FLIATNq@GMB)9F-5 z)imvouU|I}glpG4w;K5o*rNDI%fx2JHpIMl(4i9^zP~(g##0Xj_P_fc@bgTGVuKyi z7967?fHe`FAp{S#9UpxR9@IJ>hMFGw-Uxbqx^33;+1<%>{6GKcpC~0>Utc>HZB{xj z=Bv$ORr?U34x~BoHdu?I$SCgK0KWxo+xO04>`H60X_=pmNx3i2wx-OhHB1grMD#RL z0|I%kU=jiiy)9y-NfHIYWGVT;M+{GJ`~)f{^90om|rr;8s|`hQ=DHwDTSg zwYq+TI)W0T4-qAy0z;xi1?Jr159R;hWdA1jKt6K&;tw_SPo5ltn&DwU7ry^w%EqSv zMgp1uNGFkiTYE+Rh03U;XXBe|dRaO?3zYI}V<`{9Ql zLKJ6bXD6rA5CR)aw=JXx9t*bO^04?K(ghSQ?qNHr@2y+paS|c(@Du0^#dQDK*%_N( z!&rP6nx^TxZoR4<=zBPA0trbZj&s<*WWq&jJqD_)i!**Psg6jAXc$n=HpapyzRB~v zEb=1Pld2q5MM-K=R>>Fwh#ny*?6HS`QtYjY9-G`?BnAf^C;S1C15Z%i`wWU1)2gbp zvCB<;cRQcWW+8+;FO^pPFu=VOI1$>T)!P{pk~h@+=fHcW+J}Hz^*A_XKE7+de$VR% zNa^h3;jizr7Vs`doeCN_#$;Kh$VP{(6vE)q^Y-@+(RGjUMMuH;7n{24NstS6 zMaqy_TS0bV3!5pehQ43bb=`CwIa$kWJ}I;FQ2}l|D+ZWq)br)4?ph`Z!9fYoG%DhV z02~6t4gUyS{KQ4@_>u-1iRq?+i*UTbR1sGK_y$NgP??dAZpRCdhpWge1=lV7JxGy* z=~h`*N_MH_%3NaPxY%yVnuavC~N9(EU6QBWO- z2P0J71_z@H_*_8Appb@{M}p^+@NCP?iUbMiWFLH!bB@w@-@4^^J8SIgjhS(e&nZSSvdXE!%@c~M?nT^2>w_1$v0?79wG zK7*sNy)6nWL}Bz|^~TNp5sqmUOZ!{U*u{t2*%+fSrYy_xcnqS!m_Rg2-}g;juh(k? zln@$P)S%9{pQN2*xUl5t-A3zbR82=?B?4mi5*g$Xz`N`FZn0Q|5R_t{QI?$UWL06t zWnPu=U|HnGY6T7Si2N{X(ZjL=8YM#zgZFUz1fd1!8K}?`doe(`7HtN#@9}t|ja{rZ zH#fI+-9SskK>wmgd~okrhiW%n5?`?`%SXh~?sZWARCT}uzk4)I1~)4oQKTLDwU47W zk0PbBkB7f5C>9&mZ1^@sYFMjeWPVa1(mbiwfcO`P%?zC%fOG!v5AmAEG&eqhHWdot zcsw`@53xvqR3tJFe$*8niZt7)`nXkUSGDfdAh(yu#alYIvSM2~N zcw_~wAkVW#HjLey*k zRZY@it05g`PMg^X6o!fcc?1;&1vIgAf{ow1fU(2gN6_Cp5m;?-K-?LP_F7ve9U)HFh-m0UDCS zfcW=XBj*rJY-bdF77=M^;{xpqRthaZq8Vtx;X4d?Td}O5abdr$nq?5M* zS_of!06=2hf9!a&9|`CuyX>VCZgl>_r}+A(NRu=8pbanz<3P?a+r1?*_1Kzym}m|#?lEVg+C;M zOBr~M*e}$VjHhKSh^P}W2Bo!y9*h}ig$~}u5GJGX%gc-0X1CYZ*YiaW_less_fvS_ zW1kOSV1EE>@pu32N7uGP*TTu8&AgB6O|w{S?&gcK8ozjXWv$+9HnaJ>?>f>d!CMeq z(8Q25qo^Bg2kiFGJWHVh@lUt*t zjDcAT+Catrt9K!`KET$(@qgegz+?11{O1DD%Yu^CXgrym3T4{1oz3Tq#VQ2IG-8y{ zjG{SlyMc;sxh=)V#nJA?4Y7Zui5ivp5FAaDv7hFyX%6w8*AKv{9pK@wAFvj@oFmW* z6qdAz(e>ScXcEFl33(Y4p0s*#M|vQb_SPWISq3Fxqu_h^&JI}ea0rmsOQpdl`$%>~ z8a-diQJ$Yo$LA+gW2I5@_9Xk1{!4~?4t`y9K{Y)0}^a7 zx&?-3zzGB#SjK5N$B-vpIz$K}BG?Bk@bn-$5=4kJ6>#NHc_H+m`2@ZeSbxbtg9_=p zfKY(L0EH#zeA{+lGd#ZN;qe*mBgt1TgCk&4Xr02tUE9#M;43_~8?eivVC#VwLWnYg zcfkmwkw!-}Gx!R61h;VGtuDtsEgkt}ANzOGd8A&%kL};&JBRp{wYY~=X&({Xxc6I` z?|&ZFB6SR&h#0@J7W?2jK>%57Wzc-2;A|Q@1q^xuD z7SJ*v4UZ^@wZIB3qk;wsNUX?F?=X;I9J;G}B2*%leXR3%TnSNTx+;nihOHUwo?*a0 z)D0{uU@s0T5FG;QB-#eZuW*W_1(*wCP4I}S0k)*br2u`?wKXZyiJ~k=qfwq&L58PY z+YwXblvYJijEcN6qJ)x3o@EGdkr{(^9|>a~b3P7kfNq8hjgOs!6a{<)nQ_BQ%`iY& z!-oMpLxkn2wTS08nPhpsTrRI)zus(W1^EeLwDqv+#$L44Hi{@?P|>3t5~cZAxZl0D z)%7+Nm2m(01N`IzDgAfhCsRl`n$*Kz7m}Dy>R}WT9_tm{CV}WwfnutYf3pbFp!n9( z!k0(EI&z#Wx;WcRfLO-?`qStyA^0H#Y=p3QjRt~H#9AOuwz3h5cJN9uEz1|@Coiuq z$K%o}SrnPlvT57(roNl6e)#cvzO19r$mDiZ2?K|%utBg|WtlCY&Q~gJHVuN%JMVKX z$E7`;oQ%d3WembQY&InB6M~r_V-dy=T22TQ12YOLlgD}u#tQc4kQ;bNq* z41kBW%Q?6s0Z}23Xh}*{N(qF80X>ho+t`dfa^!h|I>HdZe9iAPb>qE*q98bQ{*(Yq z7GYseTn*(+M(jyS({St?*@p9 zVVXgu!^R$WD$Iwp?C}ZB^jOipC_HU{I112Wzx(@tAW{O`lvsOxm@gJLx3_toUtV60 zCMVAO+q=8XX47@>8qeFY*eAwH2{r>Y&(sPmXQ0mws)pJ~qSP>JjnGPxnXy@(<3?VdaiOo=L(yd*dWA2jU0xcHB=;W#Fv0!M&A!z-}OUp ztr?dO+x{)3#}%ZDlGzaXBj-}&@Ks5M!x}wQGq)uw|22}vFjj3 zfxLotO$Jay_=l?i-butbE{oIYw8O#*YvHq%I}Fw% z`iE-*=Z%jCU#FX(?UTuKQV3>R866Q`i~wxv2M4kk?=e7xB8~!)zgig|up3|G+11JT z>xlRV1?=U~GOnLvOS0jYyj1HKQQHo68D?IAkv!E8AYT0?*Wkw=dX z0c<>2p%}pZq9jx<^bnA|*d9P7^G2i5T8hFbgYfnlS!N?nB^VBLFi3=$Cx?|%jBPhS zCyjv0K}Btc09Ras#+(uby*_eM+$axBp9$Qt$G9nffegYTm% zkt>uXolsi?e6l+p8F`#HJo-_=UwkTX&2ZJF^Mw5(KQf<>eEs1-F}T&=29H^u4bb=Y zzV3_-YnWtvqqc{t=O znJF^^*?*Re$K%tJQ?1pjSFgUmeqF=&C^{JSw55q4BPI1&>Z=&A5!+Wn2Cx>Ns|xPn zk#+Lf0P6kU{O8|8!Fhnc{18Idb&JJvxm--A(-$vZmQ}TB+MCbS^Ag*9?f8!8Fa_J?-zJj7%UQ)6n{inO3FECe!ih zbgH#nuU5Brv-PG9%0dZV>TU=i8hy-UFoNhd)X}!B6FY%fa(5F|@UfAW-iXlx@CmPi ze9p%Y0>6HMho|$%*HLLy98kTiuB5lD1tjT2L8D!X)@ShZd^`$`DHJp-Qw9u3_OQ1B zaDt%5;ZYc5GVXGU5i++J;GRe;oS(2xzER!+7;0G>QA)+a(qADxzJ)+ca>bivz zSnpvk)KP$V8GLXptehgG1Yj#XhO*FxY6p2ozA*@eg1I{h5hT`l3~mWlSW~DzhB1%~ zjWY82tYLVLE=_y0&_eX!D`4ZoGKvtSGA?dw316Y9W4}Hr2Y5nbKtN%#tSX!3JTJB2 zq>yVoLhlklvY?R&oGdp2r_XorhrmCj4wFvy?^7kbd4;jf+s8)w?vr4@iqd()evu!U z&qu!gaG)4(`o+3@V$5yRXoaG?&2BUN`u`g&z8lzV~i$VQ>f}imee$Q>ga+>HP}_=lPl9 z8L<{o8E^%`i7*sKolL5;>GbS$!errSG?Gf*-QC^J7K^5tFBhxz#(ANPjpWK4s}PpL z2=SR973HWXKCgVLwtFr;2c-P({{Fv%H1FY0DMmzxV2kaGi;EX8Um9a)B*cJ7Awch0 zNCoFKn1bOgexDAG&;xh}+ zboiW8LnkI)w=B!AUR+&GM-{Y_uw6GERpap}#<(H)Ae71Kw!6NaHGQvjrZwbk#(;vy zs1jRpoJ_2>wMI&f9RV=BuwTfm9gjy^>-l_sH=8Y2o4Or(AA?XsfM-1|g_2O(0%=ZM zG-p+42oKTmz*Hd17=#fLMD8tItB53%K`4Q^GsN4YT9kxi7cA@KrWwM+0gekC{A6(z z5q$tL0|cJCNg1D!_z)^^2hNX-!YVl6%5%6~Am`4_X0sVQ)4E{T*u;yThh_Ew=>8%2 z=KhhvcTjwyQRw9O$V(4=M0|=gACA-nT!9BKa&_~~N9Oa9uRk2ALGSV8|nDR&04^@#sO=g6~waeQGp#4T|kc#+MZcPQVSIg6dSP(5+bw~y21C(_XC_g zbP&lxISLxuq~1nj7IV-e+wQZ0JIOOeB3eE*9$8Cp;DI1aG7Nq6{j@5+x;j5UJsFJ< z5Q$c>JOr%2bBhX4gBTA^rp zkH)C!WWvGaA*sA~zL9hrFAvKB-T zL2%(h>t!=QD$*igUk4{P!vH}W0bB?dlvKgIb4tp|cyxJjJ{na<>-A=HcXzi~ZM4ml zHr;@vWq{HNs_ZGG7F<{Oa|~!i+5tND5zycgfJeDzy0Rx(<-yV87<4AI6IwA zC*$A)f^64yh$1gXy$d&Yv$h|U)I73STmZEzY}iAs4>|w=uGLItp_k=d-!{WAWJaBw zoD@Z|TrThKppRF#-4FyUe3XHIZ-^b>6nC3N0Kygl%_+1xmxW=dxTr=0$ITElYM3@* zs1T@V&<3QSFR(|V!3g1}hx#I0R|zm_psWDAf{*S%vm}@tA`2kop<7bOs({qmS{p)a zItVst`+#16WevC#44)84D+;x}kFXO@aa%CnMJT6d-kf0NI2k^kqw}Vey}oLo}YaC@@g`!MD*6^%tG2ez>i4V`zVy&Y?|8{v<6n2)|37N z76MF)B)u0AwwJ%M77qhhi+}NVf8R8XLS)~(>$=%&)^%N$lFP($tw${4Hb0|NR#kj&ws#0?3yY+g#TCLiyL!@AsH=x~i zkV?Ze7DNu{k!|{l)T?3yO=8J*f`tt5yhM@&d>Wz$qihCC>mFvJ5F;RVo$?+gJK#x- zDG^++EQ{>&WMnnSCQxQzXh3voy<;uN0nRYc?nqG1iveyiffl>6z4OQq9>c7*EkX=f zt3n7y$x&6FpPincohm67konBW6R1MDgy?%0P<|kd($6WiU`hgi2)zDr4euX62%N|P zIJJl1k*{-!Sg^n%3tr1PxFNFv{0tr?aNg39GeGneAV@*e2+#z~_wob0fbn|fK|-Tj z@=xfubjjfJ?N2d|CzIcN^Yz)d$W+LTD$DHh>})(LqYrKG!2LjMq3X83oiEm#dgvhp zAa=rs7-2inbtp(A->*VsP%oTRRjHNqeH*;fTA!XwCgU;Ol+EV1^TnoV;66YZ@{5K3 zNt`y66=|YG_M{NO!A-3Yk(P535o&M|T0?0t%Q9AfqRCdr0Ph7f$^Z<*-VG30z>ES@ zxrR3?@IRbBF&3ykk`rz#guwh>YN-f@1Qjl&tcubYc)w*E_hA^I`ncnXz-}psk7%>w zO`E2~x$;ws@FgG9O+MjQ4t~OlBHkqXNs&JNB;ewwmcrQ{P`^xlgLhnSw03NBVm5Zu zxD(rH(%3c{XJXrGjHa=z#%P?0ZQE*c=XclozID%^aLzu@yWhPZbg<TKyNfX*k$l(wy+dTzv{d!z?H)Yo&IzgVgNJaT;f@}?r zhTWa*e4}V~9#w&5RSQ2o+R1hpGXVQ8O)vcwi;Er&RC3At#uZFg%(mCPkhxy^$BS^I zJt}SlOK|L<3AQQ3A047~&`z5;h+bUe4Sv*Gu?8@6$>%E@^9CtFF~W1Rh0N*H$!p8u z#!1FeqQI8gC*7B z!WUCl-$aMyFYT3Rp3>oKC4#rbTgy)oB8s1!Qu>{onB>y14577`Kz{9*R=8k~6j3v0 zpPNi=R64rZL{v|wH%gi5((o+{UnKHp0YW%ZIwBnoqM669OTx2GyTIlT{7DiDB87Jc zst|a=7)^iz;%C9SbA~x#^O267mj8mncDlaB=T z4K5)Lt`qKu_QE4EZUE>W$Z28dO$wHp;60jsMed|UVvkwiWW-jQZOh20t`nl@U}cDZ zi49pj{VDTuNKE0Hq(p>%5`u0iedaTL1H4b)Vrd(@ypnF&3E`_1mmF&= zy}oL+Rnl=CBaHYuj{*viAYaC>`+p^q@tHL2X1YdT0 z^D})W>QbF0{z@EM*`&Y7x_D|FK}}qBUhdHSaeaT<(J?7)t(cDztF@KcA%X;r+&j3f z{=D1+9!tlBI3Y|4f8?aN2$7>wWxy=xyHm{_ zxQjThs_6RCa#d{tDUz}+?fT_8`_(?Zf=fx-cTwxspExKe#2I^>>>S3}1q9H-4UHMd z(9-w$Od>LgE~KMGV)~{uV4nzSmbEh(3RA%V&zxg|fNqVIA~eIY!l9%o(z3L%EPzCC6Ui>4u`zK6aoG!^-I)GfsmTR~!bP;*I0 zz^SuRCJ4)^B)RUp3or}P@1y(vZX^nFGVr7j`He&NKnI4y@`ZCfRz@>;!)blM!C>1A z4t53P-MVeyg&T9Oki^cqk*!LS>bs~MVt2*$J|j9S=w`{u*`|EA^7Kp6##6@52S-iS{O|FM(1THA$)%%z?H2+;Ut5Oz=K7H`&ySB)aUuM>nn)+_rq>)f#v zlmgc{iGNiqoaIf+`a+fn6nfj<=0tKNV z`=6rXR%k8|U*mrMs}apZD@4lpfpZB(OO06w*a5W8j;I*$hqKBq1)v9qXTWsVNIa}0UQXNai&TDYOez(3x*8N)pQ{hwChflsEWb*<` zUY?g_j)m}Nr@IZ){&oJ^xM}Dub2cxbX&`vBM#%d(s}W)ru?cJv5^GdOr{X$$JZ1r> zPW%-LrhgG){=q>)yo&pGn!E3FFsAWU0SRao(`|Krz4jOccC=^h0bO-s<5;42?2%!DgHRPAggJh{Urr$uTjENQh4qXRD4`-WArhY)}^j zpTdCvu)AtzX!8idwz&j>1t+&K05CKC8CfYMcqVST8Fqx3e=8>oPN8|fX{YtuvXX>8 z`ffrybzO?D-$hKqCbE>U%9u4`U@vbyk(^DW?6~La=^9PpqV*lS3gyI1DJjP!H7uXM zJuLJS03XFn1)ERdV4k(7ZD4+|as4f43Q-==DMnG=vim&-=jZY<^6LL|%j1dt73z;? zfa{NsqGPucy3!Mmz&wR`XX$3hp7*r@r@IH8mrY6l#j4 zw~@3r^KKaQMp(A#h1FtQ=kaU~2CHB7EHqtYzTRA4bMP`_`llgIuER$plWq4l>-Sxg zT;^vb$Ho-U^*NE25p!X^ysXPFJ)>L-BnXJ)uu-CN1mE+ND@HxJiDHL}k~E65NxoNn zsUz5Uu3h1VxS1U5UlyqoKWqaq5PZTB3<$PvR|ArRC@H-Osf9Yd`AW^#=@D`KHDSwM zM6Tu8(X&EpNBTr^p){qfS9ijlNQGlw)5BBMgES z5el?m`e(5#t;|!(Qnn&k5dONqSuc;u0IJ#GOYIKx~x9t8DuZsiF zEyHZGA@E_@?;!IrIy)h1TymFY=*d0ePiPS@m>K!4;EsdAj(qzM-x|B1MovjR*eDzf ze|D{16f^5pBA=Wp$-`DrKQgAL8@rA?E=`FCwL>a#DR!v0+EH?PQf=5`#H!`=H+8h< zF&8%O``i!cqw@GzWi_g+77UG_<0E6Y5H$BvJ;(%jGZrq?mzN7ob#&JlTeFyPQ$#vpC;$7$Zb^X28tB$qlZ%IU1{Mdd#gersq{EuJne zwy?^$R|-)6sMSW1Ls5+w1^u;X+*e8SLippXFyEyAXW5QY*C}{`E+|JNXO<*^2|hGy z+N@u>gNRB@8P?|F4K*=?Xl*tSI)B95X#p-g3;H_+CG`D6bTH-_LO2sqq}>!X>4*4! zoE33M|1=YCU(YKB=yF>4tUB$Jg8HwZQ9E#B);;kxv{5Pw#ZMuB(Ugjmx_shotcJ@| z0^%zPL1GR=20Ea!VYs@7m^&eTaw48_SH_gZ?ZOxXnhB!krcZIqKh0WtUCNFS_K>E0 zG5ggBO{+C;5;gL+QC3Kq<3^ufRJq2QxDE2Gtk9Usg7}lk<}L7c=hzl6}{3Zp`hi;hM45*9_AzTC@5*~9sb^x z&17Uu!P}j&;wsPn0THWOcTk#N_MO|!G)M!GhoUnByJod7yZW9|4?(&9EHI4l!;BRveH1l0 z+zKO3JR-};MC!n(mVYZK8J?D)*mMgII1i8rx1jjp1Th%t1fBW8-Jb9 z&6~nxGBD3u?7e_w0BMjtj$nq7mL%6$|A$O$67?-n(Hi*A!m@!#elndIfxTS-uj)<&Rt zlSVLBqSlW*!zQSzghTxpbLX zv~tFyg{MaB^sKf}z~HbjT)Lzli6?;*n0R>9qIRfA5|R}22=RW2pK{-2vhCz4hYWx7 zz)+FR3OB=!4v_SH$t9bbQjRN0=9*d`oq4kY-gg;RX^!oCfBO=Bf3ROsQEnaElsPs? zQM5Ztd|Oh7WMqx?sjB{p0w`{byg~Fp`JU8jHkC9?4k^gEb)MLU;4fsgWZ65 ztY`8;>63f49{8^I*$P38ty10-0)ty9wa3^8@h{my&6xO>tDFf`$H$e7wHVN!8F^L5 ze3UT)X@QO7nBsp&VTV<)`=V#P{&vnyiHvs1C<8&A;!TuVptOi#=htT$r<eC={95UQ#4ZR^4Sn8lz=7)1tVvD9mNL#9 z&8F_-E#;u`%r8xkrG(`hHyiohH}B{Kp% zOs>r+6!ieM-k2P`x;)Y@vBr@vg)byi#jYZXnwgPhmbUoP2iv6f+gc$Pyax<)QE>Eo*1(DWZ)5v^8`$&WNE`Bk!_RO*kE~C)|bN2eqr_) z^%!T2y1@NyAuE71goE9J{vBkT2YuM4L-MQOL8}PWvPAOzY3FRuj9jeKz`5SMBJP}KQZ8aOjuqhsDDOK$u(WZ-qBiF7AT(Q8g2T5BXZ zW7M(A;x3fb2;tF&Y7@&I?N`f$-0bl&NLuOIJwrr1C?}af-r~nw-*tM^AQEXoum}3$-$AEe)tuWE%n3Zszn=xre1?UYSeQ?pL zAQqVql0%0h(k2h?tO*L?9Ri4#r67yNU{8NliquY7V~U>k%R+C8mSUN#ny3w5;15Az zlPks5U)9K>Owy*ntCTSEbWjzk65rIG&m&c&5N;Rx`qkds%@;Px*n%v#42G6|Mn2=- zN0s#=h>6q(CVt>aC@}aA;{llIVA7gs!GW|1Qx+JA;nT|*C0zHS5Hm2}HXaMB zXCviV)z3E@CXfL3&aFumhb&Z(p?1g|t3nl_XInQz?y(y)Vyf>8ir>%s$@(i$LS!)e zEl41TRIvn!%qQQ9B*H$)4)Q@pUsb9oWa3SzDc&My_fIqPhJ$ao1?-=b^&h=M;!O{A3-H(2}5m z{v%X$hhD~ML7$q^vA!tMyX1!{>4K!ILtP@xltf2Q6eSuaCt?2P95HzGmNYFeNNP=% zCRc&xA5w&9mnv%pv`i?Lb^>!|Jb;S_>-i8ut=fRUt%c>P$jSPHDVzUaS>D*_9(j~^14-nWE%BJg5%3@Am34) z&9=)~(+CROJbql*yy23(2|0ZCSvcG)paU2cUaI7tbC2JgE!xx*5_|=n#O-?*80_^f zcKxfAz^Se%N0ljTVaUlv=-A&6pIVQ~IkwO=|0Urzb@!UP3uu^KVed|&J z;v{hn9eiz!Cin|s`$aV|;yV=j+kuD+LYi2OEqz>ali2X8h?!Yp%H+s0d?~y=D z8LY@Wb!`4|l`B^mmJ6Xzo&s;^-YlAmX#c2>bOhOa5G)TNX-w;3&_!{o4pDl|R`s zLOx|o4CQ3R{K%@5o8_H@Y=QXSxBf3;ix3?)g6?mX)afV5rhuKePSHnLel?4*GfqdL zlC$fiVMuMqQLQ^XErf5A8G=+~1}*hD92sw|uyjir2`}I8MWJB>1JJ14G};i)oTw~- z_#8PgkT`GZV~mlq*@=|E8st|b>VEcCW*Ooy2Wv*as06PoL=C=l!K@#+#T+J;Af1Y9 zA!14Zy*jF0OQ{cXCZeI2{-Ws`ZSvvg*Y0WNEV(=p>Vj~=daYf zmbXO>yG75S?|T5V<^8Tljn$1xO-)|j({gKwu%DML+#-;OMW#lb6-`18m&5;G3C)Mv z8}TRK0LV{3@%}2jwxL&(#@y=pldKo<*VaArTd;H3#OF#Kf@Euc#yWk$autnv?=J1C zG<>wCUvCD&N>`5X+e${cbe@mEe;xL7E%up^%Y5aK_fzER`jQw0*mwt6Plv$&kO z-(StBgQd|GB;c@)a)PB5ma>dUxQo$a%d|@*tWq%WBWp(a14t=@YS1{aK7kX04JC&{ zh3IQ_l=CG-r|KplDb!`AK9o5@hf_9}n@eABVwBiVw$ zT;XmISC-OicSm=(c2#;pUZ>*=2G#JEC9VMS&bYKW-s;`&fo;|-SIR}D;pbztB*0E(L&dRc@ys1+6+s|hZ&kIy+nuAhH4d5o}h3?c%SQV2ulnC(B2 zHiOtM@`K29Tf#rQ62*y|tsFc7tY5^g?zQp*OlI7$RtgsWmNUi&F(~)3XVy{md1Smr z-Q>#~EYYe}JXwP-`YpbP^Df`?S<~1dW-aa3tKX@_Rmdb1 zEtaX^WXR#YJBE<9kY{41r{KgSgjfkm4H1V1bEu?C@_Wco-9W?F4zR9!Afv*g}bkTgpk(n z&cg_q;bFP;m?vPHo^8#vc5AZ|j-^Tm_rLv^%iyLNphQuO(dRX>+By!W+`%;zhIBQr zf1Y0}7HhGX#L;yw|t z!P-$`%t?Rk%y~howyf=VvMUb|W*F!XL#2xl<+_bV!jEx){)~a- z@sF~_xXCRe!H>PR)0`^)44N1V09g}?XiKQ|Qp+M+vld;o8`NYW_{env#%1n|S<@~= zkm_(A5HEQcAnHc>B+0&$ou|DwGd~db{l?~oK@EZYh#wU<`9ZM(iFt!nCFV@XQ3Czw z!t2#&R%J}EPy6&Xh4*8!4|tfP{@f>HkRsAkFAN9s8oGC?P9F88qKR&dUi3lhho&KM zLndClh(xOZLjg#;=bHtB%O$~zxlVsP(XO(Geso5p;_3Drvq>tt#vu&HZTwg&(NBnkk*I3R6xnYae<{dxL)ufxtsl9kqZcCKdgn zXwS;?V#n3b8^k@44fabqa3CYt_}QZ(r@Os9B*gKL<@Rm+vhen8@w% zLtxAPak%Fv9TbX50b9R=y~0-$F0Phow))DR%3@~$N;cIrar{PtF9qu8!)RBaL6sLb z#6Rq@yg4DwSHLGgnO_grw{DgdcqBFug3TU1!qSq%@@8Wp_FXqdke>bORX=pY0NO1B z(~<+{aHgf{5UaJ95K*u-5X6yZRiI{&n}5AoMh8szJ2obP2%Oqwhv{leo~K1A5;YBg z3jOx;ZKq%Q@0CHZno%Qse8}C@4(e(jP@z>~rZr^tQ&~i~jSzy=xZJFoq8Qy&(+);A z9mi#Wq+YFewW>VKV~huQ&mh2SVk&4#*S$IY(Ue&@-%CU@HIiQo&$OR9sQA7+oD?-M z$r%nIW^nO*I3dEw$24S0_l+GY|Bd3`{^rKonwIV1ZIRFvcG04C)tpIP1ZQq`w$k5B zPM%UN-U*u~gUUt4MZ{m;3IGWfr#_*6k(K`9*H`E&72{1Fem)}JobbQi$bC@JfN=d% zj*-4#C(>RK;E+T<{o9z-4JAc$6{bDB3%BuYCrVsJ-YCWH7 zU|~l|Z^P0+HJv683A#pDrFQqR`sGrjTmo4IEYG-}__pY&Fb_$WbWI;{5$27x0VGYfi)QV87~UE5ATW=qkM%FE@;QWg9|23 z-WNq6XVX@(GHOJDsezrw-)2*QlAJb{q#mP{%Z9SFYps>K z&)&eS>^xF3#VA>e5-*;yA5xW@+`jX7_9}{mj+*oHCcYg8y!N;-Z)8OoT#ihmAifM- zev=YP!Y=wBL;SjY5{(jnM)VxqG6ex*W*L7}bP%<@dQcj}m6nVLYm&{QyDzYVljb9z zVWIor9aaqhFDX%*>e2lovvt*8AnDITj@0)zRgb{uo?f;5KUUm6xe4-Td)b&+LWf+8 z-zXJlubm*n51F!S+_$5C#2-F{X5Y$st;ksW2#Y%Yy0eG?So!P)s6xUaLY>O^KPF+4 z0Le?=LydTC;v;;Y(`$n(o}X(pe#085F_<1bbU(kdw**rX?;-9&fB*LnCTW%8ec8~F zCkujnIZEhoU%sVx*w1m5U|X;p;&yigSjKm9OEmXVCnmR(Bzb@y+DU?Gj9&T@`uUKaKAv2E zyd=5W7E(`I@M2s0ORnA5*wyc`pKBG#0H;1w$NnauJ-){amc&UxehZ&1MXiw79*t z#++jGJyz$)xcqUrnJ`)@h5}p9?`Teeegdab0*+9eQ^|6It7IO=AEl&MzMm=-W)Rs8 zg6eDn1Bjh)LN%h>QFFqdi5f8g64*vsYTx=RagOp;*Yf~rS}u$XSz&!Bx(zwx z$2sDygkH;Yl~Hn_v;R$2>R?5(9EZ&HP|UQ>UW+7r)c!8^5Y;=5Jf0*BNx9|pOqQTA zP1HcOBFw1AJ1fQAn*}9K*rBcA1l`g#p|Y4#k0=kU(b;|CZ{84AV{9_{~+-k;o52nb}05@Y<5qZAjfT=_*q!}z4jTGQ5!W66%kepR|^ z+vXcd%pn&`Z$9e~<@U~9uJ;-&nK2PeHEait9n_#p4-XspeN=l`8#WNH?h&e+rOudG z2N9i~fh$S-vN1It8lI2NmYV>bGA4=*D;X@=A^21%fMnOhOoBX>jhFbbx` zd`PP%DoJ?W(N-qO?svJWQ6wHVJTn9<4b5qEon0h)@?HKD-#b5yxf) z4by|qdpyw)r-#eMJWDZ5pt?%BxJ8cOAe=!JH}GcE|v3i4n6#K zZ57irjT0@eRfgo}bg}1Sw;^hUXcgS`SQn3NuUw86Y4^proPhKy2ugUYJCrJXwT?rd z&Pux}BSJ8wuWf8>44nMz()O}F{JW(>BQaf+#GK2%3P;#NPd$>ehk8W318R$s%IFJP zc&Xb+RcK!6ZqZmnax^%Z`bYQaVwU3iQ~RwV2|?D0MVpSM;$hue-y58Ey-^zwfi@0H zRMZQ1o_eY_hq^xw)oz~2MbqrUN+6Kh3eg((>}GtSks^NU!pwz1J>~?_m&V8#2bD(`;0jEIq=Y zDvC684?QiQRkdyP{ej6$no>pCqS@e)9?y)}23CNvtPF6E zY3C`?h}z7bcr)I?RzW#a&32s|{V_!u9^-(yd&LgokqUKF-Li_b!^SQaqrzfDbpjjG zW>pn69p6qprlhPqIW-x7cw23qKDK}EqRm@1ppS9Y8`<_8nAc4>{%i@=u|wtQk;eCM zR!q|*FlVa9TFVM$k54D0MJf(JL9g)5DCpJEB={RTq)#t#02Qi17byyzeq0Z;RZDG2 zwIWrP-X4|=#TF#Wj$H#qESRy41fxoTPHu5(;;aR-86?GfBru~e8~%X=#_=xGIC+CS zXJ+5#h2O4r&uvl(Lo*01w2)(56Ybi%exFVsTz}=Jy5sZH8FFbgWpeQl5Po@|+20+z z9nWlc_&%ng;o)}3tN2GxbIfi2Id|D2EK~giNCEpm7%UsWTS2gJvbH>K4xcR&@ZL}# zu-z2lLCz(5)L&adKk%p@pVWsfcIl(t6flG|hRE1aN>GX_<0k&g3NYboL+M;BEVafn z#;KLovGjWNFG$-Y%!^cDl*l=n?w@UvNirS`1cmY_>_x}1VdIN#-< z!F*6;F-_vE|CXmTP;`y82X_mPM810uC!~>u0Uz$$u3}P7{3q%weRAUj(rwnMWL6{@ zsgfUtt(!HM@Izz&wO|jt=)1lmAH=YVaJSA@@?{eePtrsCh_JGtek2vv_p7P*m$Nqz zPnIrRT=3yLU^ia)-P6r&{oWVs&S|nhr~q>URT56~%RczZjAI+?u~EuY$vx#s*Epq~ zxZt`m%s>>JvKQ*5T^c%Fh{E!_UEyf`G*WTU?NJMM5txJ+Bu#fyRPF#0vh zv71rKSj4mZ*dk^Ylhx~PBFCN;2pM17)_H#0{%UxXbvIMX+6c= zfMua~`vJM@ivJzk~CV}WQWY%9mE%2FrNPrQ4HSig~$gnYe) zJ|;Xi4YPBMV5e-Fv{-mGzz^N$^X=H-s7r})pHK-B$XzN!SuvE@|-4C@BxB&+Lw2K#F1oD1iv78H!McP=x@A#J(5E z5(ZGHk`;rmZgy zX17s_`vPmmv6qU0pRrQ4P*^@yWEzY>!g@&=X#&D#fkg+N0LbjZIr6LrXJtWy5%3|! zkprnNUYX`gX>x)Lf5jDWWs!R{_flaKU0etm$z-*3X~>PXH(WV7w_T#5P;Lx1ZGS}- zGSDaQKCjIVbyf48Dr#u@E=Fd08RR1owM5J*YP5XGe$%qkhzBbCy)pB9gUsl-*k7wt zYmX|LtLxUVO&^E4K@6AcLdn{@Q` z7LPXkqEgOarwG6tqx@SJYe*CfPqZ$L9TW9gmDLrAet0-N{ZRE75`^=oyITr`yu60? zqqTaGNegv8=x_X^%I9xmmOD_yQX@HnU-_TkUm@Y5w>AxJ-H?P30u8V`2WrDrXh1@W z032i42(RAfVt%68XB8DY905}j4}=E9Qi6q_eaqBSgM)f;q0(Bs5$aSV``2{ejf~pE zsxrTh7v}q#W*uxbb`xT%2BQTH!a>mliq%MWtyS0rqRE^R(-caPlV&gj;)RPpzr9^F~w}R6G!7r&7#q`?l1~;1Ibs_)=v=UJOA40^p~VtLM0yi63jgY7!D96f#f=mmRfdBC&F2s8`DyRSv#W zj@{4i?APeO9Y~3%zhkisre)BiH?ojk0=@XijpjGm^C{mZK3;wwyXx?+Pnc|rkKDew z*LlCc@xR@Z;9?!FNQ}5U_E6SAnPr6y zTeP9h31_=Km9DETu-W1(-voyz1;vw*VvwEt)$i`e6KH$#^6=u_q}ODxd*3Z7AsX@B zuA_Jg7A|~)?27Kk)fIYkXNi3Z@y^E!ht8(nJ(GV)bd&?ubMr@$@Sf(_ zd}QG7+MnKmj|Iox@d!vsbni(wVU1y!$1|k-0iw!tXuux%H*92<^)>!p@G2ZuRH@0%l3rys3W3=%bC(JaM7~EUSG$ zgfiQFo<^yHB=TK7`5Nbon)hHWAGi-k&IWy~xReEsDNvQJV8$9LHV??UC7yNna*{uT z7H$gTST8U%fks%GUjtXhViz(uo7~bk;3N}Ec6IQS5z%kv1tO7|zY|b?`upU0X=LGt ztwjI>j~hUQwDpAj28fBqgIy)7;t>hJLO-|9QxeamjTxm`3uK8H$fQdX8sv*gXDoBx z00J1B*s=eF*<3>*1s%8orh72@3#@?wJDVgAX}*r^!8X?|A6Fj`Fn@lr`KFnC%rZ5$ zI(RdGs!3&IyS+%EY+t8AFOg4tLXCdzqaIC$#4Bw(mBVPZ$#b3$k>0~Yb08#cQ`WR9 z=)(1_Dy?B0kow3!*#_{CXUr0G1({Uf`57f5t1{AC?88&1&)g@JFGPG(dSyW18@pLU z+3rVqee=K%dp0~GXgR7+E~C%RDb^E2jq zNYQX{l)^gky$WzoAga9i^l#KR6rDqr4;sG3f9QXiIITF{7)}O%PTyZ_Y2oEX4JCp> zR2HnY8!}@1K$hU!%Zy-y^BS4z@pGsOt)vSWu~O9Dlf~0IV^;ijXjoRCUwQ1}L@Ef_ zM>Q2P+idP-X&>&(UXaYqnf#Ale*l)~RkX5$h z&V^3h+lMDz`9;U4d15J3$&bpSU zwgh|97%_Xsf|J*87fP4yyoItXv=MmqrVC#K^mP+3u#m%1375J*!AJv4PU|mbRZnm- zpG$N=IQjTdonMqev47j*8&wiXrpo<7F=uh`Rsuz9a}t z?`qC0_PN))&rV$Jvug+xO~5TV|FY!C$52Gx@^~u0P+%AqVBu%)VpxR%+!|%f-%ygqyHtnIW zq2bna{Ii)sKAlG0c{;)bnnF?^5jGp}qhe}GDK|S0Uvk0ypNalvC1jN%nWxT8-ycpv z{;+`LSkHgMhY%LZ>U;b<0_Ibmgeg*2uRGz{y`>%8>Di23STogU&F;(9W``HQwsP-w z2F1^-#6CuRnml&6FzSmB89Ida+6A9r8A(hd;IBx|gp%2;Z-(n*5;x48J=J?jGABJI zd9oC>3I064cN8-Cdq2GWKAaMtQ_Y$j<0%ns5}{1*z6{|i`|^&)^CD{jiB@4}C*L=B z?$81HU!S>b}2-WWd>ti@|*M55P;WT@Ks-3$LQdo3}o)i@RX`;>L!Gv&qygGoD z(j2h>^XP(;&~NC*SrYy#Gf&iP!Cwt7l;b@T{&Rgf6QWmYWZngCc{MGY-KS zg72}D#WGVEa5z2puT+;g?Yo@qdBCwp^TOMNxrIsq_6BBX$jUGuko5TA`tt&B?q3Ia z=XZ==il8Zi*xSE?XdlvYKt_m=o7EBfhkKh;!1?mb+ufV$dgGK~=b1N$-uO|(AL4Ec zBVFiRs7yO7w2dMiq$yE>@#LpWR%}x(=0sG)KY1CM1QhjVz5Pj{oHIwwBs{KMj6$3` z^&d^W+u^3jM45p>&#To%C&{t= zHOd7Kn=$QL``K}|X5KX%Z8c#*ovV~`%=?9T%Jq<$(QWjPs_}}7MRr5On)0Y}c$c6v zEMfy>4A@(LzUj~=m&r8#yB=^de@uSo8PiESz?&sgOQJq}yrAF!Vyr%dehechAEHvM zb++Ar`XhUXDr)%&f+s>ta{tvvxpgp9!exB2h?0E+)-g>I7nhbV3TizutYA2kquSLyxr@$uW;nR}hz!&{r%lK%Q# zSD-4*9!V)~5HAWsV>Dl-&QU(K(8&mmqlkfsA-6VyE~V!sC*2*{LDr{Io;;=O9B+6{ zgicL2#KYt=nJtZ-(==q|9B^+|WVIY7}u@ z6Vbfd9zt=VNjDfNOXpUBlE{a(k6j~`GjsG;T4-AMH$czLmKcX{{c9xmi>>C=9s)8^ zFn4WXA{9EMb&Qd=U@;Hi^@yu91dfWP408^7JPGtdr&9RBTIEsw@aD+@6fH&%7PI)j zu5RW{#O3P<`N!4b>NO=GNRb_Pl}i@vK6iEs{owG|;ZLm)F z=P7W?SKU%5prlCD-Y`MatNZI{+RMr7jb1fU7>sGN6`>>|l+!^nS10IjR(>)q6Q+AA z83`qB1)0iRii_#*JfQdt2P*qhNh* zXzCG8(9~I5yE^*A;3_poU>N{o7HAhB3)+%Q3&oLpgmbYyT2U^ALUElWUf3qwFm{3po`?Jo)EpaPF#y_5 zY3`xAdJ-f%iI1(T1_!To%6CS$aK*eH>fXwYrQ_mdrpSENL>eCX9MFlu_+P>)T zC|EFi(HeE_`U)H>W1YuN<^(2{?YPu2M882iXoH{Mj-I2_mHl6kNm^siyVBq5Igd@S&0Z3k2!D@-i$h>k#HN9Rw)^~$NhT;=!a*z zdQ z-@cG})x)k0AYQ*e)T~L+r!}bZ07=~Ulrotleo?@%%_qs;$h@dbY>h<3e$(Yal42=` z#})4E6#FbRl_q9{z{-@yc>{iMEF5d z6KIS~4sEHiC^VZnq;9ocwTODc+Xl;{DU1mm-cYmGgOV)4TpnHva}zFYCokj;>_*8d z86kXGSYm1WmcM@!5)y)oAPgbMJwu0u;LAhKh@Xf3%LcQ3o#OY_vad06TeARhj9x2; zryP;|q$7U=S)JAo5rJo>pNcV7n3c{_sH1uoIXOxtOMgwaK1k(pcj!w8foTlHlHobR zI)bpf46VdBU&pVE2T2NNdDxAH*=3q~{_)>f2hg{Y2l6LACX8}={y-zf{q4% zc7{ggBUH-Jn{Hm!iRiP@<BM+eB*$6&!Nq+eTRi_ZuhJ?WWUr)de5Akzg_ zl9@?I)nu-CDRINYO~Z!|1cNG~BHWXxA{>q}vdd=lPKf`4Gm9{!%t1z;Diuo_wEesZ zea6bTg3hhRZJPUAp6B?E!1lR9+NRx@`G&5Z6bW)kN=oXG{#A%zNZmVQX=XryM|kBm zyLonsk%uxee_1S*`rq%GcNqj@TtH^mB3|WyCef8coFHyH8=7z84qi& zKiZS38do4iQZE)*pz=EgqQ{?9Iqsoh%QH4V^ld-E{#Qn5qJ3bX#qIQ!ZDTlMgyF9Y zom2m7`j0aE)#T)4a6`kqg|Dw~Y$igPl{U@yD;pZXqtwklHl<0$bpMm6R1MsUC_a3e z=u5Y%f!B{I@zdSkKbU zA|;F@c=|6foH}Z0CBnM=+DO4@M+7uTns7X$T^ zx7*YaCP4=b4iLG(HhFPn76Uij^z|31_485q5@nrF9O`M;F>vg0hcJsZoo*DHT459R zF|@wz(s&WS%Qz}JCO#Q{#d)Ob0DRjONys>sG@#?U2{DW9`}ssGDCYe%VOppT;+cnO zgI_-`4myYCC#c2KX{5Qc;ookEEGES=uXDpXb(ZfL8afmPBw1m2VK%Ja%J$aNr=(V*R0#B8Ee=qNTOavbdv7FrvkZ zffJrwn|J7VtgbF^FsFOj5lr>fTW@|{nLqb_d}+vbd#TJ!%uK{4N=)>eiMrBgYNdFg zYy57M{x-iW8dcWxj_7|w(YVmj(UG;PtC>6sF%l--q~Z}DM_(#Aks>vwn>M7{Uu#6* z?_1D!nf^@U5Q|1t&yejyKgqHw9w3g?>RYddB6!n`gk98l@5$?OqY7f{Xve*VP)YSt z1w>42B6B{~x|$TWd1e3L=k)%a+R#378yg#2&(em=ufeFW5M-T&F=n`0QvKPs#oYrF z6SJkc`J~;;2jt@J$2m-#x>YY^GvAy8oi$vj1=`*1pkLfPAf=;x1rYc7Jz zMo|>*B^$9Uo9dcx>jJB>zZS=pN;XCG>K<7Er`CEO7RKnqvq-WulTVA1lN+Kd7NqTS z!uiA9{)ee=V6H3d+Kz2ojTlMNHkE-;8p*8&LzR@ZwSiohh-M zJ>p#4we@9Sf+|o5qiB!Gz<*hWEuqwuiWWwY9)E>7#8GuuBr7`L)#po}<=ZEmW zXYYdRt1CQnZ)bOJXJ^P;9Xnln7>ONtk>l8B`{WIDde%DTsk(8d{B900DdQhX; zl7iucZ50`|l)jaH3onV^iz1<6MREC;CT{x1`nvbig|2Qwbyp`?1LQ zVu$P45C6bQ*mWiAU24Y4&9o-IPQwrJGwpMF|*x-yMR*Q=exitJ>Pw=A>L|o9-LmCjLvpZ2~pymrLXTiI(nWvoh80B9i8?nCwaQFt{U@SkV*$RzaEqM89t>V z{Y}tgcW0-pdy_q;acBLXK2&s(zezpMkk{0+uS@}WyRSkY)qpK1h8CC42BaG$R7d5K#Eyxto7wV@hZINcywRP-W;0t1v;*w zafZ-f#)rTI5)Kl9AMjb0rKn*d@w#-)3&lASPckVLrckU{)Kh*!YH&K~lXH0-5TD49 zU#ZG#Vc&aVagUkzYHXZ^w^T_DNzfO`Rxr@j6zU#@KRg40O-)U`y>+cZ{XJRWUvz!T z>n54_!h|9H>RlnuG#3;|gxks^?aG4PM^2^X!kxnb?+bkJ>?vG|PL{06>py`rCfSD4 zS@S>9rA%xf2~`vfLx$e{8B)9#Vi$W)^V6-U>?KSE2O61+??nqthe*4i249oC1eDtH z%XD>Z|5WEFRnB#SEeU@2_QuE8RoEvgD=R6@RaXy*1SN_nWQ6)cx~@MD3(8iTM)iq* zO@^JA>r@ayCyel=@;A}YiDl-_ZVM+%KNWBE#(+cS45G~M3;}Xqyr;l+aLH=96qP@}eaHZOF!Gxs+s|NFbq z7R&kbu79tfKP@e>RwF5)6D<*1$k*b_uLQmzDCo|ZqPCco)BM@n<;& zxp_-es9T#q6yzlp@YS&I)z_Q3R}ze*d3DT8s=68W_V%Mu>C9`LlE-K!7oL*}Ze&6o zVf?JBS{?Cju6zWwm;Vr!zV!QS>8f#07*9PVlAqz9G2Cq%3a*VUw1i2b|GbqKt-eD& z<5^7AihZEF(t(h`&qzTd69Xb}n7SZ;m$dL;6Q`z)D-S8dx-BAiW8=E#<)X|8DG|_V zOiH86ZjRrxl#~%?#6_tvN`yM5L>+(Ua~(=E*M(xO!~1U`sk8dOg(UX#WtE?wUr#Sd zcb=8?ysK@+<&Ckt^?G-uz=u|v)NLL1TBcD>H?+JQC-bNFuIAe6g~cb5hjk;J@lOpg zdVa=owKe)Lo1E}3v75d~9q5o2E{N?1SIG^|X;i*Pp#sAPu>D$7?EncUmYQ8n8~of{ zV%>~oKT3Y5KS7$;-$u7?$HoQ+MRgN$EB>=A7Zl8&KPjqQF(6bO7J?!WZ|r#f((Vsc zn=m)%7bsauJA$>k zmikfp172_^3^M57ZJBX04vRqkw7b<7yCqWoYXsuLVD`&K+YyMm9kt(`&L7J@a`(WK z>i2wTL-nYA5{Ep+ZKU-%jyx){-Sc;dHugJIwYZT^Vfx>90YbTOPz8s!(UiiFq1Z}c zh`ck9J+AIYI%?olDz@RV5y@IqoDo9XWQHHO1aR?2$gkev14{lebFN)>I&ZTSYFn^7jVHsw=(?`5ov{P8wJl$vGTX@WBs~m z!Nj$t8oWJ_MHu9j28r34HeJ%ZtG#$XC`~X~!3!wy!9BH|=PZccP2c-*5gqZC9Zs5w z`NEo`2}#aUD!Qlxiz4Hm3qq_BAd8)Mo%*4?PnQSOSc943pgG5}HVk;=F#VE7_6~X& zf5pN{ojj1;<~(onMZUBW6T=QI0-z(SHs0o@mSVvcm1!HnXD0phQ(g6m2?=J#3h1{6GA7N<}}fW8jH;#s>TCsMf#}u zK`nLpofxHVt*z0=lne#j&H5!cEm00&W2MtyrPU@&1pb^dr)X$*I>|@$3p>*W?Q_dy z(=_^{Eo-p$6f&UJy}SZL?U~$PCF0*gafnmWmR90zH#SG^E= zlz|JhIaNhM51*!c94Hvg9Q^6>@?l$P;wmWYrKqjQ&f=qlkg-gWJd@1=5}ix@$w|(ER&A3H{g_DTLk_1FSao1#{H5ZI$`4gWJ8mz2oC!H$MNz zbKEaJu=Y^zMv#DDXX<@Y*A)5+ASR28x>*2`dkX>j3sXU~3Qjgi!=tNvfloB@yR9N^ z>_1#?;|^U3RZU!_NtG$jDfuG2UHAQ&ua-E}#)Jn>#BCjH8xoZvgB@^m-9eLHljL}M zMxjF(xPn=WUI2oXmui?3hZO|OGdL}Y5|kQi#Gb#CGBEJHWq@@Jj1b+?il5?}BLoFP zyk4(&JH1hh> zF3Ibd52rm)4}`apwkYRy}A z$%gwB(Ud}9;k!2K!_pe%#a)ZpXOB4i>_=ckdJ~bB7j=pC^P_!c8eV|*i=7Ii5j>ewrCB*0Dx#ah-pW_XGyBGiLm6tc00}utuap2tt{-LZ7=FWF zc5gM2Q}&@Hzc|Z4R#Y{NVhapEU^czH4<9VXwn=&QG~3pF-uC}fj*N_4*;sB_j;_M9 z@;=Q?`k<0>P%_)a;e{RivConn;>K{Et&m8{p0BU(+&XyFvb+o) zBDBzsSpC>E@fBryfK9%cqG-9+@r9pKc@;}@r$(Nj`2~xfh4i~*hytn+Va(_k!}QXm zO-!!2D%3(cjOOKV5Y@zD7x7TWVuac^ne2ytl;ST^lb}%YQahK#AJSu3Yp#*6x`;27#ms6@lGsj0 z`A*2OPQIW?Iz+00oN*NDUS#Z|tL2*P9DH+9wQkl8-opivf=;H6Kh)% zXROp~Z=MM^^6y+6E>=f*3Pb7vRwQ@kVFl@wV8I|6J5-O2+6dZ)o?wOEoY`W$WNACH z?H*Oj|4j}ru$|OndYD$32?A%AnC;W6b0LpG8SCZC(~0*nx7RRT=)TuqEVn z_rKdVd+1Nk{jbO71t$%O;0$VaiO8y|R@ZD`V^`4vshu1n_(B&9gr3bJ0p8W8rH~Me$c0VqRY= z7ls#w^GSXY!8@e)D3n3yzPxmvi(-LKT+gN8-^N*Jq9%7U`H2mbLY#%Cl;}SJWq4l| z&{`D<6H3~N_q=}olot*eO=CT$80|+31Z{QIgk^&Gy=J z(hre~L=1-$3(MB`!t+P$4?CG`+Z%Bfp^(^0W>h1ftU1+ZhH(^Y2yj@)Qj4N9esMpT zHY`0L;sYSO(qNW>sSs~&nGnAza4Uef!j8@Lq6O`i7M)xs25EHdP>?lTfTxlFPCos? z)r31YKfh30an_=87l}0rK_{Cd4Q(xcT^|@xpkk)0%ku@BZ3{n9ebub=XWjkB$F?zV z$t+b;zYgU9qS@cPfqb2!tz4HQ?NnZqlTOKDW!)IkI1(eW2|O6W+IF1_-|o6 z$c0VKOvVHBMeRUE_3!Bk)g-vxoBU%rlV&b%em>6M(%VHat~F!(uta6N8~lF6cK;J| z_~Il9K_!pNb0KQ%g2Kx^eaAHHL$LR&$(lIvW231_f7Q5?H-;f`8eW7vMeKAZvFJ|h zPu$#YO1MC>77QNKbeCfQ0;mjX@+6i}4LXXEcC2e-H9Jh+Z8?(R-synF;>HyBN!_gfk295j#@>52d%-5rMP zvV>R(^3lyqn`>*k7O(c3a~7QS#U*edr z9jOS^$84lfk92XYm>wU=9Pic?rKaAz5arxYuN3*q$nky2Y|AuvFbIPtEk^j ziD@Ad8gsB{mL0YPI2FiY{pZLbnKm4;6SY0+9t+=(K8fO`z*`S|?M(Z~7p2`c zf634f8`yD_5MI-Hh1pf!5m?69+8Ium3-SxY`Wz>JCjYS!_i_+5+ zc)_nw$qPufg=D+f?_RQ>>QlLi4bV(zonnk~iYGx9Um!NJipEfNyB_Y9&)3Zp6WwoQEXc69KFvcB1$mkGDoMlLxK{Z8mY7dkOp#Th&G=Ley4J=3?Y4d^OOEN$^GoCB2T6JcV`R7{&UW= zjDcr1nuu{k%97lB<>PFw@p(twXf*L8pJ6wI)*}q@RUzSBY##d5aIL}(J%CxQH zWvM)j1JW`FFi~FYb87C`J;%n-Nzu2qkhE<#Jl&66|je8CBTIXgsZ((nj? zqDgbMtkSFDTIml-_vu)rZ007;oL9zXoU(X@;hsIN@5V+pA4 zk8=gOhXvO{F$Kb8iHkY@{m74M$Vx}j5>6fFd$49C7q~CFVj6@dvU^7oT?Ji)^VHT} zh)k*>H`1Ezy~M)voP}F};OBc9faxvYPN9oTbY3WoV?{@{+;^CrxX5tcsnstquDCtp z=k^HTFnP1}mE*Cou{B+6s1=*UDH8!A=}VUS3Oc&V?YGOz%MyB{HaxJ|?3rCe-LnbT ziqt`mPR8k^)IC)Ca2fP&*-V+_&d~bL(QOZu=MldYe$IA{dlhcT$!YmGyiuv4%T{Dt zq)?twI7RV)&`}X)<{whDSABA(@!@jSlAE)CEVvtTSCmgQQ5Sox%^f>CbYjF~*l9#Y zV6V!&hw`=6CH;tWRvCngLSUFD?n%09S!?mY*NL5gx7nwsr`ySO&mDh5&uw11LCbs~ zp+|)@P0FvLF3lo?i5)Wh8OJjev%l9oOSG!3kn~ z@kXir2(?0Re#?M%W;5iCuWKz4zvRaYWd%c6ji(&qg( zq2AaA%#Gq_{_x460l(tA8N4~OIXrKJ!+Iv9I9BiAq*Ws!xO&JXCh!73%#6B-_^`*i zGTufkj8r!yRt2atMJY;Ei|3h<{8I6Ubpui6&(_Rt!6C08W#80uLxO> z3V9hi(X?5!!H|mxc2%)<<+HbQ)xNnqN;VD}#e%Jx`_c z&2|Dr{Mr=VQO#jX$;Z0KJ&E`yC*yRL_?g;@%U(PI*%SutTdHMD(`KS2HiOpI)z~1v zZTI-v3WTgrJQ*~aWIqny7s&Jykcx&;Q6o2u1mXT2N=ai^D?)_>FgV>>G!U&xL%5NI zeA|k#S}6)WvdUXu`NSRMw%UR;r|P~LROKH^0dGd8!ynz_FLf=}H8P%=R3AXZGem=h zc%)EpBw6qsAzyR!RQ%MVy)EGRvfY=TpRUp}@U4Ak)!y=+Nrcy_-q3c?d<#O0UK`E^5GE2l2vsL@8eGn>kLyg{_(D?Lc_x=( z-m;F8`vGFp6Gg*Pxf;YTgVH(Vn)9bs=%^MQ)peX_up!n zBt_!l(igAsmjq>}#Y-=Y{0quhuOa=h1ImaG-86HR-Ob>N^tI_pua}qy^A@f6a;u8+ zHth8${fJF)vdXX|mh%>~Ml9RZU`i~BR&4VGJBpdNs+kIN9-Hx2>IVIsoXAwQSm4uIipbjJlFBl!r3eZM<#66BeCOyA=#Zxz~8Cg{YJ#JZ|LZ={>_r63Hz5deT1DF2Hyh2I=M9XSf~ z^9q9ljeE7lcIdxV2zg`mh?m|=m78XWvN6lgnEPDURA(D#?*gtvP)YT9;cV>;aCA=M z!PFvU*1q!VRARib)VC0-U(%wJdZ_dhMZ)iHl#tjxAl1m)O)kW-8v_+p+?+-P}`JGa(u$Gj|kE9vi= znVvkkJ=@3T)_n{V>+3h#Kx08C()RiWo(M{R59X!aH#15xse+@TgOUU5B;PTVQh-^i zk-<=bQcNhyF-OuAy!a7t%fjPIHI0x^wCApw(W@jseBQ>eU!*1OEW?++q7eCnPsgnQ z8~#*8JEf`|sNQy;u%bPqvCOf4UUgp|D^|LkeEYHJQtB6{(}Q-qE;fxcXqC>}%gb0u zPDTQ@V**`VPLAG=me~+pLq}N^k@%n+a^QK&~8TwTj0b%iS)3Su(m@u(of3~RgKXE4`YD)j#xYHkunc_1`kkP%diV9><~ zSXhT31OMg_3Og}sOK7@efhEn#FT&br zP9@tL@-YH%0xR2&h9)le?}owPKP)C2vbA_BtYTmbZHi$LC@8f$B62HqBLj}8O6Y15 zyL&3nfpmy;W&-Yj?R!Dh6SQOnx`- zo*&zZFw$8uL%~1NwP<57Y0Ka;`*^al8)S5(L%?dUhR^4B9~Ym16_W(Q;)g{n{9!hp zC6jZp;&@T8OP6lVGzV+U5TIqPzr>c7j7%X@A4~Rh zG*;IOe-uURbcL>;IN}XQ^EE!8CStrY3tL)|l`%T`mtTcbzl-2G07`VMco< z{|a}g%?+TFhe(C5=(3wk__f=~PWed@wtQj+J8XsFA z0Xqp9^zYh;9kkqp1x%od9d=1rIxe6!lv6$__6%m81e;XsJC5Pg(3XXbh7D1Zu zV4XvUstC}lE6~Z?`O$OdgUx;;OSi#&PoW-|SZwcqf@wyHO!NCMpZhgL%b@3LM?(EVmZ^BZTSsJBa^5rUK{jAtD+%)y)YrHkv?<;D$DQ=GhwXck4u(TSr zs$pxgO!>ZUATxw2$TlviP8mXJ;21m+$ass(N~}SM4;wZ=8J^=ZXDy36A&h@Z1B_{p zd;$d0(O#5rd?8h&@Sb*$F#B41;OCI2o^F*pV|@FV)GYc!z^Biu?(^X}(AC4;JHVZA zfra^=aZH5`mwLfr4?VO6?s6HBimw~&CAs2jcdDg{3$SSPRB~|zaD{#mWP)ZN>$-Yg z{Gz&mE77d$_hB5&!PI)c2RT?n->Fs{PK=cRD?m`uqibrxW2H+i-A*-i)lus#9Grk+ zKI=lR9)eS(GGV$!E1_K+TQFVYki_%Fo^@pdJm%|vo?Wi=&E10e^5P*>XlSUM+onD? z*jYgjWS(PTnP*|)uf+~~5`+HEgp+kMHZb~*F(eqjgrGgeNiG^B0AFPQY#bZl6E%g6 zP$Q6avAtvBt0@9lG3!a$#`5y7S4V4zn0=kuA7rAemJ9{rUE)N%IJgMb@aF}Cdl5y> zicdA3Ds_4pV4#vP_xE{qO-?;3(c4aZ?E9wWd?C3&wn9bV^Y7Y2UO7^2s&lP%H_Zj z=%e@#*r8ONy)|RZgF_yH=zvXtDm1h%SxNR* zcpCe0f4^ku;?N4P3}B@YZUPbhTS|dAZS9a-NM5V3%MVHuS+oHV#FO;#7fF#<7Tyra zPyqT*ggZ4thVv)rQ>dG#aHeugCsIRR3)wnkhEIS);*d?ZAl;m0?t!dU>WM2UnfM)H zek%mH)}P&!ZgnIw9dEUN!6^&n3#0O$QUWO;<5~i94;QWbFQTgZSDp*96%KIc_XSnzw8nAApHDtJ2b`XSIJCefrW-sgj0+b+YfMj|Pc$-|iNi zB5i`#fFXXyz==2pq;%s;WTc4(V%UUh5nfZ{rXcPJlVNX^J~L=gNoQBVpk(zUTQiIw zUd-3KZVw~u5<*DGoKc(N^lI?X2eS-S^0?3Y?&4_qq~+|r`#P{AZvBm6~az&UiJCQ^_2^^y#Ck3p`FOGfW_*jffX#p()K zGj$IE#&@T<-p6ur1(Mk(2gy}jl;ULBU*(EwGyed98y(b}-MdtvcNV19K*Qzu`^X`|#;6BYLhor8$5y#Ax zSl8Vbz#vvQGLhhK7M6$A!*+a47)%3Idf$+751AJd2^?OGsiH=CG*t%q|9{v*=Kp1W zdiw=vwa2sLRVWU2S4-~vi4)~foruwawCKG+*VlBdHG-=}*`D@S5)U3*GGNgP#qNht zE}DcEkWsfnM?H)C{^)EudQ%p>?o8Mtaib{*OZP>CFMEw}-swi_7i}YZ_BSkVB78Uq z=CB`P7)MNgF2-<5RaO7r1x1-|>7=S&e?*um2w|E5BcD6UHj_*sq zH_Xp9oCoF82xDLP_omBc=!_r)@^)xxYvvrLW*|1o9+YlS=`*|Sq-P9Vjit#f!+d}3 z1OeaLdY$fm1pWu&^;P4wCucExMH{WPYQc_Rd^hsxO#QZO&K^Qim?+sb&w<>+TrE&# zRl=bdY42y@E?8G%t@&Ls78ajPUMl>Q3;{o6W;;-5G-P!jVGL}40HBaS3-p0P1Y)d1PuohiH8U4{OCp-o#^X~RQ#B5aNVJ%s42f1 zfBDL_NEelVf=qRE_%+I%I%?%_;^%%t;=IxZhFyj?`9wpC4dxNhZYxxtKY;g9$GS5VodUz&}aVP#iJpAt+cO`yO( z`Xpnh&e2^ix2P$O+-X4U&<2yb6N|+F#JUtQf7EonQ-os>5XK(q4?=G((5jormifH8 z`b2U0Fa2II)iKB{NIwu1l5B~b`;*{gw&x6R;D#X7^7m*k)zQ#z8MyaG9>CL`^NW!_ z^0olnaA)V5Xo=O;0EtpZ+jCEY{{nQ)Qe&sTJ0`NwE-M++B^f^^N08TjqXK$+fQ<9N zgTq7`MM?!C)~l1Z=)Ja-uc3X$nDRyr+1n27OHO~eFvIA;D9sF?VKi<+OwLGi{}-U7 zVNf%)F2{`mR;?RA8HcnIbY`y8Wk20a@LVmKY{~7Z6o)qvg!S5gDF*Ur1ZaTVHCItX z9N;COqZfn%I&F;eHTaO=i&Lv%scd*6QB;6Q7_DC_IliiOxLd~!NCl8-Ay?zE0e)T9 z#sksa^}p~%GqI1qu=Hl6SPkK;GDpOdY{?zhoyraD<@V)M$wKoCWx29O3Ai=z3zIWw zGr<~0tef6;lL ziX2RVIv=yyL-D{0YZ9x)lTJDA@|uR?63;C&ny}Q6HiWwBiml! zRn&vn52?GBvhJy+1X&tdis(}eh`Z~dH!_&x%r(Y>bJbCkA}z6o&eY>tbq}}qGio1* zfs;@V`-)T1==9wZ@;W%&CU}nOUsu-1ZS_1ZNnQ^Yj@W4++J!C=K)Ohhh6RlJMyK)4nq#(rqE-}&&%el_ef(5M&! zwQeyggc3IFlDr-=3oW8mgsSX{9ABn_n4qecz}X~>m+nb$2-!G;q-4lMXkR`!{Sg=O zj|>Kwi22$c$Xj=eVQNmKlls#L1oM&~Ss80Mk}X+FkjT>lvf~atMYivRFPDf}yl5X9 z_35RO^7{O)IGk$OTr1Z|n*VWPYqSYan?=Q=6q#{Dp)_FSPl&Z$l``z8S&&DeO*BudtawFy+ zZVicQJ#n%_XefzYoDqOXGmJgtE0`f4m6N_#mIj-lD`H#wGbkHsjCf|vT-SklMb8P& z;1}~Exlzsl{6OoQ1nqb-WH#IIp}!^wSBzumYinwD#>l=J+A2JQyqz|crdf8A{^r~! zuNa@nIigaS^7GT@=~25>H+jJO?djn!(?8(og4(4l#*41qO#-MMhC4qlMs)Cw`044q z3+%)VdVTdKPLqHYL4KugWEmx}NvTzoICVi_I?mhN+9HXU%7e<9wct=aSI1RH9-Z%g znE~RJ&2wC-F{j|MOO$Y;XGKU(?@qsIKrsY}vJof3rGzj9Pi6GYfPjvRc`M#~@)PoYpu ziz0|$N*YZjN4sYeAlqlxjD^Vv2{bvy05g+#770inkb?f5tn7-uGuss=R^FA|NuVK$ z7IPaDnhJ`AL4Rgu!?Vh1W89!7hCVNTw#Nw*k~gg1V@`9cz$PGoSb0`Ob) z1ZOCHyQ(cV5RBPLdj$*T7(-P;O&Ps#*at-gEXMWLtq7a#L>`Uz3JnZ0=c!O)*AodV zET@RLbr0`JK~S+QY=Rk-;Pt8vWU$3xOUEGZzckietT^&swBtQU5O>r|!pA{~8d-?* zb=``k(QJ~7Y_4qy2=J_JY;^S%^!a@JwQ&JS!jLKGUk~q6jQk@IH4$N;kweZnrH2hQ z(=sT)#M>2ZmV%XD>RK8kFR{7(T<32&=1HOMmp)Y0g-wD%RQMh# z_`9sHt}MN-jIMX04FB?ctv!9x!&6}?*T8JaGwUprT87(^Bz)@2O2EH)Bk#Afvv9HSkC71w6GcWnBXT57%-o5hqFwfoY@cXwfkEBH1+j_Y0lyJXJTLUwWsTO+_8|JZB5&W$-K+5G5n zmv6a?x#Jth?e^zp|Le!PiScwgZ$qjB{7KL3RRtZ5>#N2aI3C#b>)DBg*;9{0aoQJ? zz2yuQT`9}9I>?&+(#sK}f_&Fk8lzBk*SAI+herWX6&~ncddsV=xOH=vNS3mQR|V~= zj*?Uo-v%ivimR*F%Xqw;K6eMV?f4$+W&J0tc?ERabo>N_{9n%>|FmD{U~sJPH-4{w zPd$AT&2rycNHZR6;cIBlu#;6rj**1_i&(cmx`$mg9cB$7mSg6HuUk;oMg=bzjW4zp z1)|8%4?>$WNy_z^4c*at|v$5P%dze(zH za&o+$^xVNuU1yyy5cGYu*(3U%ZKiugtetLNRkNV69Zn^0*>bkM-TUzoDll)@@BO?# z8oT`3HGlOetu0Yg#AZ=m#96g9_ZEtTi&taUZh6~a6#;MZ+8^>X=nY%p7N@FQr8x0dzF z@-%s7>4+lJJVg&uUIY-^u%PRL0;I-E0%9vwa#-)8V}u0&H|4An1_Uoos38 zbbRJ%qZ+j*`l0uiK0xz$lEHL64_+lwWu*hpgU-qw)e0m02eLnCc0^IU^TyK6+16~o z_jCI5&QsI0AZ!?3DmE;s#F%HF?(5Q|QbC!5u}R9&dz}5#QCMpz?lzD1hvaJ2cQ=k~ zHgsCW*}tQ-t#@F%9)^6;>alJ-`UPC0TkjQ3)s~;<3X!e<=*pwh!$YT~=N{wrwlRzYD+vSK}0<8fUJu+WDlDepIp}x(5D814_ee zCte(>D>1n+NK3ki*2I>0IT|jKs zXct@92&lKQloW>+x^Sr99o{nHtS%z>Oe8IUh`XzRU z8DVas+hbryHMg0d_XYdUS>QBg#(bqXg)Wsk`=#qAer)(FZhCJ8 zB7x4_bgfvhm-3NDL(n_YNuJLj@PelaSL04FgWLfb?j8l(iNwyW7@dIw5$3qgG49+R zpl}to1p3xMG=uJ}Taa^V*+(VjyspK)_^|W@} zovMJ~$dSG6$nn(hM!9ht6)EWMs~IXQ9=_6e3xP}~Ya1d}ZKQiAUiB8eQRuJiEyVH~1IS*B zDX2zfdIxFrsvP&;z^+YE+7zz&V z1AG^0?4_hW{xkae{_JXCOBn&F@%?q`{ZDxVH{q%?yurUM z5zDSl5*f#`DVA-dmo8!JzM0{>xm~r@lA6rtT{byOK6-Y)hJ3=R@NE1d^^w#4%-xVz z%`7f+4^2%kiIm6V8QsBircnrgMRpNMI?;NVzl5ms&SF*d8wXs)lZ1tBHuRb*dUAsU zG+$~il|{`HrSY2<#i+=>^gG$0MMMSjLu-?gA5aA|v$;i`0Wi;$ZCevv?Vr|l<&Zi!eCYVv;Srhzvkh)Gg zTyg&M7|VnW>h`G7*0UKwBmaexJbFMn9qVHU__pM=xt_>fdNR6eH*saPwP z!lxVufOHwG=z_Fep6bWP;Kbpo_st=mI7Smq$`g8@OA!hixX^WSzNwl~l#K;_8)VGv zR%}o%JVOGD3F`Up2EccH!kP|U0fvd5LEE|Q~MHF5T6tHMu;;~@<0 zQ&%YT`+WHh-|u~U4od8QcTvk=sLWK(<@*&Ijtuk!Q7d{_F86jnqoF;uFbVrTo}aZ0 zH`fv;K7Z@umQ~qy-AD3`y}U5fecBs_f3jdp#QaG-@hvpRz=Z~dj@oyB=@fk63^Eon zDHAjfO$cC1CUCiN2)BC}qT*~rsY_KF-zDTq!Zz>#(QXahg|*1+#g~J?F1&|J>J)#m zRhJYFGF^)y`Yr@%F!xQSQ4EXKUx24QbSYF>miX6*N-l|3nX*??;iTGY4;w^%vi3> zbN5z=ow&?mEmm7YQp_F0uz}gIq*fkB`ds#*{1BsjH@iqLY44v52P+dJzMl>M?sr^y zf(F-*xt7n|v|8V03g&p1Urh}5HKK-fR>~9CJWGt6bDn2b+wa|UMh6eHU5~u zW;mqymElxvaZ$0%b6ykrW%@46d6@GFA)lvkS)Y$pP(YIK!u$i>)Ei4(o2hAn&iqt0 zHK`$x<9hybP}3_;6)IJZwoYW1rPDGI89(Ln3Y%+c-M3)tne}3*%gHZM@GeKI-CAdG z8m|GqiI&6qD|%uE=gEf$Vw#Jo}S6;n4I*lPI! zX_~stAFNQusbeauEt7}c(mR5FFE_v6p25cVV7tF%zmzutR^GBQGl0EQDwnrY;C1dt zD0oV@y!^U+64~DuaQ)+asSI(p(QrD7S1B{PnmL9jjXq|7E}vgg)k^-f-El{%`ODns zrzFfpA{m@{Gh!BXFbfVERZ1ChIPs9w7jndCG2?bLz!BAjfgRB%MG~0`2^^DE4TBm} z?`l077x8004k39P0qD2U>(W&gyr81d30$17ot}aL^?0H~cp6)Ji(eZ|a%D_kc)OcA zEdcW87k>vUTNVaF9a~HMG*qaf=T|bhq{J&~JYH*^23-vvKU0-+8^XsezR+TWM z2FO;0jDz!B?6scc-wi>h5(p7OvgeH5P-Cu)gaBSh1l|s&BPvCsuuceu83NXA4+TgI z1!`Em$Q%0OWDeD0ZiisoCwwJF2e!9_-U!`#WyiQMBRc&g=QPaC>)(vl%!WjDJOh3@UU1%VkI#Mz%9DEdPL}{bYAtGzmnaG1lC2wN`Q&;@TSgU_ zF2VemRu4OM*nEV26jCt8-AvO=NMEuVArpwth*)yJ1!SvIv*H7LSfvWQ{VtV8Cl`8u zxjj%8{xf*0Qx`$zjyCHge3DW zsYB(HZp!C~G{~vb0}WObMWOW-bAujraZ6nbRX6^uAZF9*#o7^*xIw6DD2!qeVG5~Y zfr@qwxVD7G!xR^gcG6Gjx(z{j5yPnbRZk-U&}8`%FS=CekutOkZaK8H9_go`m}O1! z$Dl_&Bullt3j3%RQ*q7m_@%9v>8&k7V(d_g}q4cRKnceBXJea2@Daa6oZ`~}>o zYeD~S>X`(bIL5x%Di{VBr${ci7HOJHCs}vYf{z{Dn(`2$Yf;sWoom5-gu3C_C|nCb zL8Rp1Rkr2u&#uKt{8M)={^ei&y%d3_Ur(pgjD2Qn9j2yE=ubf!L7(fqVfC7r1$Du= z+$uz}*9gU_W<%GSK*B0#>*bzoZIU=rMyml+pVg4DEGBC1MO6!tfj}DPpgI{g8Hdw zd*S&{Pcx}R6Pp(+`q6X-UNx{t=;k1Tdw@ebU?GGc*CMgKxwLYQr;J+QTI6Z^=(i6a zJ$iIgfi$|xU26~bb1=9(r?{LaqK{)7Ab5B5`^yn6lS#fx8$Pv5^KPJ7Wq%&FCj z^&-Z9gHQob7-b^D6q3tBS-%NfTSDUzm78>teo9ww4lz3f{X`pBiIv8P`68j2hHGo6 zUK8|Hgl?++?Ljeg5tA4LC92PRAL@~4h-ECwQ|NvYIZ_)Je|F#LU2g)BLTN=o>B_IL z<^|O)3Wf9Q8+9#waJUQ1DaN(1=GUib!tRSnk}cO-;Bq8MF=3XJ7*u8rx)wHS!R$Ni z5OXcmaPxr40pW74g+$7q%i>(-OSJp(UqocBht#HOZ-)#Q45tkPW!j< z3QdzZJLB}UZhvPFk#lJf*_!f(^{wvrzS;&v%GZu=%yKPMyQIs^K4ufAe3Gd$XqbX& zMYhMFG@7WwsR%xNg^AY(L#4JMooxL`&v+>JMXEwA%~uS@4(5KErn7?W+1m}RFm)Na zS(MC=l8?b&wpCRJmu3?gyNWz|3ld#7bROwZ?KI4hvWH4)n~X_NHbP4S(7ty=5Y0VE zT*`e7A9+tkthyFy;(zq8} zYz|^pMTI|x-c6CDQ27$WwIil-gAn@)qhv&w!p*V2ikRZ|K)yuOLi)LB*P@4R?udXW zsMU+!%lgS5gR(fPQzfKG#1v5*l<#`RI4EZ<4<4A&yH z2~o6~24z-P_%c7to#0T5(q=?8O<*~u;Zv>!v5Y_~uFGQZ^G{8P8pL1>*NC>*bP;pm zA}mKQVvzX3o7)ImYw>%{Z&43)UDJ0i-#}{jQ*?_-X^^&vXW4mSwN)0MkmC(Qly3rx z8Mdt#N&=K{v}+dCor#k4ysJB3`pb4^Xltw@p`!r%?($}{R_kV2dxkn&j1L;2pN8mH zo2QVup39LIJ>?FwInUV?j8)W`lr_Eu?i1QdZ=CloFgpHOXh535`cA5~>CI zxuNn95#>OMv~t_SAOU(ahPsH#oZm}yvsh`-(pUwLKlP4o_Mn(Q14Yus>L+w9bs#!* zLmz5zMg)jFMXONc3H;aqM03n{5v-O-=|Y@AKO;%HxN+BlIRcQ+DnvOE%#2E0%8n|A~qM5E)>Q5eZCPc+-`Xa`^If%i} z2VIN7H^nS}ZU{s5n`|2*XW-@_Q>rz$0N(q5{onpq9Iw#yYpt&sWULD{>RRI~J5uLE zR~6$G%2&P9{c0QVMb<8d7_F2PqM`EBsV|sD3uU!vn%a7B&da?V3}Jcg%xJs3^prJu zo@=>9Ytast_fJDiDU^Ytrb49Z4ntKn=d4A3ZIm{dPN!m=)qx%#qY2^k6iPHuV~Px? zqFZ4ig)vc5VfQ>lnxyDQ&#*A78ygPtgBD)8A#~~NA~GUh>r<|U3(YqN2ag{=cFsNh z<)_!LUsGc8qUI>U(z&oZo9^%LKiIqHljQZAw=Z72I-Q>dpH+=*m(NipER63a9ibeV zOxS03GQqux=iy3k!wNm@DxIY5vqWCs^TZ5q!+|BMW<5@*M&{Q`L&QV6iNt@ z{YYNC*fg#!q47|WPzxpF5);bQ(S{%)D5OMMq3uGCRw0$EPxKXkmY=JRD~m-xTrHtq z>KLbzP&g9t<(T3s^p0MLwCO^!6?u^n6-7bq9gTn3mcm6$z*@ zi0qqnEtrsOR;zE%weYOA;M_x(+U8@dfaKJ?Ea7-{+z$*AYeD(g!J4=+&!S=Fc5O?y z8y?Z_*gJF+-xAlN&6gEyuKbJvb#eu&BRve>RCVaV7QfsEc<=ws-~8{X!8xb(6`Fpn zt_5k{L00sLDSZab_t36Tx~aJz(k5GlO%%9poS4$|BVf`=vBsYJsw$mlYanX-vQuB* zsuw}!Nh;5dUmX_yNMu=76op)i%Z($6HqoQ3)GV5AW#FmpxGw0E5P}>GO$XBH?3|fs zH4e2^v4@zJm#oIwQxecJBs&+|MR*l1PO#8L$TI6&-03FQH##9o zu7wo1)@{q!V2j~|W!xOJYhxL<&fD8IwXnvQ28~)s@{CQ`2`Y8d)aF{)7Q?(_ywmT( zn`Bd45|F?+jDK?wgP+smx^$|$7=9V@Zw%*tY6mKKJq+Gdz3ZX6QI5U>-ur+5cmG!% z+sDVp^ZCGDF@uO2S*JK_!iPvYTw>?|efGB(^Zb3G#FK+7@9g%MG2XQZSMz>1fmjA~(G6pT zRaPqO-PHSI5I^54i2iOEA%Yb~t}l%k&uxU{6InoUn8~6$-H_U9k9yEMn?Nr)8R8g{ z2GOI`?FM%QHCWh!opl1bc~cPCqB$bojD=8IOQh;r;EfK%wZbbR5))}tbF8KCG)oR%WER&FN80d#e8PL};7n!ZNND`OBM>@$i>c_Csj&fq$|m>rCl^Y}N%V=&H~ z83kaFk&8FaZIvh=)p}Ks7A}e7k4jPD#i+Ie-uwUf`~R&e} zYN40MKuIW%WVlO*N#_zIp^0D;*GyPWT@*ND1lPjc369=Q9OpnK3D%jH#Ug@R za*P-8hlvt`v(u8f#YVL46Rx#G6lO_i%Uc`8MMT=Zh{4atmNr_(Si!RwR~8Qhy_X(;fYfQW}%)hPJFdea70+B`sm80s$4E+9p zNs{K-gtPTRJ)KT}vwweof4^z!7q4Eu{PoxQ*`o0Y6QWT2YzmNskS6GTNx)=-m%F>W zJDpBL2$~0_S!W~hnGEe=n@26WYF8z&n}fPmsM^P$uR;8FtI!rOt8NM-M6klkvD`(B z=Qcu;i7cpiM49Nm!fq+*B0gO^L|Y7{7$b%8zNqaX-qb}5Zwg&%BMa&w($5HyiWS>f zBhi5##W3P3Sr7^9UZ`;qd7>mXJ!+as(Z+})4W9?^uLDqNHQK;0NcA31!gHOm-U4fc z!?5VcOR~hN)|}Yk^_Rao@-q!;hNy%EP?ofqS`Ka@BiK3{-4v+Qw=zbCs8)5PE3>8 z+BB`rv{jJwFAWJqktla5BGy{~^9GfbvSeMX%wlz=*EMTSl(cMO13e%tL-xqf?f^xi zvZV!Nre4uuR=|MB5J@9}_DR{CO0#j~R4AVHVsQE+U}6_S1I9_>G4CW0`C8KBT9TpZ zWReEPx2-W_HrHZNE*4c?vspBr39Kav-bHX>QBpGnGRUwIHjRZbP&P%^B280m!Yjrh z(zFQ?HqD*goyU(K-@kwV@cGlj!$THGq?4**t^b|f-EV%gfA8MC%sbUM{Ov-A1<`1p9SXdTNj#8VE(zPOF9g`g}z)Yc>` z>;d^N$1%DWBcac?4dS#LMu=dAm*BUD7|(5ln-J2Ql*VBrs{tWKYRXpc&R# zR&N&sc7rFbp)p6g2wYZ^65@|C1IV>Fw{7&!Ho|-Vm;d#Ds=|oHF~Fv?Zc%j`YX*y~ zs4<^kC$1=ZeNG85h;ntYE5uPSEEX8 zm=r35l(NM$3Yw9rt${S*twYH=(VdbM5zS~*Xn?`o4)40pV?!)gCJjF;m?)}MfT%n} zoG}$6Z@jlDp>)IOrXW9Ry%;aOSew{!e8N$Zv6|>n*R|N0O@H{|hl7KIUthg=_Usue z;L}N6bL7R|y?X}-4`#F3n>VkYK7ao4__%RCBx&$zThTCsadogjfIPZbK?>(68So7V~P*bO5@u)<#Ly98o9w-J(0WP$2o zWkYwmVXq)X=$-XKWOSj{A*LcCm3KlkJbD^$6Xab5k#ZsOXy!4HgAvKrg?Q{CMiuWX z&dWiuL4kGuN9ex9tCn2|F3>WMgSfalM4sYdsav#$-T=Uz6ZnkCh~9B760?I1>SDyd!?_!YjDL&V6W#Rz{c3zN`54697x zS~#=bhJYbtyZ9JbSBpPknIh7}k&=rgFgRZ~p80v5H+$FH0v(wrYShr``twNBv?z+6 zU$H9OZGdv<(vYbtlUEu?YqjN3sGnGa3@QYInxZI>6&f0!oWG;j%$O!}<$^6duq|rs z>^VVYNbiq_jxzM#YmQbJsu)+tplhLlEMdt4YB@?$=}O3|KO&D$oSROvEM=ydAQ72= z!MKprB7$ndqOuJx?AUL`CNV1hHA3W#LCmHkVM0_qid$uaa5-ubntE0g-+%x8!-o&w zynglc>C?JyvLp{p$n)&}{k{DMds&vfc=_Vl^XK!j3_fXmQoDq)3!nJVq}D9Zag}9p zpIOa=I2NC1B zjgWjI3#g1v9npP-vCQ-kpRNlsZIxWd@&K!urS*GsIa`OiAWFnY#M6CU|qt86q6FRN8m(V4M$*{aIZBX zvXr7?yx?Xefw?5IEF`7a{)a$Y*(p0Mnh@gRZ5o!P6)V?5&8sDN0q60436YCS!qYdo z`t5iE#=kj;ZV8N7Wl9sG*s{m`Rb^lAdim3ZP_v!>Qq-bQ38{9g_df(**5s&OP#C}3 zF6hX-uO%+ebDh1#OqDZsHC0uNtZomkPLf#Df@4{?QZZ*|Y-*$|j|EH0F)+MHy_J4c zD43`l=i5z?;v=OZ=yMKiV7oUevwhVfrZp1s17+H3R?Nr`zY2q{g*G--8`)CNs(?0P zDoWIq4H_^?LvOI+J>a4zNt)$ZF`1-Uw!5?A>@#b1T!oiWpPZc9K^a=iV1u}*+GR>h zh{!QUv;TyUzN$DGnaF=KVGm-B8i_}vD2_na#U%g!`|lq;dieIu8(fR3N|VerZaSOZ zzkhFUZ_hdR?C|;X!x!v5m-r_5D)=PHT;dbQT8q%&uxZ`)bUO9kpPrr`9UaZ*b27j- zTKK9n6URtN*uu3IF`JYH-7v~uH{+YS=!RpU_qPpVts6#&V1?2u{JAV*JhupOrn0yH zTnMV{9sP_<#G1lbW_pNE*M+620aR_3i9#P+O_(eBzjIgOqCv8J*!xJ_*d%q5DtrS!IMb)(sVg zK5mz5VW1R|A>O$r%W@{edz;J+5>NT68Q@q7F>vAQWobW0V1fo`7g(nB!tFwL)Z$Zs zecQ1VyU@lfv~=5yIc#fvI9v|C2FP;-gV7GYIf%i}I+m%$4*?a zW8Rj!WJ&7kMag24vOJs5&kR+~K!%EL6nNuZNLZVI96KnAiTC}RN^}eu&oph_g@hlM zBx!r%y0-kV9A$bX$E`O$gkqBa_P5`D_vq2t$>~o&{aBV|G2wW-Nm1BbU)T7ipR>U$&46}m7 z#k>Z;YEJRWNFJ3J5fY|uD(nJ7#1L<$Y1$fl7=ARws`hkX+fPNPaP8Pcw2^CFC=^qI znqVgOq;$%|p+WpA6qHAiNPjV>;{7jz#FpQh_*=-@i6A*ko~V~f1DGOab>tUQx-y{5 zlIhZ{1v#_?Jm#-YLP{CwLv0g`0GP3Y#0bXnCY;&AZusqiF0tONrKQ`0iKmY!9C*&MqK*gi z>p~Tpy2kypUS_VVrKrgwqa9*#j2vH*p zrZFCapAQOX@XbNQ&%2+9o%p`2`LZmnN}@_yo7G^o4nHcQ8LDsN5lQO8k|JplLv;^U z=?yA0VnN|5R_}|=5Q1C_?LRwyA28>fbIv*Eocl-izN|Zr99a)bF2&+1w$$qB9=E#v zZ?Ap);Qw&#;|ITA`}o0s#1C^vBeiykOD(wo@cH7a3?{RZtrCl*NR7U3fmyj=2?PQW zKmb@z?rR|>?101yqN7xiXVWsLdlAiD&JR=->?n9liK7%~Xr0T8;5>wAM=zSqD;}0V zkcc>ObyI9=TC}p~ld&{n=n!Sav?%iIr>8&u^2^WFeE$6T^R}tDJZ5KS_xQ=MhBJ7!f`qC*v<<>n+|?!p1aUMyd2B$hC1Ozz5uZ$kZb~E8Wv$4>-V)riUK?0fDsuK`3VimDt#|m`(}|ItuViz`ElK6Ykj+4L1GdcmRv6wXDmkEs7h`OiHbgi|Qgi8<7BSDVr$0XV>tBBfb^VX$&+B@b=ef0ZZ~yS| zlP7I7fB(mecOO0l4rW9w`NAF`&e|A^^~GdocW-YpnY3*?o6Q!B1)U|<0F7$x<_PC} zlVGzV^jexeDxLSWiD_%niw6Xjt{<{ogYb*+5b1CMQTbvwYat#5sC1YXFdUMJ!I>!5 zx-$t@hj0L%k&GbS(7KRUwg95O3?phW`vQ#^$*h4-St)#o9AfJ{L~^rWDmM$IDvOLi z9Z>!;bkA2{silXM$`Y)eU00@QuGlZ2KNc`M#=x5ZOI&1NnW>0KMrQC+Ca=L&w+uBc zlzQYD=CcoDBR0Fg3?Y?dSb&@(fR!yb@Pn1kaDXjM3(fN;&>FcxtjDRP-UOqjg*H7U zKB5u_df7r0qZ8a6xXiH9KFcf)A%W$LIZ+7`4kZ*rA|x!PZ`#=6pmbb^aA8`oQt$^B z?urkQobsX6;CeA{2~2K)jZ6!Iu24MZfxGmuY-AJ`V>FG;G5R@U9$@s%QSftSm0u+} zh73QX0z`BGT$s*CIMmHm+EJh{)3V}gHwaJ=e1p$W@P)r=I6|fSd zy@rSx4mA1=Ag09#SfQL?fnC=$0sc&GU|N_IGv|JM^7z+Z|3hlqmoHyb%LR`~IXXH% z`r-KOeE$Fb_U~tBbFABjmu*7%V{5G~yvrw(o#|dt;9NYOU%`!}$6(jgBLH;xrvU{5 zrIv;RfCmJ;|KRAuGWNqkuXBwOUE`B`gv+J{H|etmyF+3vYzlJdWONogc3R^h8bl7z z8bOyWb_K%@c%{4k3{>+V`c*?|&yWmBNUDe*eL$x`5c-If(hnK)&4TgY1~j+4(1b_< z-c-u)f;S0Pk%kI=%8SjRks}%Dju{eq5-!G&IY1?YP_QnfrtZwNfES-wp)4A+P5SUY zfu}Gn*6DydLN2@_nYX%RPJRONg1m7Vqiaj_t3JlQ{sOREH;yf%y~?y0P#&pZb^@~& zFea?YU`$+?7Ch6?y5z7H2A^Zf0@i|o(wR)%gf@gmRFx1SrYr)M!GPmC#7;7hN~{Hj z$iSU|$qlfPX+bvS;HxpK^N;)Li%#8+rm;CjKOZH~=$n6z{wEaln3fWVHtH#_b(2$3 zMKPF7SoB0I^rN~#^raZZ1ac#wfk8H6xQ_K)G0#yBJz({%v)E z7MX#-hsj5F)k!u&NrBcHBTr)CIgc2H67WN^0lcuSH1`c~)q9**;W6zpXQJNu~nSd^9tcP>IJ*Gk8}=^v1F;5XTE}{{%slVsIaWW100*IXMGOxDw3J8|X4o3L zH!U%C)B{UR1B3oxY~op-8H27N1Xx*cQd-euMc#yI0fXZr67-R6Ffc8ux{k>h=ZCWv zF*<90I6nIQ_uq5pUcGv?T+F=p)9Li^=s00-sMoLFysJa9&c_IoM-EFeWm)b{%B(0u zG>heu=T~T_h>{EerD}K&L$WJMe%l~H*eDpX1Hd2Yn>A!Z0Hbp&`b zfMNurB`F4ghrk-f-@J(L0;6w^f_b=cY#FV;Iz!-5sTcAmO^XccwXqR!?!EJ-%yREc zj&tE;k+-}LCn>Dkf!P4lLS`x&xLc$qv~7TA6#S#GJB>J`C1E=OnVgv-Z5c8rcK{|g zz~@a1sz+rBS163U)-^q9NV`GqN7L9Gqn{6wAV%LDMHDrfRZe}~7&Dzt^_u%WVQ8uc zM#ZlnG6a+|+dD*!W}azLE>MtZa(yuipgXWLg3=&{)Z0~Ebod| z7<7cS$lB2vCs0aeHh3ht_kJ?LKCqlg;24#xf`FeGw&oS~2G3ZFlj-0Cd3~(>wQ?LT z-nQ+ssv>NbY~8f5CLJFi{m0*bFSG3R>(`6RMM^(pyVH8C zUzP_{{1L2~7N~1DL?vfZp4q*!INaac-{0FQOXqRUScqv^RkJxP_Osb+HeZT4VUl$q z=9ilmY?}%$?L$5~u%?vGD)xDYA<@6)SBn0lo5HQe$^0|ag!q%-wbG40Dfas>aHc}d zFoHKV+D)J@BPH>PqN+oM0Y4nljctpGE%?L-ZW0Q+LO#BOwHCTP6xdjF(?0YLiojPd zgH#%P8w0e#%P)@On=~yFD)94=)mc|k2?X!JF}^JG@Pl&LJ1X}s^S&%#N5Hgze-w6( zu-4=bUe%nDfLBF;4pOyE+s3BF+-Va6loXg8eC-1Lob#F?;=L0vxdFgT{aFjm4Ye+u z3Y=wSiQQ&H2wWb@_BM#}n_m}2p076VmL`fC zZQGTsM-PD9Ns~_w|JzKCmLs_1nG#C2t_6vfb%W+1KsPUR$9$*&G0J#9s9{lADydl= zd`iD2YpuAVwVfvhpv$;9YjJqE|J$=?NBjHl-n~6N`Q)5?^ytz4!QtDt@BjVzi?jK{ zy3A(2ZDZ!$bh@*@H_h`rHud>zaW0L>$IyFdZ3Wz%M22%7S$j&g@SokB<%x_xC1~GS9s+uBn?g zVtM%2=FL za<>mAcMky?^`La?lT>+|AknCT^-IL3qb1dfP*8bba!^{Fy86C zcQ(sB7DncI=HU$`zLze;E>RE&-at)F$%K?(PK3~g)TY?Bp<8hQ)1ql(5Yr+EC@Ux^ zn17Oyp=RlNU?kTDbf7S#SRKMAKlk5$&vyDu@50iM@w zwKyfhs1#zJrGaLz?=bS!3Z)PtX3QPvetE5hHR3 z`G?npUZWDF>D@OlSN)KU!gNwXi}3AXv}mj;5+quPQxl_2G4pnJr+jp{|M+NsZ@QD= z7%RM+Vw58(opHXd>(leuhmR*Gr)P`0NivQAhFG~yUI`|rK=Kw{Cog!7NP3_^X5<7P zQcJ!A4Dxe-Kw^Sw9oS|`M*QhoB8x!k5$rDe%ulSBP9stD<7dB2tr3SlB*YxLSqoW! z8}H^^iyJX5NGK)C=J;+}tkX(4hYUj|ah9e99G@~Q;Lh^Q6{3yina?v%mBX0m@f}z? zMEF59EfknGq&kGAg+BA(Q{A1S~eCvw~~uDxzwA> zQFurqMFV}MXpGTTA?cLJ{M;C)riF5mWC!^viUNC7V|ys<4;68c5rE!F3=C*FChhO- zK701-ljGwLA3mI)o$T!F92^`h7S)TFe|-3K+Qek6cUe}Hll{Hj$)pTzeSUtvI6vq3 zs%A-{IqBiMX)y$=iFdo&TwRcWsH$$ReEs5nf(7Y^+WoKy48KW?7OlI<+D3KbPKssW ze>m8Ge0+4cH!X9QLTh4zTeNf7aRKg6J{r4N)*n87djIj{e6|SiiIC4ROfUj8YDq%F z{zV_%h7K!n)CVFL^e^rJAj`c(pN5)25|gqTQdkx!l41-MEx?OyUX)%%$4mk2bj}EIlp9S_a0GThL7f&B+?{#fwfGa-V z7G#?NMsIG8t7a`&1Tvxb-r@*O>*Xwq%=_G9rXtH+3420J3v6xaGY4Ve;bn)hijZO( zV%Ep+zrzf-XvmL?7$=UOlFHX;9$$6ibfDGFVQaruc=yTwppTY5~D?fL?tVh4+Rq+{DB#)^(zy?oh?Ir6#`w+% zg|C9djmXt>fofr)EHY9$L}_0Tp&$ZG_m(hfT8yUHmGu%x$u()PBFkqnI%{zSR;26W zihORG`u5P`Uk_KA7L1LG1PlykGKXObC>2g@iOlDD1_uc*o6(7Bfn^x7$Q#uG>y)z= zn6khE?ly^O(Y9@D+ooBulvP7D5emekfG6uT0Ip?@onX)p9pC~)I z!ME)H@aHlZ=RE`HLseb|43KSBx>AW5PARPH3H-r5k!fl5AL772Yp`hpM;dg4DP@@c zncsAa#Aua_$0%_~bIyTq6DmBjE{>hXZBpEsl+T|1`t#GLv)TE4cFqM(?>~He`NymI zvVvW)v%9mqm*+)jo5f;2J3noj22*n0hcWkF%}Ed6O^Xq*S{W+O^Jkxis6O(Fgsg7- zxqo2h`yu6_=2?sI?P0WNPUHiJlSN?SESk)@gWa7c$48GJ9qvxBZ;Q7n%Y0ds*4f3P zI-4)*7PA<}`PpLm>dm`PpH7wy#;S~yE~evzbwFwhpkxThT7ya0jR} z?ku5efTSA$1ckH)p!9b`JiMu4pUw(42Ns#(Iv4{%k&cy+&WZ0F>J%eGab;Ry@VhAu%&51R%G@V3P6xefZj&Rz5zg@0eUH3VD#oKp5}fnGHz0U zc~h`+qR?bkwM=}U=wB;%liwPH0l6&8I1QB&eBK!0H)C4Bj}f~rprO(sinJmfggvl( zD=OZ?p@GFGeL#ejc(vBRVadh7!7%le;x+(e{uP_WxU9t6NjeziI@&oL0p-?eklbUY z1x~4mVNw>q{r2papMF{{a6m<#V=2Y!H*ep(eV?o=r@KYDlVhLRw3yH4^I20btueWG z$$ISVu?8)258q9Taj-%evftHf1zAO@$_s|~4a|H$q@WZ22OHkcY~Kh*i)LX;ph>fG z(Fa&ldVjP({qf21#^MkMokNj5)L348G_{M7g;jAX>LbnEi}%{KotxiX$>)Y zb9;1gcWZCyVb6VdI3yp$;YT}E z%`GozneduYMo&xlx=;!ra~&YS#I$AJG{XdM_QgaWj8GT2a{!(z@@ZP=hkSDYl4yX@ zH@_~dg^fhhk<7rV=eAnxxtYT@1o%QZ$FhN#oiC9T76yliC zRlS@$kAcz`FJ6B9bh5LzKRq~fE|1B~7t8tlysj$e;Giih&J8!j9Dv2RjPIt!m5|!M z2>G)Qu!?ZTdU)T!%=be!2Qr?9_Y>HKQGmfwWL6qq2l#ofFn;a~YiEGfgd^7BTJL<0 zsck#S^GApKPoH3=MeZzCb;E0FMWy+&nlGvb3v*pC_I!p}i<8syDufuYp*3e82MN)1 zAvk?Hs0F^jD&VoR>8lV`%mDC04Kxlc_qt%yn+yyRfc}_pEwr!zd!@UoY@cRB^y_g)D!XHr$ z9ac=BVbg#lmDrJBizm?zJBH@pKDS)DgC7?UoS+Q)|^Yg`QzDQUyh@D7a2BFw!xJfemPl!=|xCW$RFNI_$4F?U4=`#F^ zUy124GRh_OS`eXR$X=iYar(NxWzU zQZAxjI+2+svnjJC$1Vss-e*#ld5)!2lSy%SaIm*GH7PcAWm3d;w1__~>uOocZqdor zA)cI`VXejatZG}VlR~@AINU%|6OtUnH3x(E2!AXpq7M{p4UA+P^vnL>0HL-;rY-+d z2;m*?O4HU#;gFM70mq&QO@Ez|jF?ej)h4 zCDsFre}%9RHlgv@7y!;z*cBk+fV?)Px@oXURNJ&6;9LuMMa2+t!Ky4A7>1M$=Sx$xnp6eV1=@1q;ZD3qq+u%d=01YePv&4?2M@a$jIy zIRINez^<{JH}f9eQ1khss+O46fWK4{>jxV;W8(pf({pyp{K@g*uTP);czjqmQ`gJc zvU>6E-K)3njnA@TQiU{M)Qd$`H!U-7WeZ)j8i*taw|`Es-nR#9wjWZ5z#q{|Q03Ak zGX&)YxcYivW(L`2hIx}OFl3%Jyi14)umSL1SQ!-ZC&4+KKZn=S`X`?36i@h5I;qRW7y$ zORz~aEKK+2$R}E~>%n$(?qf82qX~`P9L45uei3dXTGE6>AdE@5$4=F7h?1#_%wcpy z92u|+EoU{omrYkm&Qa}PRfJ5>G8q-(;tqW z96vhPEwhwDXwDbayVLX2*+$VC0kD z)9XNq(8p-@MiUynIf~8S{36^^v?L2T4WhunsIc&f!XEU(DAqY!z<=L!0XN~T%Vk># zc%vljITk_+CN&YZ1<$x>QfOdaAn#zW4lFn|z)gVf?*x$7|MIW@Mz-M52iS`<;7nqk zjz@ak4ZQcH7-a-2sT+Ah$3R;R^FpmGri<|8p+5{&tS6@TUV9TtMs5IY+CEE<^I5BTSqn9#_}cYAim^Hv1E?2U zgBdf>5a~MnSC-{OfHSiN?0c{%t8JIdYCd0hYY+DKe|U6ww7++-J2~9l*_)I_hW+)= zmi2kvF5B?_)9LdUFF&2nTMVLFD>4WTl9oOd55cieQ65pD-fq_}f52LaFyK>4~x|aY#*3 zpjS63rr2UXSvhSV8!yywGpG?xcczDjhX)4-yVITBNs(u+MKi_lVbjL*`TXOjlaD8- zi>eCPchfB@h71${cw9Qwg-ysO$%0shF}aa0Z|_v z_*CryZ4|5~tru0-MoFr@jDj;E+9RuSLeoMc;RV^_i@@w}@`)BfF!BlWaBYlce)Q(% z7|qh?&FyhZ(UPw&V3K#3G4mcuEOwW{aDA(FiHV@9)U>%7pNTn9FCC7Xb zIKHl#ftH4oN6A=}-rkp{gwhT2zXuOc^Ah(?N1v z103FDIRLO_S?(T#q7ft%AF;V|zKeuHIR$)S8?e7owj{wFI23b7tDhn=XvJ}dC}swe zqSio!z+DQb?`75>9PB+hIM^xk%!Emv9qr?s?WV5I7S$Ywai$L^XMcPC{KKcSU~Eh) zZ3a^8yJ;cVzD^0U5JQFj)C*NactPODR|1RA>@g%LFqlaV^@3mBC8CJ&4Piy+7A7ZF zI;UhC#lcy2#(3<(f`+DTjiY0EF6*>Crr$XlRn;{P)vxR2a@o{P3r}VshL}vsv#gv< z_V@M=4-bwG_R7pRb-k$SrfHTsY4WNgkisq^i5g?sFe<^G9{^A5bS6OG8&w=W6}Vjo_A|C2L(EVI`Qe(7w14 zlo!Py_c#;o{Nj3TClEoj>|M2vC3-UvACA|=Q)3KskjP%YU6 z`pInrrp15$@Bf=d1r<<^XZIV`mK-w*mQZ8n1@|mMM*%Gi3YjQjn5LjnK??TA8<_Q;lJ1d_obR$4|2@%TVCQ{L8nJxw@WUibU17kazd0W!q+qp?OIXXPp z+nHoGnb_ve9v>a-P0Gb$@$r0qTDNsb%er~_`pv7iAF8HJ$;tFS@ZGc^NZak94Ncol z|BiMWOpYOX0?{3D^_9S!46>@Z)w1xl^`Cc!DBC%I9`JOM?4xhu4^cRik>%ak`T!l3 z!@@_gAh7zbK#PJ{Lmw{cS2A#eY-&tW)J;=iOL*+aB-7nkzCnr+2@@cuEX)19y~Bgu zNrsbuX7dF$b_=0yT8wBxf?$=D!};9!9HSR1V(2 zMUdzb|7W482u40(97&21)pckv9+L75kuXhA8!MekW9wVIX9V1*ihML%RqBjEEZH8`5HqqA|qjS zev=MSgvu0NkVKS>;KBfw11$t9+DII7JlGi?{8((jg^Zk=;>iz;mhazx{7F9fh{a)l zPd26}5_=0yd0iW1KZ3~#g{cDp`U1^kQodFLED78aa{gs z1ZE?|ksD(jjgqyntjv@^N=+lRBsQ)VABgTw=jtUpyltw_w^G%t?{WDh;U^w;SYxTp znc(WbrNYrx7}j8XiGcKzABhsNY^`%?fXqQtk-~Msd-)JLK)j*w`1=YahbD+G`Uk{N0`|PB!gtx1*nxBLu6&NeI-u|+1RL|m>E~OQwU*;CPeH|&(hd7d zm_mNcUBDjEHv>lY`h(p9~6L4DJCs5u!yC`pgplV->`mtxuqQa(!`o*tA1RN(n!JJ zE7O#tHqTpQ4K>b48jh+Zzu&3i%QLIe=gY03n|x*-SOvOx*vH)^)$HNU^kL{VrWn+! zxbSqg=k>4?vzR?OX;ObW);w_gN-O7-J*{$g3e*VB<3sC(9G16rBHY0G2%;TllSsn# z%BGknd3%=Y_F9d|I?|kWsC;nLXU>fE5??W@lP1oJf)r^M%ta6B`g!2J?bQBWFy7*y ze_NZx8C_<(ef1C6Gzbm@jn#WIzk@K?2QBg@^7NPYN@(8_N|9!|bCgFT&T5&86J`sW zwORg_MXV6@o?nG(B44y14iTSbh?0|V1()^ie}p> zh`Akyk88t@M~ba~cBDIXsM?7cz?w?`ID%RNwe8(u7CUcG$wDMP%@hX*T~}zFseY8F{YXm!CNZckA}v zLSqg;9}f*Dr&vvD2fv!TbC)Ai#+QhM!Z6RWLM@QXX|9m4-g%;!QBPDG2=d#@rg@k& zXBSCjzc{hiN?C>=;;{RnN=>$`d4PYQn%i6>smH8*KvidEGm>5VBmzi-_D?jB<~Iyq?fJ!>c|F#1Ht^cSKSENx2=u=<28Dbovo=NLErH( z^V>h1Owi3r7em!Gds`BoI-i61u_D4LINHPS5B+j@CWMA`<8~ZD>cP{!fK%H?AJcmL zx7PFRx#FZ4I*~JusgDVF-eK z7SSoSiX7RMF%;tsW;2g(ow2+AY1Q|Ix3zaK^&N7;2)qub#4h?`<5jV3da<`ha~jo2suG+FNi+Ui21wJ`0ciWeNl`2 z!rJ&Or~iIm0A+@qH7V1Q3>0*FJdB#jH%&uMW;S)CiT>11PVd)U^s3LD&G+SFuM6hy zP1-=@U-LW@%gf7B`ZD}8d7y)dwqL$)a~Wf1364k2UWlQt$81Bqb35TZgw%JQw*eIj z&mOlsR=LLx0spgAn9$)HcS52GbwmeiXw>#?_X{y8My+b2sQ|pM%~3q|*O|&b(uhi% zs*}c3)v%h&5PJJ@&MoAlcpU-Dr`fYSDMQYX?=GD3lPx+L6Js2M)jtg8U86KX#)_Ux|&(B0UFN`5U>}8-KuCt z_ME5jC!Qu%1 zROv1b;h2fJQ1xBK0;BVs@9U;E0?lk%zXNpP32h`*j^nli$i_6+fj}jUKUP7MdT44a zTN#~lVd$6`j#LyA6hL8EJg7h)a-k;bR0O1O01&>H^do$cQaCS4oq~MdaSp6A+7m*u z{DZ2-87cMh4d@36*~ty_69-&)E$oD)Vo;)eM9>0pLng|@bGf~5UretrKd)ZNx_;~9 zf^`N!&uaxPK29DU9?K8j{mC>U34N+Byb9O8~NF8YklOI7I!4E=!Oaq z896xd8-SL`hg+wEq^G&F`6=-``*C%(hIVhrE7z%z#9B83sB;(S&n&Jp2j_Nns zbuUP$aOr@vlY@%xtYxV3iNCeYB$sb-Y-trR=n$*{SWM9 zi0>FrqA)}RffTet`;{=UL0A)E4zfQ?SfHIKfZeK3=yT$HiUCQkJrx3@zu#E;I-vGW zHs5x;Wv&lw!)l&}nzELCu(&PL8fjmcIF*Su%DDrS`W=&(_3b+9c z?3>-@MUcu7jIt*AC2a1boi406btnybp`D#c2&!kj!&tCsnm|BA9E9)L%Tc0%w@!>` zL%8&*Vn?WW0%`AX>6e#YmnO!}9z}dU54&Ek@4yF@+KEysixbbw9_w5qVr&2O!M&>I zDF+{+R~M@v2VR}EOr2?fHb0&Yr?y?i5F1LL+o>=8%x9zHY-{p!lt$%fI4HHCiJ(7F z3K2|!PRys-=2DZCgKpAi`Q1NuYpu3QO8Zv6Ojdp|q2zHCbsRt_R+_!Bm9t#2B!fEM zXKuA>cS2=idGMs)9w*~Z7C3FQZ)vw)9W0P+p_n_jk78iG{uIHwO1Mpgd1nVA)ca<` z)UiK@Ep5I0F|M!;AIab~iogBh@ZI<|H73X>>|VG)+KGZ9Rjv?gk0Ot}w&$mLibtGI zA4*7%YKajuVv(_tw%>Amhnqr#k2>oEJo#bO=e8kvyBXr*LxT@CJ6*ZTSOH*6GX-ny z^I8w(Sp{<~b#%IMsGq<-yD$Z6wgJ^X_s{-#R?M{c#@f6PoY31%J1mR%+@ve<`E#|< za}3OaEXZ^p1^o+qNs8a?v}tz8-l`(<_t9Jd*-|Aoe1$Xbh(e{7@G7O~kE=E^-TOHmbHEj+W4qc zY6cMtQoANW?HWeC{}#l3j@W?#@G%w~%sE>Qz*<%1HbyDs+)*Ji`g&|5_|Xuheei;( z7kl}GZmg_!(m$_-ZW$XOB`@TN9oqwbldzXtc@jRmhx6|>*&F;Oyh&_v5y?gZ)kb3m z(Yx)*rTXa%&E`3CHs*eIm^@u#U@#Z_B__vce1ZIN%^hSnr@z4&E>QPve)ALE{Cn66 zz{?C}W4l(Jz_<5|XKoJ$R^PGK|60l}A#!lAlp;3<4UVbA&Jp>14~WEp>go~{tWfS9 zrY38qW3IFCC`6na=DU6FeE$vXZ70tWpli#Jnfe^FS9SiDf%@rE3Wd}H92DuVing3K zhlO?C&gw}b?ZWTtV4{k;u#bke&tv@A6lr0SDx` z{#fu^3?wUEdoEJHdj+?p(F&)l2{(*%B@{pdg14OmJ)W+ct_v-KV}c99kZ2nYH9jCA z_3R(t+-!Bf1-z&Lll+HvN@tgyMYlaA0bk@tjN?W$!}FqH2{Ulz1dLF(8s=@21})(5 zvnf;^;ojL(Glaf#^zwKii`}BHwO>R3483?R04iJ z2pZoBf?E{7K$(;T##z02?GkRg2DcCVGI`8)Pfvd&4=AoUpbUq8y1GtFSlnb zv$>>fRJZL1%WLQ2uO>+PeMS^quYP5bCOGexwXJg47OiE~cSLK<>q&ESwl6I-l09+F zcCTJSD~Px zT7!i#MyK+$X}Lf0JCL_uwJYB4t;X;dEhNQO(`7V|^iWuSx%G%;qz7gLg& zRBU5OzLekPo;x{k#>jk0%n8`q$2i8|xf*bl@x!D5ZL@cW&fYpmgW@y;VYw|Rk|KYY zo_wF&_n4%k_q9(y4rS>WQ|+?6!n|(4YrDP5hPWQj1Oj)b6E?2=c4v5CtN91diR5K$ zyja1Y!qpV~Zd}zR3iP8Oy>ft>yJ=diNTa`F^wltuGAjLa?se{KEZ_7ihLU^C%M@S2 z3Vg zK_#~@kf77uZLp@ue}Cuf3%n=Dj$`rdj4+cX8tr0_x%ODLt&{b z&IUmZp?FYLF@E(!sh!?A6Vw7x4@_@UT(jyG*K|@4JskKlPaGkQ`}WzmF_kD~UU892 zo3;#kkX+VSTmz>c<3(e!=y?~m?|&BVMQQ71K@M6IfXhJ1{lknmEO?)W@Mx$^kb*7D}l?;ST2+nmt8swd+{r*kmPUJyTVFFsH-St`vn@sc>s_ z4$r%B4|QQ+_7(_#>TZ!!ttOg=t0R3p_%a)d&-wQ|`}NhzZ?lZVcu0JPr?6Zfd(@Y^ zmKt+i_cVnu=S<1(ECVsaHzS#X*;dE=t61+27t=B;l#XXXvTGlA->*)0m3tBiq7{(o`0xXHuSyy6pyBl; zl*F0X1>!*zJ^a{wzpi8tIzTx%&bLpQ1G7eW`MmhW(>gW^p_Arpw3)kdSYfaxrqGy; z%EL2mBUCZv*WfR4iBEON?^M9GZclBRDFGm{Dh&XMItkFxJaAJ16c61dS)x9+y(4I(nl5NvH4tgpG&u{u5sX@F zO?Rguq(vL088C%`%zuQf8VMk?eJH(nm=$110yu831oe_BmJ3q>;uN%8+Ac_~JzI`M zQt)-7u|NE?L&fKooxL=QVE-m{H?SM5V5Lb)ERaZ`u@Mk)kaak3gpWa)==WYwZ(HCE zq*$U;2}|NH(%#WaGCh)a`9Fqe{zUce&F8*qW5rXYJq4qh?C}HGEVT5hbTKNW`FDL} z0g5%UWds+vImc_lHgN@N+y8h%i@ph>UztDl@iD=|>gE8e5PXEe!Du80Wh9tk%Tm9Z zG7lg3BwBNKF6OsNH!Itt@=3mcm>fa&f1*)53j4+v5bsImbak5=Pqkk<{v|tJ6@KE3?GXx za+g=+g*Q;$UJO+1LzLT&LY-4ZLr*B-*A2$tR1DuYWf7@p9AhmD$~5Q<9+FDpU zyjVnbYA*R^UH`Pu(dgq?i=cD>AD-`U?H}A7k4C!ISW8`HFBKovDZPD{VFs(7Dc8Jj z!-2WMb>JF!&banUCwEai@ODW@?96RFB0(LGP&Wv)ai8|+k&GuCN}tWQZBacll8T{* zCqeciY<#KIJ#MhM3un&4rpd@uM6es2mB9l?b}mADJF=q>y+5)tA)8Y$-BxLGb3huf z7b7uB_Vxq*u%FI(p|_)Vy$BYaQ+zIN*(j}w=qrlm7e;jb-V*B}vjQ`xCH#ag=;|QE z#_pQPUGINUXQ|Zg2{{QRd7=}eSix?YTj%73kyFY&GAIt#ME^AsLA*88Za(9jalBM^ zUw!um_2n&PHtupeLre_di;N6K5O3GV%fWhE>v6>tRHp9Et^_mbSGRF=^pJyu_JUjk zy1u$~yHRgNqsWnrRg>FOusxI&Kw0vM?R7c_w}OnfXM0B_bhWiip!TaP2qLvG#Z?zO zt;LDjQX>1%SjE3^`Bh6gq4^gaCE%TpC79!VFPK%F!OVWz+_yNADG5!)&fa`;_lmCs zipaBt$_%9F+{{}F3npPb{JgB7W!vO^DWaYE+T*Xbc{w6jNJ{2F;=CPZb=iLG(*V2} z7?GOKr>~00P(D*k3*2#5r6ek1lv<9XPMFAl)Ce%(y zO}tH6ISVut&8_VlPi@a@zn-YqhK_(6Xow!k_>I63^FY1};x4HapB>ybfGip?{8$%J zi{?zR#U%y>&{9`sTdKq!F9*k>bT)@yd(*y(U#oH`wFPXu!_)=vUPTK0SW_t;=YLQ}rm%Cgac@^r0%>udIh9~O?Q{hY=f1G4GfWa&lv3y%FO z_xfRjdAwIFV_wMuG0<7@vfiP%+d!wtHsgBkkR>V1z=3PDQPfZ%kZ^7%HqBT#TkkO0uB%*+Uxg~?tYEoTz(N(N zsD)D5vh~XXmY0rufz@@MRcJJICQ74$Sk?09&yJcYg#(i;3r=Fyj6-bztPl1BwnZKN zJw<)$@#!kS22;4 z4N)2MxlBVJDHMvJcE_|BnxfLN+1>8v@!uAT7o7MNSJ1ex!dqw0!fyJuUz-*CBKkY= zpz#FSsT$W2iEe%e%9Qqn^3>R|EvGkjwR}mX_V7}p-x=Wh0Zryjj{+tHfSXhaTMAwn zK+C@jUEX#w7+Qpn#FM0jm)A~0(P901Mca$G1wpz_v+qF))lUGkM0KT#galj9!JKJ3 z2a{4IO^4`)J002xJ!m4cC5?O;+9FK2cVxw3xW6$H{|Hv=$)B5Bwq2+{e|;na6Ck(g zE@<~4&rwR!iQ=1)6nY}K(<{^p4KoB8Bn;gtap3l(>Y{mG1C=#z^-vtxnac-QK$KHT z(SWM&(dKp52Fa5}<7vc%G1M5w$@{5sVWp=pe~WZ@@YT=7PsBGLYGP`Ju%egxGW{sT zu)iWTha(^Kr^6;40Z;6k=Rryc%CzPXF!=-GOl$12Zz>YsCnMU+$}r~kYkQoYt}YOD zaWc}xkm3)%7V1eDdWAoYDk777&)be5v(5G!K_Yc#W8MnpZ!)tlt4+leMkS?fz2!hia`Dr7xhl$a3S_t_PRu24O3tsum&o3 z*W?t;k%=OHlL#QPG7gGiCHditZ=ftzW6Gg(EJG5uBBJw0e!!8e$E|xIY^vs%Gql+H z8xdIaW+Zuejb`o_m~0D7WxIF(mx&e3D-Yg+|MhU3cM7$Txr7q!5}R{J5gLrwPyGl5 zOQi?!VdIBD4O|4$Tf%0ucI*GN@VaKJp67%{ao}K9K$GH+gie!ao)i*Im40=9S6qV2i2|X_7H{ zsn(#(?}K-2c$gg#-mG~)Q`x&M7*7MdZ48>r>NQlDMs+j}3a8|Cyb)3mIY5?Jf|5P) zN3UN~8wafJeiD1Z^PEZG736wX6b+c3;-|D2*K*tWIxC3+bjQY@id6eSPR($_FRFf4 z*G->y4%%5=ggpZhI{pWdcnR|!SLElcPdOCk*d&^C?}wO+t#!#mT87GDGZSL!2^7;{NyYKuYHr2{CPUn6QoBAbhL&e2 zX-7$EqvRR-&Jkuo`Lf9FtS~ULXhW|5eo#kK$ef^sZjs2 z3ZKMq$1NbUw+*Et$V1}~DOrb)w z-P+#T4+xrutH)vj$sxjBxxywGnwl@L4gX=j3MzuN@wZF(O7?*9wIiFD6zaBi__p1u z4P>_7n44myfF+*C)ANc`omkUvKAzEyV?bBA_|^dq6~$I!owKpb>2GWZUbYp^b+h3j z-PW4PoO~v?j?1=DT;$YPs@?po-e&=Jt>Cjpv#3(e$*czNAXL@`foRnv_VOyz1>+x$ zCe=ojM)CRoK_@@DxSnYCLEa=vgUCMatCakxE)*1aGfkc0`iDYLy0u0$u}PB znOcMa41gf`Z|KM53s^$$*QM|8$5oxh`yJD1S`;@uzL&&s z5OiSjd5<5C)tp*u{rWXpe(A}G2))Yvi&1lmmDr~8ZJD5uf!8n3)>N%poKa@;{h9Jn zWQXc}u77rC61J}f3ZQ-P;P^0GxB=2liqRRscPOt5%1+nSV?_Pn_ZVKJCbiO~Bfp3F z8s2Y*JBh{v4QS10xB?&Nw_35Jpjx8DLf`NVnsH6AD?1~WQU9{Lp87q1&_Q`g1Rk`M zJ;nE_Joch<8HehC)+QKI0ifEl(b~}n4(FCzG>|2>EzVge$__PyOV5IxA@7805%US) z13Mk99p4y;_CDRM*&;h{YP0fjkOhoyy;dv?!`pR4^|~trkK;u?7C#4s zaDO26qSQ1fqwkUgJP!RrBVq-q){>thhyaR$t@*i_*-q$k7C`qoIskF^f`pP3Rprb- zoP$Tv2sU<`fzLX^a>H_wo2Vtac{$4AI-JZ)L-;1Gjg#WP1zEd3w_o#j=Zem!SgSTZ z-Q3)q!mDVtag23`U8Ew8ywQ+#8{we~zY&qhn#}Dgimwp=!|cqXU?q)w%>dYkKx+Ut zJHEz+BN>`6dudKatO;O4qvcrU_u*SF^6L9KHN2gloxSbkoxku9o>lm9m@{&y z!B;Dzhf)X5hd1Nl`u^%{WkjuwF^U$1XAOR1hpl!Q$-L|*T&aL3^4NF-A6L0g0(97QW#tjb~Tq}4Ewi=QWDqMcHx2m*}KyNg6qYagnP!z9$K)9gdD+vvK;# zm8}Jf=E(Fja}aeNK^W#l`2Gq5_oS$;SvO1nhXHen>s$y-u~{t_w7O_2z6DmjwT~IG zHF)i?bRB6y8(t5Xgg;C0V-9UmvUcPvo%@eE`$80DG{l*BvFlbN+kptHZD#v!og`bd z9&&jU3YsT4{c*g>HcvL@JxTvIQDdF4HSGbyf3hF&JD+vGXrJtMM_a!@pv9lLeBr-j zemUPg-?l%=Oz3Zf``-Qjewu)xn@lp0%-oh=HOD5U(ytCtrVJhZq0=h!!vWR$6~a0} zXqq0~{3cLoh3Scq&s(0v%OtX&__ndgGO(2XeVz&28CXe(RTg6OpH`BnvYpzH z0M6=;haxL+gy%#?c2V1L?XyIxT;6O#y`oP9C zNK#*iMgf5(6@l(o2o9F8uNwo`w_XobU7xKVcPXr6WMlJPUEZHQO>1|7*S5)jK$4L3 z#6>FZddmNPMK2z|#P|ogri|`vt@weUG8rS&qzgB4xLC1XtkFHC4e2Lzj`C-RB#{mK zXZv8ZG@5mpKJND~yQ-?H0PYTp8o`TV5l+Oa+nSQTKQk%~D|nm!-mfG5z3jZ)wiRWX zJzC;(4YYf)p~W2jz%Y(%{e%3B@Z%@Vs9*i>ETi1T@AvNJtVh@P-@-c}qK>w<+8e1x z_zn4%+C>%gkwIJkdRO#jxKdTE(_cl^`@mEudBx}K!1EV>H?OSAr}g8f ztB@YkVBV8Y+uLIkS<{#qZ}i9|gP$cN)&5q-Qs;i*B~gp)rzmlG+c)`&I2oFMet3$e z|CXW1_fC(cKIU;eMGfh3JI)JZ!T~*a{raw%`QAd=*c2yo^Tnr9YIzo`7r8t8*gO)} zZ9Xk4Ys`zkPEkYEV)9|^;O%HbC&_6K;d>X~aG3K(&>0SKVl?;{jiK-e?(4H~tpqAN zP?5Icll-R;p96nUX^}^BuJhmFJ&=d?S$e(pJ|`mhlni20197C-GbRphJydW`xfTBW zYZ)R(_j0W~z|b%}{tN!oh*4V)8pMW_B#|FdM}Gp|+L_YJY*C(EwTR6PVF6~+EN&ja zuz?~X0q0$5vzf+qHjLOP3h91}JDZaF=XrbW_FwITbi*cg=%KU;#Yj1|^xiaryZdu1 ziZ%r{g#iY_irk-jckRt#fKSt~0TqVz;BU_L)#vF*YQ4rX7l0e{g_E&z3%*)^$(>?2 z;z6gJZW(c@hEY46n6lne-MCtuuw=LAsI{i)S=HoR=|)j@(sqZ{iJOZB{?GfWu8&I# z`^$xlnlLx@TF9Azksf_XPz=P(EUBa}p$(zT8~cXV6eDg<{hxw3 zRy6U=lLoo_$qud-B5pGth=$Z9x#r}QXbl@+r-;6 zmeIEVbIz4dn|jC0xL3n{cb#4Pr*Q9KU#+|oreghY`7@7=-WDv9#k5un0GoU^0ddpF zpm!7MU0-bX8tyC~crv#z&Ujss^kX;8@QU*+o2iv)r^93{MQyZk+Ep&oiJh|_pBFCa z9REo6rfyP0Zn-?OjL+8q9&cvHa+=%051$J8Jo!jDL~C+lEXdM-S1QU&rEVp}Pi|sR z&9pnxl6isHg55rrp|$byYxExJ^_#3-3uSr|B<^$6{zc|6^mhGp*lJ%-hLWh6+KZg~ z;8-rAY>dEBzUlp7gXek?As zejZkJnQIWJ)%07VGU9HO7YsXcJ*Z5w`eD(3>heC+-P39_t(XGd zdza&UK5m-h@^!`VRAp63ubY-BgqK2wry@MZ-%?)OHx~YM3C8=SCQ(#G_H7bZ_-Quf z)Ly${m8|I(@7R3nX<>CWstz>B*rm)3iaYl5l1H8UE|Ln}{Te2#`{Xhd-~L}z*>qQa$GfEv&F4FE#3 zx0aY=HbJ;N(ZZ@Ai}p1Hi!Qga6)v+9Hgx;C>HCd||3O~t2&054!?(&SwrSY8w2C`j zvwcT^$yw`p+S)GP3dBSC#t;QTZZ=^t9y6El?Ml_)3?$x7bF8J&?+lcfU5FTQ5N@X1 z_=36`?BS4;<*MT5FR4h-^NyimmrrLWL&xdM_QAu2h=~2gf?c-i&kY}kaM0PzY%2Is zLX*#^!IQTJP}80U+1F}Vb&X1jB}3EH}xdKBKQ(|7#k8!gJ3 zBJAJ9Skr_Bsvky_F-Yh**=sGXS1yd<4h==kgmC~ANYOS1m-2#~U3BF8L@NdM)?n8c z67vKY;%A}R;(Bi=5zTk@{>a-GRA(A7EmFfpcED(6nR7oWQzo7P)ri^GC_|$mYd0IZ zoNXD$4{uv5Lyfd6G`nyE^)500J!!(|nxunB`S@A#24-?(HXx2>Q3z9mzFl`BR-&M3 zNa@ULSSsr|HU=Y()9OmPU`r^Rc3#$mpLizX^L;qc39?%xNGY?4@BH#@wRFND^!v@{ zt~R};@n2tx^2#9_L2P+@rpzck-Jeqz89DZF!esv7$B0uj0+Zh=#4$7iPiHiLU{Jvy zhW|~rj1$5nfkU5r6bcS)$%X=32WL!b8Va~t<-RWa%Shl`7@*JHMLh$?qNqtjgWKlh z+3P^nn)h_xnmgJ=KUgVS*!%hI*_!8<)QW9uM#k#r+FJRl@JnnaNS8;nK(K%q@Wxg< zD)2w2GI3p$V^fqOg(5@PmNPs>ox7`P5StS8D&EMP3v_U+v@F8_I)Uj^toEVvZHW0u zm9{OO8q3OR38)Sot5)sT-SlH{`Q8-cen5g^Mxh!J+8jU!IO_Bj9<7?VF#3mxGGv@| z7v4{zBZ7xAJ7s%MQ!E%vL1F0ps3kG#e?H?RGiA)g?sSmjZ76;=*_$Pb8OM-IS67}6 z7=r~vHy_9LYcG9w_muC4ang-l4TI=$`xOD<{Q&;d`jn2+2?J0dxBsoCg^Zt&A)BGX7+I?TQJ9h8GJ}J1^FSfT7 z#r_ZRZr@5hX1`{VPT|gQWprr(w^SZ8MP zLeF1Qx7?YE^6Q+}AQ<-uit6S-0FNnmq^DF-BFii}A9bX&j`~HtST}r3HIZ#Pq`as8K)@^l(}H-w)Onr!x>9|J2gS084K_Vk?^s4BWHJIN@nc~sRsh#>? z5IYsrNR+YpolAeA&Fq|(Pgagu&vq0G}pNxWC z``P{1uzY^If6*}sUA7Uaw-|bB`2{b$-)M|O&m_37AD$b?gWV&gxWhz_5_x&XaBU_S=%;8cK zOm=#1-yl1A8>6VXfX~4&jMg)$-E27j!o~NaR0N;Z0YhaB$HQaT@K`($#Ii{tQff>$ zFx2#$+ib8LX6P#UGrh zhiu2UBLo3vtHeoSd(ftPG++?e!nj18k)72Y{SilDSC>(HY(Py+&<4iU zCt=ixX^`7STSuLkA7gvY0yU}3`ZZ>>+E+f<5@*&>W-DA1_xBBtK6T6Gi#Gfbf<*ro za(I=2fx=mU|6~`oZMz;zM1D%5`KqOZMT`;gib7hH)Dm;K)RI4S;7Bp-s0Vko`vEF^ zs1n50L4;JABYWSu%r@=}9K8ZF@pv$lrtizDR6Wn91#X+ZNKRVnVop>l^iL1?bk1e8 z3gdy{HXAD0PGV$~xz4JJJsyh`N+Y-}nBD|_;h35cflQ|??bViWjZ*D_aW_g58C8F7 z%@HLGYJ+Goz&3ZeeRp%1<7P(Ya^D|pplX^=5|u-5`)ztww=LLRFu#GpW7C%T|s@- zsey`3s5C~76I@mt|1BDJ;LL?`{XrnE*0Vq-qix6exLS@Vk3AH}40DJWt&>t$6kUXI z1jm%W0y!YHEpC)(6=zYX%}B|hghW*$$Ux+a!mzXvK^NA-%4W9`UE7`OBX#Z_Ud1>X zff4pkC#lfD#>d#a8i6cierFn8C>rMoI25F86c5kZ)Pf9HOFIb2q*abQUbb!2X3BKN zVy>;f71WOM_sJ3vCsP7}ESxR7-V@}?8iT8qKhH8k(uS)6Dzy$TN0E<_tLr8N%A{zM(U7{A59qA zvM_TLmvTp|k0>0F&WaQMBLbADD$-A^BpvwXXvPjn*3qX@RryzH4o7OH@tlwHM?qqz z*YnN&Wmg~~bMWKX{R@~Z5R8QE9(Z!!hx4V@CF?OZi|qEBy0<;wd)z$&!+;O5p&3U} zBGq_Tc;ciwFD((dToQ)#^Ha~xWHWrO-Zl{tW%X>_C4;sZ5GKeHtBp&d(h7k{YHQrC z9hN6~VJ1J{Q>S$?I8iek42D}=hp{OaXZVP5X&1kfc`W51SA@MV6t8+UG2!Ghx$`0i zlQgI-xH1!Ax!`HEXw-kb&BovA3`u<<-7Y3$J0T3=+QJ}`0hM4IEiRGOys<^(DPYs7 z*GnRkSl1X-InN0ZrCZ%Q+nC&}pY|vGH+F?xEkCVyj_p+thZjZGO)snm_#p+O!fUzz zV3wq^Vp7FRI5%6*7uz!t>-!GQxrfBOYeEBg(Z%&e6uC354~6f*rWv!kJ>r@3a*oJs zV<|fRKd9?L=94L!%`Z~cE~v(4+v^uZ`RbP9$6yOdJM^_fqW>oWn&@1vd%&V?&pDDe zOyrOUfhl&Oc?~BE<)jN0R1$4s^X}3E=1?md2=4pvN|0KVnTAI2)%{q?>8Xu596Y0& zbJN?$`_Ruh+M#PR5h>(BW3Gzer$+GOeh|iNTyh-(#%&>(+#`8@hv{MD3;=A4a4L|g{Ix=puSKxYAxpx z>RpK#nNrw)y~q2%-eX8P$B8HTg)z*_uQS#XrgaOwe`*XL)`~dd-=L%))bUCV-taI2 zmUpm;ez$#%Uvlf=13vk>j|7Qou~cGzr{Y6f;1c{yx*hPQzQj_=wf-lJuf7DujuQCzVa?Ol z*_kzAesHK?-nPAZem*f#dm7psdNds|c8xOw1&{2!3Iyt|eem|!JZy#bj}h%{LB*yN zzEy-|g~WGD2$bN1;ZCpcIr#Uqk6@!DT;scU+)g(h1napGc`J?aAX|ZCyH_uN5K>^t ztjA%(p=7&Hq+QJMBb)62!crzl@po!%36_}Z#~M1H2*4c2-xpO&cTVZ5fb2HDzsj`Z zCn3PEJhDcj0TW-{0{c(;3B7GYn~#SS7wvS#bsF?HQB8OYW++vvzw}D8wg52(hF4^C zl5d~Acrv1P>1K?p8nWT>Wzw;yH{gUbasCsWL|vx_uc`fGf$x>-IYCG32h{5_$;Yex;&D+lxqNNp|Dcf@DGm-u43cQ&164Mm09C`CzyM6Bu&`XYn(0 z;0iI_-u<;zMsj6KazM^Mb%uQD2m|;+-7pv!I{<(CyG6%1&7NgzNe=X_=h>_p5!2}2 zong|Jr?Gzpej#0^tW}SQ4%V{i=EY)eAL@dd+;E^_ff}YxoWUyLk|V=rPXDToANZPx zfnuu{o)80;UpiFE-ine_7(&)sV_E#{=+I|bq_P8q1mvjF>f&PuX)zg|NrHF-tbd6O zjuBBSy`$$={cOcU^+<21Y&yP>dJbLl<92duKp(*+Mk2eqqL29Zi}{RuOnsVyXWH#& z1bFQ6572Bnemcr&7?ilihQ(lwZ_)%BwPuQ@XK}O94v8qkx-c5GvjEZsIAgDTE1BRee#e!C1cnnyjY+_Y^~T(n=QJP(;%6CVuoj70^) zxRveCep|l`Jh_kr8Q~|7nXNWHl6lZt3f`LGEfv?$eAa_eOs0?IeGig&^OvXUT@?;S zJwcbW3!ZeO8#cCNcThH)nu3*!a60RZTW$?^PnL9YlM}p!{FO9X^0->Bp2YlHPR@kY z*nh00_H}D|>c7G1tG2oKUl)0{Hbk9Z6;Bo~^_iXaiU&PDW%VH_4-~L&A_``9Ny5@f z&tlS{>2z7ycGz`1lg_e)M(yQBj5bRhE54H%>EIH&JMb5bBus zpxMx`y$3AZniAvD^02q=KGcbLh70|+3D!Qs{b`x&PJ4jOy~ ztbvA*F0xqFl>(HJrj}W-s4OB1K!L>6 znH1`C+BXJ5sTd2@7bUYQ%F0e#H--M~AWoOU-MB?wFzJ_smp_E|FgX*KLvKJa+#-t# zcp;+B-t^NYIKy>m0Lzhg~zponU1s^rib)hyP%Vdodw^~bWp06tQAwU;C#ZH z!tjqt+r(fwe`A{_7sB$*C(#!0 z{u3j!<05?_DI)Vh)mx$Z14Bvr!m4g)ahLOAcS~R#TUMBdUcAdQ32P2SU^%+PnRA;= zh}lqr#f)tHcfpLrldQL)VODYqUSRPc`F1$bUTUGCk&??0#}M#E^>*5M819wiy;{27 za`E)uIN*A^Eu2Yg0~{Lm}J5Ai+Mgvad-iJ45 zN#uUkX!Jhh;DiX&ov40dOD{?vKWmpxqEP&ySxMw(qe4J{BXd~6|QV$$QbeZ#Zc z?>6hUnb<>6pXAL~_p$a3qDg~aaTAGs!(40~;g)fYApa|8=sB8ZTs=Y+Wk*^qw%s$B z#|fE1$6z|p33HTFf2px)Og)oY4_d1V8B`sgRg&D^A1P2oLPu=2Vtuz09eU8Kl(+T2 z(+RmRIVGOqzxwx0$NF9w9LuEjQ$R)5C)KIk;0<$4SV?4OZ>bMfYTZcam2js9D_*<* z$JaZBR~l?xqd~{EZFX#%9otFAwrwXJ+g8W6?G9FK+x*ww=X<_${+n~PZq`M;HKuA- z%`rOHo6aBC;S0SA51sH8_S(`T(oJ_)podKWZ0{Cs;o9lH>laS^xK$4=k1L5FmOtxt zft!fqct->5)pv2qNgm1)D=WQW=YBnT$W2zaQ_PaQrL!&!vrUVH+MT_cNHS2Ry>r^BbFYz7!!=bS^^Eh-oa5kkGhxm2+H;=O_=5BB zIQGu#j@rw5(Ub616Y>xtP#tiAmVYAq@_Ha;CgpTfeGIDT$V8OCfU!c`VXA>1?s(nN zCcHkveLdqq5A3j9=2h!CplAU-G&0deHe0ti%l87lxaV7 zoM5Elio}be-?%ik1v$EhHq9VNo;_XUj>i!USCK54_WL&r|=<9EIO5TlhL8eH5aL{f*& zl5$s}o+BvXCexE!1RkNh6#>4gZ8^S&KcK9eSn)kj$W^JOqE#^)JF=ITtA!owH?i14 zAs9Dpf;tdGAxOnIA5aI)%&L_&#VM~ic-V=+H)>gx8V@<+t{>SC#(;8 z{w=AHd0lgp>e0 z{oX?0MVj*3K+{DOSsN0P5Xt>hTV=iw9@*BiY)QI2VOVv$vBaScCl8%LwZhWM)NE9Y zv!q#QZEs#%72~#I?qT_`tKvvrFU_o0D~yzqNQ4&OEyKgVq=iV`!~S^;BTF8DU@Q4r zS}0D7pU8LnlRLk;@1e>P6ArOilQAu88qzkrXafDgR1qTdv{_r>R2aDNtb37uo`gUs zc!ym0%>KU!#Pi7lKE|i=eyUz%Co+~+Fp$bwbW|M22j=<ATXr*&+HDdnCjK zC347E7eVZ$KpajuCuLD6LSGSGCq8=0?6fTaIVh)^vnf5@@Mu2SK}sH@+7?f{%t1{B zYkYfab8~B}hMPEmRrKz+Frb@ci>uQ;v~fi*+gcwZL=J|ui@;;*Zw^}a;2@Zsrn3Zr zktqq4streo5}y+zg1VgO3RWa?RXIH@=SCWx2i`StU4;e8hXQOGGHEYdB<6E<7$FLS zDppBQZB0W2X2)p-`T`2oFG#UySPI&(%zG{N!TSL*IJ3F|E&VAW@Sb%&!P<4VMfdYZ zGx-ZG4*vAC1m7v*sIOEDBOIDZ7!l}I-DxwL5=#$iKX=mde^$TsRA|B7k#`6D~oc8B_Gg4TK55Nmp!X>wBqO%vEe^^dV7oAVb64!)^ z!NnaS)K+A3KpZ15Yi82!!0zzmK{`mp!2wkYnA?#LV zHf>OWN<-Dr)ldGD&_&hN&9x}ZJ*SlKk^<0#8)yn zmJ#pH(`;K$-w+r#ma5ClretY}SSw#sHOZ==pA}ONZNiq-Vw4I)Wu&@)A<&3Cs>ArT zA3g({n==tf?w{gKFVu5Wo_zni^`%l-CAPGHUt}FcZ05z$mJ^vqF(u0U{_qbU_qQm` zm_KXo@k9u?@d=FWyEy1@&@Pcs*$nYqieaBGIE5mQDN z3*obm`;_eFpCDjFCbha4nD-;`d;7ESuA>7Jk{yOC0%-d0`aVU)qTx0Al*Z3!C=lBc zTu=s{O5?D^kc^ZjWsfh=ch9WUXU*mDM@dHlI>lF;KBuQIH?3luAukZgNh%fddJ+77 z)_t2^^EUy;3aa%&V95{XcDI_3K8YMkYlP~-6u;kQC<{>48rH0$8cZ+kM2VqE%fPc8 zGFbGG?e%>zggzPFd(_729KNv0`v{b(h9>%9@ZzNv0Q<*VsrbJ`yEVArIo2rz%pG2C zNn5OSZ@_)T0z9peO{?(LIC26Wt>#zfrbk3gO#=sIh%Pw-U1f?xl@(uKO{fE%HHo{V zkA(k;^xmBa-gIf5n6ihpSgud}ZgaHN3*v`oW@2q%b_-6#G&%E*puXa(*8Q_b*)WXt zA=>`L&LF|C-a-&oV3Es@CAx&N6tJ`in-94(O6HS*X%8VE=v?4p_g7NfH<@=3UOa5v zj#br-eXkKXVvY0T?tqPS(n9e$jb~!e9Q@dIHnBUzno7UAXAi%hWmnnx$qID)7eHOg zi8F;+%<-qDq?i!DxWxEAQ%t83TUdF$Xh4=fFXQQG50U)0%`X@Z#zVR+dr8eJMI=*K zeJRs#PbH~nY?IwcWmcKj3$D09CPiN&qm`SUiv6tfkWvievE-y0c!@ALMqP_W16C+CSc z#^uX#mwLF_4Yd{7(~&W(;~HJ@aHxfD1Q00TI~F-x7@wjXNa!}4qwHUGI&wbnKiwNf z1a(NgJ7w;iD$N+ymnXGW=3vx`X{Z0Hp*0q=SJ<&cBr`Uu-gN7`6UYZ)^Kft0_kC@$ z1XxX2;)iuqXjDDcp4Zx6*|q9Ov0UZgApIOM{`o!gQi3P8*r+Ou6vMO+;RaXAP`bwy zXfC17C#zxke=C(YGaPfXVl;uy_H_`9tM8(6V zH=nz227TDMv4vy{BCiv^=+p1O?M5ij=N&LMJniJh1jlmpni5YY9VgQm{nJoM4c9&k z(ZeGk72PPBQ=?{rf*-PG{KWjoRqNQ7$9=Knz{Vx>CaDN3sR+t;H)Nxz)=%CpFN)3? zRKU(`x2PMLi4%`g%M|A=A7>GP8`Bif*GK6tNPZGESQYBD!OE2vU=YzXr!>2c;Bdg) zg51{Wjjl&40*!$=9`t>8xVSQ_K_Vx*Ew7?qqh4Rx3b_3C>+IRSbaET{K+y9P;bkzX zPxCkbI0HIOby6!N_VLaRtrn@R4Q-^QhzgzoQA z3SoE@9Zc>{Hq*H6$Y&@9`I61CSw%kf>$HBKZ)NSnG!kyXnL85tK;XjpfAGvY5$8+)ZuD?gTe+ z@h+{c^DZCq1f(Wd%8(59R9A~@kJa&t{7Zq+FB&4Cm_Hg6ITZ}u!xzqg#Sf&Dita$P z9ZnKg8Kn$U!=Pi$FfXCVL{b}22gjcZc4Up;7&xB6rX^;eOcpD_5nbveXK;Z|av0Wi zdH?#_^7wT!gk7~`GNS@m^8dI!Tr@jeV0y@jFVJiDbXwu${MOxe8QjrL2mZU(j|9{E z)qSMXGND1{h7Va6BO`^6XGjx@8n)=&7k=YJ)CJi-ihbpk#>lD^@aW#T8K4b{8ePxQ zPE-53YfOr19jy+2DP+o=;axdKN*tx#Q9%A$BS&FJLR+%BuVE$WtHeV47kQ}7w!+cQ z7?OE1fpGUY$$cCOOZ2dyqVnWY9)mzB0Wm`|GP#t5qOo>gE+59)&lDpkt^Wcna6FM6 z2Uj(*WtcWEM*G68^Ul^XY9*ibw-+MkZ!93FGjNYCS~5fYQv&`V(c{S< zA(3Fr?qdTmBHP+Q5$9^tB7^ILC(&rjG&Ly-4vNQJSPem4t(5k}`q5s5|7vh&y ztM^x6GF0t}qT&8Q$7GsFOwXlPOyVeqGtxxGAQxYG*NlrVYCy1y<<+b>Zc0#R3n;a8 zn$cTX+jOX_(mjtu7JamA{JK9+qkVH+mFH%+MXOwW9Q@Yv?`#K9!jqaD4an<$_FzZL zzwz#GvPo%C_}uIYX)le$uZZ;GX7rncj&_)0F#p5eME{fcSwZwxOLXmig0Yi-6?yI> z$6drE^F#tEjXjUQJyB6lTge!GuCJ#^w-@>&VyrVC952^;!Qd9OIpL z8q;*MQ6je{4_*wxa?0G6IZ;SX%N4H_M-q#+IP+kjU|}{%%Kay=nmW8h*@Kt?xd+4} zW{PWpuM==dF0Bmv?ZuRtz>$bC^PjpPEl^^>x)1VoYdCvpYW9X_hZck~^<1q1ESewtV-gj9}QZwdtG3atqk%I|%J6k(D z7)pRw>X5)WmOaxh6OzglPmKUlG$@dZD|}^4$KML6r4=9rhX~~bB;$a5x9f>pADBlD zmGI#VRSb`^_HYq?91A{^VX9AazPGe8pC9^znii4Dj!}RdUjRn5t61i|m-3rIRV)#+ zYPquZ+!3D_+$^%jZ;AP}#q#^(?eKhMHuCz~`bV2aQkLCy%eT*a%cU2u0tB@TcA-9E z!+Rh6b*XTZ;wnZ6(yD4;tx#vunwy33vZ3FIhGv>c%gByi`a<&CJURVa!MVIQUI*C6 zkaZcS4raS3BX#}6YHS6|LXD@E+(9B8N(8dVV!l5nH-f0COI%Y4^H-TAb|YrT0trt( z9l<7ZgmO97I*IIRh!r4+zlI zZ04B6P+u^~VhCYK>w~}gbsAM_GN(^ZE!W;DACFRSDKfSq&K`nsMHt5@z!WkmvqFP*f?5MHI~@D2OA@~F2qxI zqK+Y!3hwI?i5jH?3^Q8FsGBpkO~TY6AVIY}C0xY8zygm~hEN_2PCWafVZQ&$wmyRU z{^k}MO@WLmDCHSD+R{nPlRI@5EnR%3|FyK%v!T4cn;-Fm^X3n$nIGpN%{!Z3&5Hl` z+S9B$PR!MTx2^h`m!DUcIVY2X|ej*L2aS{29o_w!XToD zV;P9=Y;)dGu~%7ZA_P`YDMC9X*XhFL5Mb~Rn<{57yJB!7ld@+h{chh3J@ael8AxG z`bXabCN*8T1pa`zZV}wlvAo~}$})G;hC_Za zX5Yix8{kUd)dUai+lv{)O80l2=O5O3f3~P!$&fjORu=^}x*&#rvoKrfGvk6N(sEfN zl40Shh7*qKlhS=v@?Vdch!v^(v=L{7hU?5xF8&*1U=f~(E!u)RqZiBg)y2Wshg=fX z?VY?OzO;~@!cD=2)m=yX3!V?wVG~>T$ZUeGb&iW{B6XEUC8##wzORE2aW7;Xnmr#< zhC6}}3PbeD2fN=mpk6-;CD>8+hB;H!^d_94Mv?fUf6bL38$E=_+zEjHv$_lEF!1L9 z@T+xPL-xv$<8ObK2T*L0G>>>HEzncHm8q_JEmsE5dEHL z&g#+E`@CJrBMEtb*ZXDJxTdPs1+eS&eQyD{?)lu1$T9MDk5RW1?G`Yx@?pKY_q|tj zS{0+UAzn?Xm;w9DnnjKzwP#k#q?pY?ytHF`yw6+J$aX7KjfTtvk8E*z_VJk6=b{ts z=ku8Clx?@Dqn=I~q7ZX740agxC^S``uCbO<5zzYd?bpDa`ycV>`T2f0>1f}3`f_fK`-7?)<= z)E3#4k=Wq}fwwPAHF!xg(v?ado zlps>!a%@C391l{{Gs7s%ZaR?>|aCl#OY@%`mpw+m242+P;cWbElGMX-dzVgYq&2*R9K8A2D70LLD+Zz z1tAsDt1uT+8N3Qbbu?TbbRiD18_p%J?shfyT#YXz+rkpIa!dW>^up~pi}P|6!Xq_G z%>$!I(hh@6BV8c@nC$;fw4!$;WD4kM1HY)<-D>o%&4us9r$+Epkne5=Fh4K#r3Dy zo4?k&g!X#RrWTm9da?Hn7^%kA2R}zt4^SID{2~@jdStsK9+!nBHGx&*+1ocFhRIcG ze`(*JL~XMxLScg(9ANlu&-az>rgLt=M>pi$OYXD7e<}{OQ7eCMzng_-#eQbO3Y4OA zVt{&aXq!}dp8P~iuGSTXp!4>>!OtSGN2H#Q3SStRc%LIv>5~mju8ooxiJX-kfC+B( z0}H*bj{hHsEck@^BUCG9lV#m$ngKDsKZ!9M|`^C)4K1R!`1O@$Tjhi>^ zx}USEswykoJFkv_PiL=cuf0nyL|q8suqD%55Adyy$^PqYoz?GbB+L0dm_>*k1+;RS z#tgL;>n%Z!WpP!IXU1xr7;@4X&(nO5WE}-w#WYTNBLxaiN2djJZ$>N3V(sWRjHZHX zIidNnlCP;@DZunKnI>HJVT4^wHGv6*$@!b%FJ(WhS}K;B!TI4nLaR%s5UA0@4b@zihpIi#a-5b$_ZLDVN7*qzIj)Sb8dy_fUpW( zao}-^zX{s#j{%;~bmt&#-2DUy^%;;;j>5&CgZ9GV$@k08ls z;3?MXZDIvWC;Y=t2Zp2=q zw+dgpwcpRfLw~RNFA!mC8){fp{?U{2*-A^%%osJQfB)~;HdVes-wTh6^bJc3*kA~j z52TRC@c4hjo1#>7J9aA@)qr~6C*Cn+Ih?)IBBb3uVG?HPzeIDhE`wG-8}GYen*TNj;ncagc~cjVDd z?w{jP54bSuO?>Bas|2EHvP%BNxgv=<)eCPVIIbuQBmUW}$0MudzU8fFd4L^X-=qI`p5Cv)gSROFrHDY}^DL-V^lcBG+esn82noVC<4?IiI*a$Gibj68 z%k|+ISvyffHcq1RswoHf%Er>hq}a#}EYuM4&M5Hr^Kk7~Rew7FL5Xi2zoa8pSm(;T zq*UzF7eic=Wh__V&-@C3EpoNVEUl~*(~jA1+q4T01fZ3SW58T`!$f$>nX16?orMzZ z8i@Nr%)!}*w${G0ETuSWWR>!?w&7YH(hdJ4`oHm#U74y+PgJkO5|!QS4VvI^pF~zR zlvaVr?UbC;F#oUXB=5hIEr3OVX+^_cUU;mg#5xOY8c0PO9rz`Zfq8S4IZH(|V@(+M z?D?2eQ)?;vgQe0Xua{;MNkv2TQH$d@Rd~U(FS*99XBeeB2^5bRFtWXxLwlz*ug9w~ znHDEU=T%=;Qp#6XQtbjuhbV?Q6K1FE%Kh}kIalxjR2(&J60xMox(G$jV-pOHDm4Nh z_g;CEw};nztM04!Ter^c&8_Y2>$l%jBx3Y)ypbc)rmTZ}&)mSz=EJ(@?C-4Z@mf1V zt^2_o!t>?|Z>!fTzuAJVx@K65A`JHrGe=wt3%Lr}vR|hxBM0Yi4(EnleReo%BZ`Wr zn`a_hWFBJ5Lgny&J)E3e;+nEBui*B%5$K^3=srAZ2sPZ&hHmhgshCJ;j}~}5I20d4 z{EuHlp(O}_h%|n^0(LR+6mQt2u?dw>EK6qiL0~3gf=5C@PUywAzzv>o^NL+s|L|mG z64`?Nt}M{U!{vi`qi)T9QZ;N3ZKB?$ZP-|7jG})=&nCS8+)X*t_xc?-+|{JqjjjFf z3q!S~-J302Q=ZFphbGwSibk=Cb$=LG(_5;}lF^U&_*0wEk%o=Y1jfD+k4&q3dNeb| zh570T3mP7-{{lJj2yCE+SGp);Wv`1KEEIBg3WChIJmHDFVE{BF(!NE$iP!S{qM`l) z!H!@IiH|>$*mTiU(5Y538!jrY>igLuM8rM>p{@p}h%ZhZnGAb1m?jmy5 zpENl*hZpV1(yf?0Bd>x{L_IR?<=eb9gzR*tyxqAY=>Mk8{^-`(+0)(K4%oVWb98Eo z!4V&kxI=wP`P92*toqK8u_PR4m{Y|#+W}VWY8tkH)$dE(cU0;OQCk=2Y`h51_UB- z{3P&V`HUSIvD!1!6a-R+rXQ9gG;z8N^b|c~-s6H1O+x#jhx&V1vq(k|#65)k9&p-q zS*53zbW(7X6`*MRTv$P8RZ~j=(J9*SKGsYki~)HKSKb!7z|~5&LsW+9=3b!{x9tIS zSLqn{`}(jH6c;?VUqUOjFcZ>*&v$94Z3~UaS`TXDon+-aj~FF0aF%ar|I?ldUFZaL z3aU{m4n@I0SttFg0G?xXS)9uXtKX(BH$rQh_266_Dlzy>f-5ve%EAUU>&GyB6kiQB=8m@wgY@n_lFGJ2bF$Juc;l^eUJi zveS-kNfIFlYUaK_iY+F9{+FDb}UuFSOR?wOb| z*xt}L*uJxxe+=$^K3O()dhg)^WB-i(4_vw>Z0rZHch&>zYTfo-Iz>p8`ZenxgLDA#e{v?e*}3 zUjC)Ud#sI(#p$Z&uGhM0=jvK0R-K*}{ML&Q8~a2lu@y1z|{77 zunG(-4+(^`T@V*lO>CZ1M1B|q3afzP>PM9lSrx9&bSeDxsUkYn6yh_Hl#o`1E*cNC zI-xsPR`De#BV!;GAe_OJkx|5OKq?NMU=0^JKt)>&!V2Zr$R8uBQKan1$*E2I{ldvB z2*KH`_IbEi_I*7oD4=Is=x%uu{Crtib5?pD_WkMhdHE($EG}qvT%R0H@i&0{{NW(v zneCu;;9C8Yg*Pf3=YU%o&k`kb=U<9JKdfnt;+WO#3$!3%aj1L~44G5R3`{U9HekvQ zd$E?tqwQo)A{xGxVE1|Sjtbm9P8nMUj09nfxp3adZc_vj;dP9Z;g#KmGDi{bzDSPp3AE=3o9Fk9iH`C1ev5|M^w^Sq0$&(ILz2l_lzb|C?Dw z0Ir_7{sH?P6!Tuw5FQu#ZC9lnWPJuhazgEa4pcD1$weI&*I_G!`r>8sA1y|byvpdA zk+nI1U#M4&QCk8$4_YH%m!h^B0#=9~>~@wzNtnd@8JL~Ubkua`MzAH(HVNh17Psg= z4xC%yt@$e}jGkK~ts>VkFm!IFhov+7$>C4Y6zm@9_67DTJ z!|*%cDGzLEr5A?nC!6Vu$z1gUH=#s6Qw`k;$8@DF9phC27jh*cb0%Nd{E;pSd3ee> zpQ8a2Vg*q+!Jyk}AstSRlBbiDdd5Yn_t#W4Sh8|t)0}YL-4b>1A5_hde)y=E{+ob6 zIB3MqU`6FhN`D*qKBnP5kz$&kH~or`LgV#(y2%>Rz}u$wG@{%f5$&<^VXy8u<}0_( zOSh`iI%UUOM;RycP;Kd2T6TATbtXeb5cc6&7}tyqFyG`VQ2&F}R+{0&DiXboPYa(0 zLD>HRi#~^I6nKA#Y5n#oL?PflxuawlxRBAQ0Cn(sE3BOj$Fo-DZn8t>kQAwp9kaEQ zZb*r^^f`xgVw2exFm}3mGwH3T;i@8hwpt);GjVTq*C=W<=i|~Rns5I8b5$ec`dKRtjJlMRTI-*|mBi1$ z?8cL*jw8&L>-SB&l&zD*$JsJ{cu878Og6VnmPPg$L$LXLQQnju!oXe+ zEU-cBTmVlN|41$11T%W;GK+@M6|KuBF}jS6GUk=Z^#dCMG&WEIYqgXDH?b|#2ODi* zo{~J`R%l-irHkO4L=hfW6VpgRn_6rzdeyC$S_2=8H516pj2M+g8!78I#f54)?NAs`rGYOj2Iu&N=pa z>DT#r+V|`G^-m4FI9C;ps`2?yCiryb&g(aSyB5w?0N@g6&j1AAY~ny$XvIQPSZ2}E z^Yaj}9vrzRozQTOk6RK^X_t@H3?;pRx@7=`4Hh0Z{Xt9EHDASj?1#;3a}Yadu>i;* znHTLELywB?Ic+%{ol8OjiNq{{+~kHAA(OaKe!WfELSL&L9l(^9^ChaHt#k^ zHwX1rzFh%A!U+Cdujp$|N+YY6pc{T<^l&L*$;p3M*n6aV42V?8&EWTF$rlZAhnck3 zw;-nt&3z*@8)_F5(p6rYL;2hAm$+<{=75)@uC^vycNk7CoDArEJ$_OwxdBVW=Vsd~| z>a+=utGLj_X12;g3!0Db&%Hc; z{#5ZH-S!%N2I}M_KqZeGAXEH)9>_=ahEfzrgLy$->{pPhMEU2m$netdQhP)NN;LUy za+L?ak}F^76e2w;P23W@V=BUzj_6lf%9;f=^e59kXhn^or*Cyfjm}f3_klRbE_Mk? z?}jA?L;BI`#>P8#jvxHwCq66GWV!`8k_>5rRmDUABv{ z6oE|ff?O=y7+rerU6RnQEvR`1hUt3A4$U7dC_(0&bS&bKz7gxqf2IjmiKa@tLJwz- zBoy^XS{fsYLpRrg+uyUj-?gb;Gllkm%CWS2Co_!`o3qc)maTv9(|-P~o1f2DU%i4? z|Gd!FhB}c8_4;4Og)n?5<&I8#2#fgRV8vE=3jB%sez*Tbe5nW{MXGNNm4oSsnl>Y6 z`&l4$sStKVbw`hBTjn~v`RiKqFWopLB^yi0^n{7?oJYLywIi|0j)Yms>a)xsdOCg5 zuUhXLIlQrk7=`i^a!KT?L2iVxzbhsUEJxy64_cI_;!%J8*|S3w^;i?jeR;d4mle4( zE%tj|82Epxsj2C$04~+9pER?}d5E0;4H$`4l6S-AU!r7Zxt}&-g(baqfXO{UCN(ZK z3ExFmykTqKfJc-}>!B$^<+>2TXMNo#1%7JBh7VSy){C(OT0$U>n0@T8WrVFNpJWB@B;~9-t43E>yC@{rX(!~M z;LNdBXv62RUDBMis#}t~C8+2U25sP}dlB1YzuT`IBy5@YlO4 zT+iopgk)8792+?YR35cvOCZXOUgiVj^REIQYxqzR+r`%Ff|R%rD_}#n(4|Na8+i2jFj7re@3rzTy|{Pwsh((S}81EAV z6CD4WNAUhsq_E187r@e2hg*R*-=T86P_Y%$Zf_$9b0^N1t@u00m2s6~>(V!R<(>bU zzFKqBB%m`m_O9vTYq%_;Te|WN)x9aK&BmxqPAhj(49V=ORNZ}iD0oP7a)5E*_##Z_ zor-n2Q%Ni6boqO(2ZYT;K^R_$8=a;5doZJkKA)YY_Sbu-zIgN4{Ri+SnHsh`wRiKa z2ot=YxqM6jz7k7;uV#oQTfs6N_A61U>I+wR5GN3l1kGWeqPDpg0PJkJ7D&X^; zWcu`Yg#1{J=huI1KG;Lq`3F)Q1-k)`K^0~l;@L7U^c!4=lfXQvQU&~LMN=%C0du@C zeAH5am9P+A7}Rah0pFis@icCNQEt#2R2(r_Ovd!G;yQAt1{$zZiJxMyv%J5-4{tzp z^S9-99hV2X30NL&h+9wP8`fe74xVmW)XgHgka!^QMAW5B z4+_TaSyplyqbtWmEiTmpwX?(@gznxUSrK7^d?06TeVW9bI8AeHG8N6$1YvN8asgjLcitTlM2{CG=-PzQGV%UeIJaCkMpEifxva zm5HbH_sr@xTU_3SV^v|QLYXO{S1r?yoK!-5qPBlqEQ^$xQzM*!S{6`vOnqYSuAZ9g zs`-}$q)7xMN*K10_oi=MN#t+6Mk&ZS{6VWFwEQK=Ny%-#;MgEXNkA}^lu72{Kwt4X z0d$Nl=%w2DiU(Zc%YZH`3dvO-aK@PD)ks)m@NOgrUgow)e<&rbCNEx{ma=(C6^5un z3xHeaW&;{{XrK#!ob+;#SOMC6V3#2-Gx)+G}r%Z2ol%T^d7ZN0tQ zcCGjqr8eV8YL7}MmmN?e5u-f!;HvV+B-zK8pF1C(CHca!LN&1!NmJhK za}UpsJ>;2#K}c(yt78BJfdi`H6z)7xnbN4q`URKzdRmy1!xsRnjN|&v%gTn2_v>Ce zJIqEctyAh+#6A1VH5P)StrM^E_vs@)70wP+SvX?7?a?~5XzKuH*C^@Hdy*{-QJ5x( zw6WL7u`RaPCT->lVw^=b=v9SI=bR@!BBBZ9!BF|^X^lFv+8Q3IFUs41Db#3Tl4_Apf1YJ844wYSbFw{F(IdDeyQ>F zy=?Q#BGWkc3}LeyZ_}Yh|76z1q*Y)dKZLR-{(B~;R**|r&ynRL4EJAvw%6b{ zmfqC6BivIxE+Kh>f6zLKE=-?22EMrE!0RONS7hLWp^rxx`-OBjy|Xq{)Wj_x#g()9 zTfA1-im1WlMpc=3t(Z|Coi9NHz2n2m+~GDZQOGH)CQ4D6qa=@Ajv+AdTz^$W!{!-a6F4TFg)6v zJ9jx#XW-&!r=o+R-mG@z=|h|UKpn~v#>?Y|egOrJKsxUdcV^%ld?h?MzUAg1VwwJH z|6Hu>RKj(8c?(=Bytl=SvqI3j-(S7o-!ULShGWfYC^@Goa*33jAXvx;fq*goov}Nv zL-V}mIjJ(vzinBrjcXUr@5$KV`Y`agaIaD07p3k+R}rB`gd~x#+)CLNlBm3hc!ejL zkFz6s^fb`tTVuTU$u5g+A;?efzG`ZmoSg05_robUmZ~(+C1Rqz>9f7QoztRj{_d?+ zoODK>tOoSr%i=kD)%-2nR*!27hDiv77>qjgs4C3|RN(IY1b zGX9{iGD|wi;t|gUzP3>Fn7qach17V~qH#MopC8xSfxYz2T^-a#6IXzbf(~9F

pf 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

A@>X7{x$F0y8Nlr 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

lL!;7xw}GpHmL&hnWw>D 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 0); - } - - function _getRandomPositionIdxAndBurnAmount(uint128 _seed) - internal - view - returns (uint128 positionIdx, uint128 burnAmount) - { - positionIdx = _getRandomPositionIdx(_seed, positions.length); - burnAmount = _getRandomBurnAmount(_seed, positions[positionIdx].amount); - } - - // adds all lower and upper ticks to an array such that the liquidity(Net) invariants - // can loop over them - function storeUsedTicks(int24 _tL, int24 _tU) internal { - bool lowerAlreadyUsed = false; - bool upperAlreadyUsed = false; - for (uint8 j = 0; j < usedTicks.length; j++) { - if (usedTicks[j] == _tL) lowerAlreadyUsed = true; - else if (usedTicks[j] == _tU) upperAlreadyUsed = true; - } - if (!lowerAlreadyUsed) usedTicks.push(_tL); - if (!upperAlreadyUsed) usedTicks.push(_tU); - } - - function removePosition(uint256 _posIdx) internal { - positions[_posIdx] = positions[positions.length - 1]; - positions.pop(); - } - - // use the _amount as _seed to create a random but valid position - function forgePosition( - uint128 _seed, - int24 _poolTickSpacing, - uint24 _poolTickCount, - int24 _poolMaxTick - ) internal view returns (int24 tickLower, int24 tickUpper) { - int24 randomTick1 = int24((_seed % uint128(_poolTickCount)) * uint128(_poolTickSpacing)); - - if (_seed % 2 == 0) { - // make tickLower positive - tickLower = randomTick1; - - // tickUpper is somewhere above tickLower - uint24 poolTickCountLeft = uint24((_poolMaxTick - randomTick1) / _poolTickSpacing); - int24 randomTick2 = int24((_seed % uint128(poolTickCountLeft)) * uint128(_poolTickSpacing)); - tickUpper = tickLower + randomTick2; - } else { - // make tickLower negative or zero - tickLower = randomTick1 == 0 ? 0 : -randomTick1; - - uint24 poolTickCountNegativeLeft = uint24((_poolMaxTick - randomTick1) / _poolTickSpacing); - uint24 poolTickCountTotalLeft = poolTickCountNegativeLeft + _poolTickCount; - - uint24 randomIncrement = uint24((_seed % uint128(poolTickCountTotalLeft)) * uint128(_poolTickSpacing)); - - if (randomIncrement <= uint24(tickLower)) { - // tickUpper will also be negative - tickUpper = tickLower + int24(randomIncrement); - } else { - // tickUpper is positive - randomIncrement -= uint24(-tickLower); - tickUpper = tickLower + int24(randomIncrement); - } - } - } - - // - // - // Invariants - // - // - - function check_liquidityNet_invariant() internal { - int128 liquidityNet = 0; - for (uint256 i = 0; i < usedTicks.length; i++) { - (, int128 tickLiquidityNet, , ) = pool.ticks(usedTicks[i]); - int128 result = liquidityNet + tickLiquidityNet; - assert( - (tickLiquidityNet >= 0 && result >= liquidityNet) || (tickLiquidityNet < 0 && result < liquidityNet) - ); - liquidityNet = result; - } - - // prop #20 - assert(liquidityNet == 0); - } - - function check_liquidity_invariant() internal { - (, int24 currentTick, , , , , ) = pool.slot0(); - - int128 liquidity = 0; - for (uint256 i = 0; i < usedTicks.length; i++) { - int24 tick = usedTicks[i]; - - if (tick <= currentTick) { - (, int128 tickLiquidityNet, , ) = pool.ticks(tick); - - int128 result = liquidity + tickLiquidityNet; - assert((tickLiquidityNet >= 0 && result >= liquidity) || (tickLiquidityNet < 0 && result < liquidity)); - liquidity = result; - } - } - - // prop #21 - assert(uint128(liquidity) == pool.liquidity()); - assert(liquidity >= 0); - } - - function check_tick_feegrowth_invariant() internal { - (, int24 currentTick, , , , , ) = pool.slot0(); - - if (currentTick == poolParams.maxTick || currentTick == poolParams.minTick) return; - - int24 tickBelow = currentTick - poolParams.tickSpacing; - int24 tickAbove = currentTick + poolParams.tickSpacing; - - (, , uint256 tB_feeGrowthOutside0X128, uint256 tB_feeGrowthOutside1X128) = pool.ticks(tickBelow); - (, , uint256 tA_feeGrowthOutside0X128, uint256 tA_feeGrowthOutside1X128) = pool.ticks(tickAbove); - - // prop #22 - assert(tB_feeGrowthOutside0X128 + tA_feeGrowthOutside0X128 <= pool.feeGrowthGlobal0X128()); - - // prop #23 - assert(tB_feeGrowthOutside1X128 + tA_feeGrowthOutside1X128 <= pool.feeGrowthGlobal1X128()); - } - - function check_mint_invariants( - int24 _tickLower, - int24 _tickUpper, - UniswapMinter.MinterStats memory bfre, - UniswapMinter.MinterStats memory aftr - ) internal { - (, int24 currentTick, , , , , ) = pool.slot0(); - - // prop #1 - if (currentTick >= _tickLower && currentTick < _tickUpper) { - assert(aftr.liq > bfre.liq); - } else { - assert(aftr.liq == bfre.liq); - } - - // prop #2 - assert(aftr.tL_liqGross > bfre.tL_liqGross); - - // prop #3 - assert(aftr.tU_liqGross > bfre.tU_liqGross); - - // prop #4 - assert(aftr.tL_liqNet > bfre.tL_liqNet); - - // prop #5 - assert(aftr.tU_liqNet < bfre.tU_liqNet); - } - - function check_burn_invariants( - uint128 _burnAmount, - int24 _tickLower, - int24 _tickUpper, - uint128 _newPosAmount, - UniswapMinter.MinterStats memory bfre, - UniswapMinter.MinterStats memory aftr - ) internal { - (, int24 currentTick, , , , , ) = pool.slot0(); - - if (_burnAmount > 0) { - // prop #7 - if (currentTick >= _tickLower && currentTick < _tickUpper) { - assert(aftr.liq < bfre.liq); - } else { - assert(aftr.liq == bfre.liq); - } - } else { - // prop #29 - assert(aftr.liq == bfre.liq); - } - - // prop #8 - assert(aftr.tL_liqGross <= bfre.tL_liqGross); - - // prop #9 - assert(aftr.tU_liqGross <= bfre.tU_liqGross); - - // prop #10 - assert(aftr.tL_liqNet <= bfre.tL_liqNet); - - // prop #11 - assert(aftr.tU_liqNet >= bfre.tU_liqNet); - - bytes32 positionKey = keccak256(abi.encodePacked(address(minter), _tickLower, _tickUpper)); - (uint128 positionLiquidity, , , , ) = pool.positions(positionKey); - - // prop #27 - assert(positionLiquidity == _newPosAmount); - } - - // - // - // Helper to reconstruct the "random" init setup of the pool - // - // - - function viewInitRandomPoolParams(uint128 _seed) public view returns (PoolParams memory _poolParams) { - _poolParams = forgePoolParams(_seed); - } - - function viewMintRandomNewPosition( - uint128 _seed, - int24 _poolTickSpacing, - uint24 _poolTickCount, - int24 _poolMaxTick - ) - public - view - returns ( - int24 tickLower, - int24 tickUpper, - uint128 amount - ) - { - (tickLower, tickUpper) = forgePosition(_seed, _poolTickSpacing, _poolTickCount, _poolMaxTick); - amount = _seed; - } - - function viewBurnRandomPositionIdx(uint128 _seed, uint128 _positionsCount) - public - view - returns (uint128 positionIdx) - { - positionIdx = _getRandomPositionIdx(_seed, _positionsCount); - } - - function viewBurnRandomPositionBurnAmount(uint128 _seed, uint128 _positionAmount) - public - view - returns (uint128 burnAmount) - { - burnAmount = _getRandomBurnAmount(_seed, _positionAmount); - } - - // - // - // Setup functions - // - // - - function forgePoolParams(uint128 _seed) internal view returns (PoolParams memory _poolParams) { - // - // decide on one of the three fees, and corresponding tickSpacing - // - if (_seed % 3 == 0) { - _poolParams.fee = uint24(500); - _poolParams.tickSpacing = int24(10); - } else if (_seed % 3 == 1) { - _poolParams.fee = uint24(3000); - _poolParams.tickSpacing = int24(60); - } else if (_seed % 3 == 2) { - _poolParams.fee = uint24(10000); - _poolParams.tickSpacing = int24(2000); - } - - _poolParams.maxTick = (int24(887272) / _poolParams.tickSpacing) * _poolParams.tickSpacing; - _poolParams.minTick = -_poolParams.maxTick; - _poolParams.tickCount = uint24(_poolParams.maxTick / _poolParams.tickSpacing); - - // - // set the initial price - // - _poolParams.startTick = int24((_seed % uint128(_poolParams.tickCount)) * uint128(_poolParams.tickSpacing)); - if (_seed % 3 == 0) { - // set below 0 - _poolParams.startPrice = TickMath.getSqrtRatioAtTick(-_poolParams.startTick); - } else if (_seed % 3 == 1) { - // set at 0 - _poolParams.startPrice = TickMath.getSqrtRatioAtTick(0); - _poolParams.startTick = 0; - } else if (_seed % 3 == 2) { - // set above 0 - _poolParams.startPrice = TickMath.getSqrtRatioAtTick(_poolParams.startTick); - } - } - - function _init(uint128 _seed) internal { - // - // generate random pool params - // - poolParams = forgePoolParams(_seed); - - // - // deploy the pool - // - uniswap.createPool(poolParams.fee, poolParams.startPrice); - pool = uniswap.pool(); - - // - // set the pool inside the minter and swapper contracts - // - minter.setPool(pool); - - inited = true; - } - - // - // - // Functions to fuzz - // - // - - function test_mint(uint128 _amount) public { - if (!inited) _init(_amount); - (int24 _tL, int24 _tU) = - forgePosition(_amount, poolParams.tickSpacing, poolParams.tickCount, poolParams.maxTick); - - (UniswapMinter.MinterStats memory bfre, UniswapMinter.MinterStats memory aftr) = - minter.doMint(_tL, _tU, _amount); - storeUsedTicks(_tL, _tU); - - check_mint_invariants(_tL, _tU, bfre, aftr); - - check_liquidityNet_invariant(); - check_liquidity_invariant(); - check_tick_feegrowth_invariant(); - - bytes32 positionKey = keccak256(abi.encodePacked(address(minter), _tL, _tU)); - - bool mintingToExistingPos = false; - for (uint256 i = 0; i < positions.length; i++) { - if (positions[i].key == positionKey) { - // minting to an existing position - positions[i].amount += _amount; - mintingToExistingPos = true; - break; - } - } - - if (!mintingToExistingPos) { - positions.push(PoolPosition(_tL, _tU, _amount, positionKey)); - } - } - - function test_burn_partial(uint128 _amount) public { - require(positions.length > 0); - - (uint128 posIdx, uint128 burnAmount) = _getRandomPositionIdxAndBurnAmount(_amount); - // console.log('burn posIdx = %s', posIdx); - // console.log('burn amount = %s', burnAmount); - PoolPosition storage pos = positions[posIdx]; - - UniswapMinter.MinterStats memory bfre; - UniswapMinter.MinterStats memory aftr; - - try minter.doBurn(pos.tickLower, pos.tickUpper, burnAmount) returns ( - UniswapMinter.MinterStats memory bfre_burn, - UniswapMinter.MinterStats memory aftr_burn - ) { - bfre = bfre_burn; - aftr = aftr_burn; - } catch { - // prop #28 - assert(false); - } - - check_burn_invariants(burnAmount, pos.tickLower, pos.tickUpper, pos.amount - burnAmount, bfre, aftr); - - check_liquidityNet_invariant(); - check_liquidity_invariant(); - check_tick_feegrowth_invariant(); - - pos.amount = pos.amount - burnAmount; - } - - function test_burn_full(uint128 _amount) public { - require(positions.length > 0); - - uint128 posIdx = _getRandomPositionIdx(_amount, positions.length); - // console.log('burn posIdx = %s', posIdx); - PoolPosition storage pos = positions[posIdx]; - - UniswapMinter.MinterStats memory bfre; - UniswapMinter.MinterStats memory aftr; - - try minter.doBurn(pos.tickLower, pos.tickUpper, pos.amount) returns ( - UniswapMinter.MinterStats memory bfre_burn, - UniswapMinter.MinterStats memory aftr_burn - ) { - bfre = bfre_burn; - aftr = aftr_burn; - } catch { - // prop #25 - assert(false); - } - - check_burn_invariants(pos.amount, pos.tickLower, pos.tickUpper, 0, bfre, aftr); - - check_liquidityNet_invariant(); - check_liquidity_invariant(); - check_tick_feegrowth_invariant(); - - removePosition(posIdx); - } - - function test_burn_zero(uint128 _amount) public { - require(positions.length > 0); - - uint128 posIdx = _getRandomPositionIdx(_amount, positions.length); - // console.log('burn posIdx = %s', posIdx); - PoolPosition storage pos = positions[posIdx]; - - UniswapMinter.MinterStats memory bfre; - UniswapMinter.MinterStats memory aftr; - - try minter.doBurn(pos.tickLower, pos.tickUpper, 0) returns ( - UniswapMinter.MinterStats memory bfre_burn, - UniswapMinter.MinterStats memory aftr_burn - ) { - bfre = bfre_burn; - aftr = aftr_burn; - } catch { - // prop #26 - assert(false); - } - - check_burn_invariants(0, pos.tickLower, pos.tickUpper, pos.amount, bfre, aftr); - - check_liquidityNet_invariant(); - check_liquidity_invariant(); - check_tick_feegrowth_invariant(); - } -} diff --git a/lib/v3-core/audits/tob/contracts/crytic/echidna/E2E_swap.config.yaml b/lib/v3-core/audits/tob/contracts/crytic/echidna/E2E_swap.config.yaml deleted file mode 100644 index b2c5c6d..0000000 --- a/lib/v3-core/audits/tob/contracts/crytic/echidna/E2E_swap.config.yaml +++ /dev/null @@ -1,10 +0,0 @@ -checkAsserts: true -coverage: true -codeSize: 0x60000 -corpusDir: echidna_e2e_swap_corpus -seqLen: 10 -testLimit: 100000 -timeout: 3600 # 1 hour - -# blacklist -filterFunctions: ['E2E_swap.viewRandomInit(uint128)'] diff --git a/lib/v3-core/audits/tob/contracts/crytic/echidna/E2E_swap.sol b/lib/v3-core/audits/tob/contracts/crytic/echidna/E2E_swap.sol deleted file mode 100644 index 289ccb9..0000000 --- a/lib/v3-core/audits/tob/contracts/crytic/echidna/E2E_swap.sol +++ /dev/null @@ -1,487 +0,0 @@ -pragma solidity =0.7.6; -pragma abicoder v2; - -import './Setup.sol'; -import '../../../../../contracts/test/TestERC20.sol'; -import '../../../../../contracts/libraries/TickMath.sol'; -import '../../../../../contracts/UniswapV3Pool.sol'; - -// import 'hardhat/console.sol'; - -contract E2E_swap { - SetupTokens tokens; - SetupUniswap uniswap; - - UniswapV3Pool pool; - - TestERC20 token0; - TestERC20 token1; - - UniswapMinter minter; - UniswapSwapper swapper; - - int24[] usedTicks; - bool inited; - - struct PoolParams { - uint24 fee; - int24 tickSpacing; - int24 minTick; - int24 maxTick; - uint24 tickCount; - uint160 startPrice; - int24 startTick; - } - - struct PoolPositions { - int24[] tickLowers; - int24[] tickUppers; - uint128[] amounts; - } - - PoolParams poolParams; - PoolPositions poolPositions; - - constructor() public { - tokens = new SetupTokens(); - token0 = tokens.token0(); - token1 = tokens.token1(); - - uniswap = new SetupUniswap(token0, token1); - - minter = new UniswapMinter(token0, token1); - swapper = new UniswapSwapper(token0, token1); - - tokens.mintTo(0, address(swapper), 1e9 ether); - tokens.mintTo(1, address(swapper), 1e9 ether); - - tokens.mintTo(0, address(minter), 1e10 ether); - tokens.mintTo(1, address(minter), 1e10 ether); - } - - // - // - // Helpers - // - // - - function get_random_zeroForOne_priceLimit(int256 _amountSpecified) - internal - view - returns (uint160 sqrtPriceLimitX96) - { - // help echidna a bit by calculating a valid sqrtPriceLimitX96 using the amount as random seed - (uint160 currentPrice, , , , , , ) = pool.slot0(); - uint160 minimumPrice = TickMath.MIN_SQRT_RATIO; - sqrtPriceLimitX96 = - minimumPrice + - uint160( - (uint256(_amountSpecified > 0 ? _amountSpecified : -_amountSpecified) % (currentPrice - minimumPrice)) - ); - } - - function get_random_oneForZero_priceLimit(int256 _amountSpecified) - internal - view - returns (uint160 sqrtPriceLimitX96) - { - // help echidna a bit by calculating a valid sqrtPriceLimitX96 using the amount as random seed - (uint160 currentPrice, , , , , , ) = pool.slot0(); - uint160 maximumPrice = TickMath.MAX_SQRT_RATIO; - sqrtPriceLimitX96 = - currentPrice + - uint160( - (uint256(_amountSpecified > 0 ? _amountSpecified : -_amountSpecified) % (maximumPrice - currentPrice)) - ); - } - - // - // - // Invariants - // - // - - function check_liquidityNet_invariant() internal { - int128 liquidityNet = 0; - for (uint256 i = 0; i < usedTicks.length; i++) { - (, int128 tickLiquidityNet, , ) = pool.ticks(usedTicks[i]); - int128 result = liquidityNet + tickLiquidityNet; - assert( - (tickLiquidityNet >= 0 && result >= liquidityNet) || (tickLiquidityNet < 0 && result < liquidityNet) - ); - liquidityNet = result; - } - - // prop #20 - assert(liquidityNet == 0); - } - - function check_liquidity_invariant() internal { - (, int24 currentTick, , , , , ) = pool.slot0(); - int128 liquidity = 0; - for (uint256 i = 0; i < usedTicks.length; i++) { - int24 tick = usedTicks[i]; - if (tick <= currentTick) { - (, int128 tickLiquidityNet, , ) = pool.ticks(tick); - int128 result = liquidity + tickLiquidityNet; - assert((tickLiquidityNet >= 0 && result >= liquidity) || (tickLiquidityNet < 0 && result < liquidity)); - liquidity = result; - } - } - - // prop #21 - assert(uint128(liquidity) == pool.liquidity()); - assert(liquidity >= 0); - } - - function check_tick_feegrowth_invariant() internal { - (, int24 currentTick, , , , , ) = pool.slot0(); - - if (currentTick == poolParams.maxTick || currentTick == poolParams.minTick) return; - - int24 tickBelow = currentTick - poolParams.tickSpacing; - int24 tickAbove = currentTick + poolParams.tickSpacing; - - (, , uint256 tB_feeGrowthOutside0X128, uint256 tB_feeGrowthOutside1X128) = pool.ticks(tickBelow); - (, , uint256 tA_feeGrowthOutside0X128, uint256 tA_feeGrowthOutside1X128) = pool.ticks(tickAbove); - - // prop #22 - assert(tB_feeGrowthOutside0X128 + tA_feeGrowthOutside0X128 <= pool.feeGrowthGlobal0X128()); - - // prop #23 - assert(tB_feeGrowthOutside1X128 + tA_feeGrowthOutside1X128 <= pool.feeGrowthGlobal1X128()); - } - - function check_swap_invariants( - int24 tick_bfre, - int24 tick_aftr, - uint128 liq_bfre, - uint128 liq_aftr, - uint256 bal_sell_bfre, - uint256 bal_sell_aftr, - uint256 bal_buy_bfre, - uint256 bal_buy_aftr, - uint256 feegrowth_sell_bfre, - uint256 feegrowth_sell_aftr, - uint256 feegrowth_buy_bfre, - uint256 feegrowth_buy_aftr - ) internal { - // prop #17 - if (tick_bfre == tick_aftr) { - assert(liq_bfre == liq_aftr); - } - - // prop #13 + #15 - assert(feegrowth_sell_bfre <= feegrowth_sell_aftr); - - // prop #14 + #16 - assert(feegrowth_buy_bfre == feegrowth_buy_aftr); - - // prop #18 + #19 - if (bal_sell_bfre == bal_sell_aftr) { - assert(bal_buy_bfre == bal_buy_aftr); - } - } - - // - // - // Helper to reconstruct the "random" init setup of the pool - // - // - - function viewRandomInit(uint128 _seed) - public - view - returns (PoolParams memory poolParams, PoolPositions memory poolPositions) - { - poolParams = forgePoolParams(_seed); - poolPositions = forgePoolPositions(_seed, poolParams.tickSpacing, poolParams.tickCount, poolParams.maxTick); - } - - // - // - // Setup functions - // - // - - function forgePoolParams(uint128 _seed) internal view returns (PoolParams memory poolParams) { - // - // decide on one of the three fees, and corresponding tickSpacing - // - if (_seed % 3 == 0) { - poolParams.fee = uint24(500); - poolParams.tickSpacing = int24(10); - } else if (_seed % 3 == 1) { - poolParams.fee = uint24(3000); - poolParams.tickSpacing = int24(60); - } else if (_seed % 3 == 2) { - poolParams.fee = uint24(10000); - poolParams.tickSpacing = int24(2000); - } - - poolParams.maxTick = (int24(887272) / poolParams.tickSpacing) * poolParams.tickSpacing; - poolParams.minTick = -poolParams.maxTick; - poolParams.tickCount = uint24(poolParams.maxTick / poolParams.tickSpacing); - - // - // set the initial price - // - poolParams.startTick = int24((_seed % uint128(poolParams.tickCount)) * uint128(poolParams.tickSpacing)); - if (_seed % 3 == 0) { - // set below 0 - poolParams.startPrice = TickMath.getSqrtRatioAtTick(-poolParams.startTick); - } else if (_seed % 3 == 1) { - // set at 0 - poolParams.startPrice = TickMath.getSqrtRatioAtTick(0); - poolParams.startTick = 0; - } else if (_seed % 3 == 2) { - // set above 0 - poolParams.startPrice = TickMath.getSqrtRatioAtTick(poolParams.startTick); - } - } - - function forgePoolPositions( - uint128 _seed, - int24 _poolTickSpacing, - uint24 _poolTickCount, - int24 _poolMaxTick - ) internal view returns (PoolPositions memory poolPositions_) { - // between 1 and 10 (inclusive) positions - uint8 positionsCount = uint8(_seed % 10) + 1; - - poolPositions_.tickLowers = new int24[](positionsCount); - poolPositions_.tickUppers = new int24[](positionsCount); - poolPositions_.amounts = new uint128[](positionsCount); - - for (uint8 i = 0; i < positionsCount; i++) { - int24 tickLower; - int24 tickUpper; - uint128 amount; - - int24 randomTick1 = int24((_seed % uint128(_poolTickCount)) * uint128(_poolTickSpacing)); - - if (_seed % 2 == 0) { - // make tickLower positive - tickLower = randomTick1; - - // tickUpper is somewhere above tickLower - uint24 poolTickCountLeft = uint24((_poolMaxTick - randomTick1) / _poolTickSpacing); - int24 randomTick2 = int24((_seed % uint128(poolTickCountLeft)) * uint128(_poolTickSpacing)); - tickUpper = tickLower + randomTick2; - } else { - // make tickLower negative or zero - tickLower = randomTick1 == 0 ? 0 : -randomTick1; - - uint24 poolTickCountNegativeLeft = uint24((_poolMaxTick - randomTick1) / _poolTickSpacing); - uint24 poolTickCountTotalLeft = poolTickCountNegativeLeft + _poolTickCount; - - uint24 randomIncrement = uint24((_seed % uint128(poolTickCountTotalLeft)) * uint128(_poolTickSpacing)); - - if (randomIncrement <= uint24(tickLower)) { - // tickUpper will also be negative - tickUpper = tickLower + int24(randomIncrement); - } else { - // tickUpper is positive - randomIncrement -= uint24(-tickLower); - tickUpper = tickLower + int24(randomIncrement); - } - } - - amount = uint128(1e8 ether); - - poolPositions_.tickLowers[i] = tickLower; - poolPositions_.tickUppers[i] = tickUpper; - poolPositions_.amounts[i] = amount; - - _seed += uint128(tickLower); - } - } - - function _init(uint128 _seed) internal { - // - // generate random pool params - // - poolParams = forgePoolParams(_seed); - - // - // deploy the pool - // - uniswap.createPool(poolParams.fee, poolParams.startPrice); - pool = uniswap.pool(); - - // - // set the pool inside the minter and swapper contracts - // - minter.setPool(pool); - swapper.setPool(pool); - - // - // generate random positions - // - poolPositions = forgePoolPositions(_seed, poolParams.tickSpacing, poolParams.tickCount, poolParams.maxTick); - - // - // create the positions - // - for (uint8 i = 0; i < poolPositions.tickLowers.length; i++) { - int24 tickLower = poolPositions.tickLowers[i]; - int24 tickUpper = poolPositions.tickUppers[i]; - uint128 amount = poolPositions.amounts[i]; - - minter.doMint(tickLower, tickUpper, amount); - - bool lowerAlreadyUsed = false; - bool upperAlreadyUsed = false; - for (uint8 j = 0; j < usedTicks.length; j++) { - if (usedTicks[j] == tickLower) lowerAlreadyUsed = true; - else if (usedTicks[j] == tickUpper) upperAlreadyUsed = true; - } - if (!lowerAlreadyUsed) usedTicks.push(tickLower); - if (!upperAlreadyUsed) usedTicks.push(tickUpper); - } - - inited = true; - } - - // - // - // Functions to fuzz - // - // - - function test_swap_exactIn_zeroForOne(uint128 _amount) public { - require(_amount != 0); - - if (!inited) _init(_amount); - - require(token0.balanceOf(address(swapper)) >= uint256(_amount)); - int256 _amountSpecified = int256(_amount); - - uint160 sqrtPriceLimitX96 = get_random_zeroForOne_priceLimit(_amount); - // console.log('sqrtPriceLimitX96 = %s', sqrtPriceLimitX96); - - (UniswapSwapper.SwapperStats memory bfre, UniswapSwapper.SwapperStats memory aftr) = - swapper.doSwap(true, _amountSpecified, sqrtPriceLimitX96); - - check_swap_invariants( - bfre.tick, - aftr.tick, - bfre.liq, - aftr.liq, - bfre.bal0, - aftr.bal0, - bfre.bal1, - aftr.bal1, - bfre.feeGrowthGlobal0X128, - aftr.feeGrowthGlobal0X128, - bfre.feeGrowthGlobal1X128, - aftr.feeGrowthGlobal1X128 - ); - - check_liquidityNet_invariant(); - check_liquidity_invariant(); - check_tick_feegrowth_invariant(); - } - - function test_swap_exactIn_oneForZero(uint128 _amount) public { - require(_amount != 0); - - if (!inited) _init(_amount); - - require(token1.balanceOf(address(swapper)) >= uint256(_amount)); - int256 _amountSpecified = int256(_amount); - - uint160 sqrtPriceLimitX96 = get_random_oneForZero_priceLimit(_amount); - // console.log('sqrtPriceLimitX96 = %s', sqrtPriceLimitX96); - - (UniswapSwapper.SwapperStats memory bfre, UniswapSwapper.SwapperStats memory aftr) = - swapper.doSwap(false, _amountSpecified, sqrtPriceLimitX96); - - check_swap_invariants( - bfre.tick, - aftr.tick, - bfre.liq, - aftr.liq, - bfre.bal1, - aftr.bal1, - bfre.bal0, - aftr.bal0, - bfre.feeGrowthGlobal1X128, - aftr.feeGrowthGlobal1X128, - bfre.feeGrowthGlobal0X128, - aftr.feeGrowthGlobal0X128 - ); - - check_liquidityNet_invariant(); - check_liquidity_invariant(); - check_tick_feegrowth_invariant(); - } - - function test_swap_exactOut_zeroForOne(uint128 _amount) public { - require(_amount != 0); - - if (!inited) _init(_amount); - - require(token0.balanceOf(address(swapper)) > 0); - int256 _amountSpecified = -int256(_amount); - - uint160 sqrtPriceLimitX96 = get_random_zeroForOne_priceLimit(_amount); - // console.log('sqrtPriceLimitX96 = %s', sqrtPriceLimitX96); - - (UniswapSwapper.SwapperStats memory bfre, UniswapSwapper.SwapperStats memory aftr) = - swapper.doSwap(true, _amountSpecified, sqrtPriceLimitX96); - - check_swap_invariants( - bfre.tick, - aftr.tick, - bfre.liq, - aftr.liq, - bfre.bal0, - aftr.bal0, - bfre.bal1, - aftr.bal1, - bfre.feeGrowthGlobal0X128, - aftr.feeGrowthGlobal0X128, - bfre.feeGrowthGlobal1X128, - aftr.feeGrowthGlobal1X128 - ); - - check_liquidityNet_invariant(); - check_liquidity_invariant(); - check_tick_feegrowth_invariant(); - } - - function test_swap_exactOut_oneForZero(uint128 _amount) public { - require(_amount != 0); - - if (!inited) _init(_amount); - - require(token0.balanceOf(address(swapper)) > 0); - int256 _amountSpecified = -int256(_amount); - - uint160 sqrtPriceLimitX96 = get_random_oneForZero_priceLimit(_amount); - // console.log('sqrtPriceLimitX96 = %s', sqrtPriceLimitX96); - - (UniswapSwapper.SwapperStats memory bfre, UniswapSwapper.SwapperStats memory aftr) = - swapper.doSwap(false, _amountSpecified, sqrtPriceLimitX96); - - check_swap_invariants( - bfre.tick, - aftr.tick, - bfre.liq, - aftr.liq, - bfre.bal1, - aftr.bal1, - bfre.bal0, - aftr.bal0, - bfre.feeGrowthGlobal1X128, - aftr.feeGrowthGlobal1X128, - bfre.feeGrowthGlobal0X128, - aftr.feeGrowthGlobal0X128 - ); - - check_liquidityNet_invariant(); - check_liquidity_invariant(); - check_tick_feegrowth_invariant(); - } -} diff --git a/lib/v3-core/audits/tob/contracts/crytic/echidna/Other.config.yaml b/lib/v3-core/audits/tob/contracts/crytic/echidna/Other.config.yaml deleted file mode 100644 index 0bad147..0000000 --- a/lib/v3-core/audits/tob/contracts/crytic/echidna/Other.config.yaml +++ /dev/null @@ -1,7 +0,0 @@ -checkAsserts: true -coverage: true -codeSize: 0x60000 -corpusDir: echidna_other_corpus -seqLen: 1000 -testLimit: 100000 -timeout: 3600 # 1 hour diff --git a/lib/v3-core/audits/tob/contracts/crytic/echidna/Other.sol b/lib/v3-core/audits/tob/contracts/crytic/echidna/Other.sol deleted file mode 100644 index 5832e8b..0000000 --- a/lib/v3-core/audits/tob/contracts/crytic/echidna/Other.sol +++ /dev/null @@ -1,21 +0,0 @@ -pragma solidity =0.7.6; - -import '../../../../../contracts/libraries/SqrtPriceMath.sol'; -import '../../../../../contracts/libraries/TickMath.sol'; - -contract Other { - // prop #30 - function test_getNextSqrtPriceFromInAndOutput( - uint160 sqrtPX96, - uint128 liquidity, - uint256 amount, - bool add - ) public { - require(sqrtPX96 >= TickMath.MIN_SQRT_RATIO && sqrtPX96 < TickMath.MAX_SQRT_RATIO); - require(liquidity < 3121856577256316178563069792952001939); // max liquidity per tick - uint256 next_sqrt = SqrtPriceMath.getNextSqrtPriceFromInput(sqrtPX96, liquidity, amount, add); - assert(next_sqrt >= TickMath.MIN_SQRT_RATIO && next_sqrt < TickMath.MAX_SQRT_RATIO); - next_sqrt = SqrtPriceMath.getNextSqrtPriceFromOutput(sqrtPX96, liquidity, amount, add); - assert(next_sqrt >= TickMath.MIN_SQRT_RATIO && next_sqrt < TickMath.MAX_SQRT_RATIO); - } -} diff --git a/lib/v3-core/audits/tob/contracts/crytic/echidna/Setup.sol b/lib/v3-core/audits/tob/contracts/crytic/echidna/Setup.sol deleted file mode 100644 index 922838c..0000000 --- a/lib/v3-core/audits/tob/contracts/crytic/echidna/Setup.sol +++ /dev/null @@ -1,205 +0,0 @@ -pragma solidity =0.7.6; -pragma abicoder v2; - -import '../../../../../contracts/test/TestERC20.sol'; -import '../../../../../contracts/UniswapV3Pool.sol'; -import '../../../../../contracts/UniswapV3Factory.sol'; - -contract SetupToken { - TestERC20 public token; - - constructor() public { - // this contract will receive the total supply of 100 tokens - token = new TestERC20(1e12 ether); - } - - function mintTo(address _recipient, uint256 _amount) public { - token.transfer(_recipient, _amount); - } -} - -contract SetupTokens { - SetupToken tokenSetup0; - SetupToken tokenSetup1; - - TestERC20 public token0; - TestERC20 public token1; - - constructor() public { - // create the token wrappers - tokenSetup0 = new SetupToken(); - tokenSetup1 = new SetupToken(); - - // switch them around so that token0's address is lower than token1's - // since this is what the uniswap factory will do when you create the pool - if (address(tokenSetup0.token()) > address(tokenSetup1.token())) { - (tokenSetup0, tokenSetup1) = (tokenSetup1, tokenSetup0); - } - - // save the erc20 tokens - token0 = tokenSetup0.token(); - token1 = tokenSetup1.token(); - } - - // mint either token0 or token1 to a chosen account - function mintTo( - uint256 _tokenIdx, - address _recipient, - uint256 _amount - ) public { - require(_tokenIdx == 0 || _tokenIdx == 1, 'invalid token idx'); - if (_tokenIdx == 0) tokenSetup0.mintTo(_recipient, _amount); - if (_tokenIdx == 1) tokenSetup1.mintTo(_recipient, _amount); - } -} - -contract SetupUniswap { - UniswapV3Pool public pool; - TestERC20 token0; - TestERC20 token1; - - // will create the following enabled fees and corresponding tickSpacing - // fee 500 + tickSpacing 10 - // fee 3000 + tickSpacing 60 - // fee 10000 + tickSpacing 200 - UniswapV3Factory factory; - - constructor(TestERC20 _token0, TestERC20 _token1) public { - factory = new UniswapV3Factory(); - token0 = _token0; - token1 = _token1; - } - - function createPool(uint24 _fee, uint160 _startPrice) public { - pool = UniswapV3Pool(factory.createPool(address(token0), address(token1), _fee)); - pool.initialize(_startPrice); - } -} - -contract UniswapMinter { - UniswapV3Pool pool; - TestERC20 token0; - TestERC20 token1; - - struct MinterStats { - uint128 liq; - uint128 tL_liqGross; - int128 tL_liqNet; - uint128 tU_liqGross; - int128 tU_liqNet; - } - - constructor(TestERC20 _token0, TestERC20 _token1) public { - token0 = _token0; - token1 = _token1; - } - - function setPool(UniswapV3Pool _pool) public { - pool = _pool; - } - - function uniswapV3MintCallback( - uint256 amount0Owed, - uint256 amount1Owed, - bytes calldata data - ) external { - if (amount0Owed > 0) token0.transfer(address(pool), amount0Owed); - if (amount1Owed > 0) token1.transfer(address(pool), amount1Owed); - } - - function getTickLiquidityVars(int24 _tickLower, int24 _tickUpper) - internal - view - returns ( - uint128, - int128, - uint128, - int128 - ) - { - (uint128 tL_liqGross, int128 tL_liqNet, , ) = pool.ticks(_tickLower); - (uint128 tU_liqGross, int128 tU_liqNet, , ) = pool.ticks(_tickUpper); - return (tL_liqGross, tL_liqNet, tU_liqGross, tU_liqNet); - } - - function getStats(int24 _tickLower, int24 _tickUpper) internal view returns (MinterStats memory stats) { - (uint128 tL_lg, int128 tL_ln, uint128 tU_lg, int128 tU_ln) = getTickLiquidityVars(_tickLower, _tickUpper); - return MinterStats(pool.liquidity(), tL_lg, tL_ln, tU_lg, tU_ln); - } - - function doMint( - int24 _tickLower, - int24 _tickUpper, - uint128 _amount - ) public returns (MinterStats memory bfre, MinterStats memory aftr) { - bfre = getStats(_tickLower, _tickUpper); - pool.mint(address(this), _tickLower, _tickUpper, _amount, new bytes(0)); - aftr = getStats(_tickLower, _tickUpper); - } - - function doBurn( - int24 _tickLower, - int24 _tickUpper, - uint128 _amount - ) public returns (MinterStats memory bfre, MinterStats memory aftr) { - bfre = getStats(_tickLower, _tickUpper); - pool.burn(_tickLower, _tickUpper, _amount); - aftr = getStats(_tickLower, _tickUpper); - } -} - -contract UniswapSwapper { - UniswapV3Pool pool; - TestERC20 token0; - TestERC20 token1; - - struct SwapperStats { - uint128 liq; - uint256 feeGrowthGlobal0X128; - uint256 feeGrowthGlobal1X128; - uint256 bal0; - uint256 bal1; - int24 tick; - } - - constructor(TestERC20 _token0, TestERC20 _token1) public { - token0 = _token0; - token1 = _token1; - } - - function setPool(UniswapV3Pool _pool) public { - pool = _pool; - } - - function uniswapV3SwapCallback( - int256 amount0Delta, - int256 amount1Delta, - bytes calldata data - ) external { - if (amount0Delta > 0) token0.transfer(address(pool), uint256(amount0Delta)); - if (amount1Delta > 0) token1.transfer(address(pool), uint256(amount1Delta)); - } - - function getStats() internal view returns (SwapperStats memory stats) { - (, int24 currentTick, , , , , ) = pool.slot0(); - return - SwapperStats( - pool.liquidity(), - pool.feeGrowthGlobal0X128(), - pool.feeGrowthGlobal1X128(), - token0.balanceOf(address(this)), - token1.balanceOf(address(this)), - currentTick - ); - } - - function doSwap( - bool _zeroForOne, - int256 _amountSpecified, - uint160 _sqrtPriceLimitX96 - ) public returns (SwapperStats memory bfre, SwapperStats memory aftr) { - bfre = getStats(); - pool.swap(address(this), _zeroForOne, _amountSpecified, _sqrtPriceLimitX96, new bytes(0)); - aftr = getStats(); - } -} diff --git a/lib/v3-core/audits/tob/contracts/crytic/manticore/001.sol b/lib/v3-core/audits/tob/contracts/crytic/manticore/001.sol deleted file mode 100644 index dada7c4..0000000 --- a/lib/v3-core/audits/tob/contracts/crytic/manticore/001.sol +++ /dev/null @@ -1,11 +0,0 @@ -import '../../../../../contracts/libraries/BitMath.sol'; - -contract VerifyBitMathMsb { - function verify(uint256 x) external { - uint256 msb = BitMath.mostSignificantBit(x); - - bool property = x >= 2**msb && (msb == 255 || x < 2**(msb + 1)); - - require(!property); - } -} diff --git a/lib/v3-core/audits/tob/contracts/crytic/manticore/002.sol b/lib/v3-core/audits/tob/contracts/crytic/manticore/002.sol deleted file mode 100644 index 055bc92..0000000 --- a/lib/v3-core/audits/tob/contracts/crytic/manticore/002.sol +++ /dev/null @@ -1,12 +0,0 @@ -import '../../../../../contracts/libraries/BitMath.sol'; - -contract VerifyBitMathLsb { - function verify(uint256 x) external { - uint256 lsb = BitMath.leastSignificantBit(x); - - // (x & 2**leastSignificantBit(x)) != 0 and (x & (2**(leastSignificantBit(x)) - 1)) == 0) - bool property = ((x & (2**lsb)) != 0) && ((x & (2**(lsb - 1))) == 0); - - require(!property); - } -} diff --git a/lib/v3-core/audits/tob/contracts/crytic/manticore/003.sol b/lib/v3-core/audits/tob/contracts/crytic/manticore/003.sol deleted file mode 100644 index 99cee9f..0000000 --- a/lib/v3-core/audits/tob/contracts/crytic/manticore/003.sol +++ /dev/null @@ -1,9 +0,0 @@ -import '../../../../../contracts/libraries/LiquidityMath.sol'; - -contract VerifyLiquidityMathAddDelta { - function verify(uint128 x, int128 y) external { - uint256 z = LiquidityMath.addDelta(x, y); - - require(z != x + uint128(y)); - } -} diff --git a/lib/v3-core/bug-bounty.md b/lib/v3-core/bug-bounty.md deleted file mode 100644 index f01c4c6..0000000 --- a/lib/v3-core/bug-bounty.md +++ /dev/null @@ -1,76 +0,0 @@ -# Uniswap V3 Bug Bounty - -## Overview - -Starting on March 23rd, 2021, the [uniswap-v3-core](https://github.com/Uniswap/uniswap-v3-core) repository is subject to the Uniswap V3 Bug Bounty (the “Program”) to incentivize responsible bug disclosure. - -We are limiting the scope of the Program to critical and high severity bugs, and are offering a reward of up to $500,000. Happy hunting! - -## Scope - -The scope of the Program is limited to bugs that result in the draining of contract funds. - -The following are not within the scope of the Program: - -- Any contract located under [contracts/test](./contracts/test). -- Bugs in any third party contract or platform that interacts with Uniswap V3. -- Vulnerabilities already reported and/or discovered in contracts built by third parties on Uniswap V3. -- Any already-reported bugs. - -Vulnerabilities contingent upon the occurrence of any of the following also are outside the scope of this Program: - -- Frontend bugs -- DDOS attacks -- Spamming -- Phishing -- Automated tools (Github Actions, AWS, etc.) -- Compromise or misuse of third party systems or services - -## Assumptions - -Uniswap V3 was developed with the following assumptions, and thus any bug must also adhere to the following assumptions -to be eligible for the bug bounty: - -- The total supply of any token does not exceed 2128 - 1, i.e. `type(uint128).max`. -- The `transfer` and `transferFrom` methods of any token strictly decrease the balance of the token sender by the transfer amount and increases the balance of token recipient by the transfer amount, i.e. fee on transfer tokens are excluded. -- The token balance of an address can only change due to a call to `transfer` by the sender or `transferFrom` by an approved address, i.e. rebase tokens and interest bearing tokens are excluded. - -## Rewards - -Rewards will be allocated based on the severity of the bug disclosed and will be evaluated and rewarded at the discretion of the Uniswap Labs team. For critical bugs that lead to any loss of LP funds, rewards of up to $500,000 will be granted. Lower severity bugs will be rewarded at the discretion of the team. In addition, all vulnerabilities disclosed prior to the mainnet launch date will be subject to receive higher rewards. - -## Disclosure - -Any vulnerability or bug discovered must be reported only to the following email: [security@uniswap.org](mailto:security@uniswap.org). - -The vulnerability must not be disclosed publicly or to any other person, entity or email address before Uniswap Labs has been notified, has fixed the issue, and has granted permission for public disclosure. In addition, disclosure must be made within 24 hours following discovery of the vulnerability. - -A detailed report of a vulnerability increases the likelihood of a reward and may increase the reward amount. Please provide as much information about the vulnerability as possible, including: - -- The conditions on which reproducing the bug is contingent. -- The steps needed to reproduce the bug or, preferably, a proof of concept. -- The potential implications of the vulnerability being abused. - -Anyone who reports a unique, previously-unreported vulnerability that results in a change to the code or a configuration change and who keeps such vulnerability confidential until it has been resolved by our engineers will be recognized publicly for their contribution if they so choose. - -## Eligibility - -To be eligible for a reward under this Program, you must: - -- Discover a previously unreported, non-public vulnerability that would result in a loss of and/or lock on any ERC-20 token on Uniswap V3 (but not on any third party platform interacting with Uniswap V3) and that is within the scope of this Program. Vulnerabilities must be distinct from the issues covered in the Trail of Bits or ABDK audits. -- Be the first to disclose the unique vulnerability to [security@uniswap.org](mailto:security@uniswap.org), in compliance with the disclosure requirements above. If similar vulnerabilities are reported within the same 24 hour period, rewards will be split at the discretion of Uniswap Labs. -- Provide sufficient information to enable our engineers to reproduce and fix the vulnerability. -- Not engage in any unlawful conduct when disclosing the bug, including through threats, demands, or any other coercive tactics. -- Not exploit the vulnerability in any way, including through making it public or by obtaining a profit (other than a reward under this Program). -- Make a good faith effort to avoid privacy violations, destruction of data, interruption or degradation of Uniswap V3. -- Submit only one vulnerability per submission, unless you need to chain vulnerabilities to provide impact regarding any of the vulnerabilities. -- Not submit a vulnerability caused by an underlying issue that is the same as an issue on which a reward has been paid under this Program. -- Not be one of our current or former employees, vendors, or contractors or an employee of any of those vendors or contractors. -- Not be subject to US sanctions or reside in a US-embargoed country. -- Be at least 18 years of age or, if younger, submit your vulnerability with the consent of your parent or guardian. - -## Other Terms - -By submitting your report, you grant Uniswap Labs any and all rights, including intellectual property rights, needed to validate, mitigate, and disclose the vulnerability. All reward decisions, including eligibility for and amounts of the rewards and the manner in which such rewards will be paid, are made at our sole discretion. - -The terms and conditions of this Program may be altered at any time. diff --git a/lib/v3-core/contracts/NoDelegateCall.sol b/lib/v3-core/contracts/NoDelegateCall.sol deleted file mode 100644 index 5411979..0000000 --- a/lib/v3-core/contracts/NoDelegateCall.sol +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity =0.7.6; - -/// @title Prevents delegatecall to a contract -/// @notice Base contract that provides a modifier for preventing delegatecall to methods in a child contract -abstract contract NoDelegateCall { - /// @dev The original address of this contract - address private immutable original; - - constructor() { - // Immutables are computed in the init code of the contract, and then inlined into the deployed bytecode. - // In other words, this variable won't change when it's checked at runtime. - original = address(this); - } - - /// @dev Private method is used instead of inlining into modifier because modifiers are copied into each method, - /// and the use of immutable means the address bytes are copied in every place the modifier is used. - function checkNotDelegateCall() private view { - require(address(this) == original); - } - - /// @notice Prevents delegatecall into the modified method - modifier noDelegateCall() { - checkNotDelegateCall(); - _; - } -} diff --git a/lib/v3-core/contracts/UniswapV3Factory.sol b/lib/v3-core/contracts/UniswapV3Factory.sol deleted file mode 100644 index 3553ce5..0000000 --- a/lib/v3-core/contracts/UniswapV3Factory.sol +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity =0.7.6; - -import './interfaces/IUniswapV3Factory.sol'; - -import './UniswapV3PoolDeployer.sol'; -import './NoDelegateCall.sol'; - -import './UniswapV3Pool.sol'; - -/// @title Canonical Uniswap V3 factory -/// @notice Deploys Uniswap V3 pools and manages ownership and control over pool protocol fees -contract UniswapV3Factory is IUniswapV3Factory, UniswapV3PoolDeployer, NoDelegateCall { - /// @inheritdoc IUniswapV3Factory - address public override owner; - - /// @inheritdoc IUniswapV3Factory - mapping(uint24 => int24) public override feeAmountTickSpacing; - /// @inheritdoc IUniswapV3Factory - mapping(address => mapping(address => mapping(uint24 => address))) public override getPool; - - constructor() { - owner = msg.sender; - emit OwnerChanged(address(0), msg.sender); - - feeAmountTickSpacing[500] = 10; - emit FeeAmountEnabled(500, 10); - feeAmountTickSpacing[3000] = 60; - emit FeeAmountEnabled(3000, 60); - feeAmountTickSpacing[10000] = 200; - emit FeeAmountEnabled(10000, 200); - } - - /// @inheritdoc IUniswapV3Factory - function createPool( - address tokenA, - address tokenB, - uint24 fee - ) external override noDelegateCall returns (address pool) { - require(tokenA != tokenB); - (address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); - require(token0 != address(0)); - int24 tickSpacing = feeAmountTickSpacing[fee]; - require(tickSpacing != 0); - require(getPool[token0][token1][fee] == address(0)); - pool = deploy(address(this), token0, token1, fee, tickSpacing); - getPool[token0][token1][fee] = pool; - // populate mapping in the reverse direction, deliberate choice to avoid the cost of comparing addresses - getPool[token1][token0][fee] = pool; - emit PoolCreated(token0, token1, fee, tickSpacing, pool); - } - - /// @inheritdoc IUniswapV3Factory - function setOwner(address _owner) external override { - require(msg.sender == owner); - emit OwnerChanged(owner, _owner); - owner = _owner; - } - - /// @inheritdoc IUniswapV3Factory - function enableFeeAmount(uint24 fee, int24 tickSpacing) public override { - require(msg.sender == owner); - require(fee < 1000000); - // tick spacing is capped at 16384 to prevent the situation where tickSpacing is so large that - // TickBitmap#nextInitializedTickWithinOneWord overflows int24 container from a valid tick - // 16384 ticks represents a >5x price change with ticks of 1 bips - require(tickSpacing > 0 && tickSpacing < 16384); - require(feeAmountTickSpacing[fee] == 0); - - feeAmountTickSpacing[fee] = tickSpacing; - emit FeeAmountEnabled(fee, tickSpacing); - } -} diff --git a/lib/v3-core/contracts/UniswapV3Pool.sol b/lib/v3-core/contracts/UniswapV3Pool.sol deleted file mode 100644 index 9e09821..0000000 --- a/lib/v3-core/contracts/UniswapV3Pool.sol +++ /dev/null @@ -1,869 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity =0.7.6; - -import './interfaces/IUniswapV3Pool.sol'; - -import './NoDelegateCall.sol'; - -import './libraries/LowGasSafeMath.sol'; -import './libraries/SafeCast.sol'; -import './libraries/Tick.sol'; -import './libraries/TickBitmap.sol'; -import './libraries/Position.sol'; -import './libraries/Oracle.sol'; - -import './libraries/FullMath.sol'; -import './libraries/FixedPoint128.sol'; -import './libraries/TransferHelper.sol'; -import './libraries/TickMath.sol'; -import './libraries/LiquidityMath.sol'; -import './libraries/SqrtPriceMath.sol'; -import './libraries/SwapMath.sol'; - -import './interfaces/IUniswapV3PoolDeployer.sol'; -import './interfaces/IUniswapV3Factory.sol'; -import './interfaces/IERC20Minimal.sol'; -import './interfaces/callback/IUniswapV3MintCallback.sol'; -import './interfaces/callback/IUniswapV3SwapCallback.sol'; -import './interfaces/callback/IUniswapV3FlashCallback.sol'; - -contract UniswapV3Pool is IUniswapV3Pool, NoDelegateCall { - using LowGasSafeMath for uint256; - using LowGasSafeMath for int256; - using SafeCast for uint256; - using SafeCast for int256; - using Tick for mapping(int24 => Tick.Info); - using TickBitmap for mapping(int16 => uint256); - using Position for mapping(bytes32 => Position.Info); - using Position for Position.Info; - using Oracle for Oracle.Observation[65535]; - - /// @inheritdoc IUniswapV3PoolImmutables - address public immutable override factory; - /// @inheritdoc IUniswapV3PoolImmutables - address public immutable override token0; - /// @inheritdoc IUniswapV3PoolImmutables - address public immutable override token1; - /// @inheritdoc IUniswapV3PoolImmutables - uint24 public immutable override fee; - - /// @inheritdoc IUniswapV3PoolImmutables - int24 public immutable override tickSpacing; - - /// @inheritdoc IUniswapV3PoolImmutables - uint128 public immutable override maxLiquidityPerTick; - - struct Slot0 { - // the current price - uint160 sqrtPriceX96; - // the current tick - int24 tick; - // the most-recently updated index of the observations array - uint16 observationIndex; - // the current maximum number of observations that are being stored - uint16 observationCardinality; - // the next maximum number of observations to store, triggered in observations.write - uint16 observationCardinalityNext; - // the current protocol fee as a percentage of the swap fee taken on withdrawal - // represented as an integer denominator (1/x)% - uint8 feeProtocol; - // whether the pool is locked - bool unlocked; - } - /// @inheritdoc IUniswapV3PoolState - Slot0 public override slot0; - - /// @inheritdoc IUniswapV3PoolState - uint256 public override feeGrowthGlobal0X128; - /// @inheritdoc IUniswapV3PoolState - uint256 public override feeGrowthGlobal1X128; - - // accumulated protocol fees in token0/token1 units - struct ProtocolFees { - uint128 token0; - uint128 token1; - } - /// @inheritdoc IUniswapV3PoolState - ProtocolFees public override protocolFees; - - /// @inheritdoc IUniswapV3PoolState - uint128 public override liquidity; - - /// @inheritdoc IUniswapV3PoolState - mapping(int24 => Tick.Info) public override ticks; - /// @inheritdoc IUniswapV3PoolState - mapping(int16 => uint256) public override tickBitmap; - /// @inheritdoc IUniswapV3PoolState - mapping(bytes32 => Position.Info) public override positions; - /// @inheritdoc IUniswapV3PoolState - Oracle.Observation[65535] public override observations; - - /// @dev Mutually exclusive reentrancy protection into the pool to/from a method. This method also prevents entrance - /// to a function before the pool is initialized. The reentrancy guard is required throughout the contract because - /// we use balance checks to determine the payment status of interactions such as mint, swap and flash. - modifier lock() { - require(slot0.unlocked, 'LOK'); - slot0.unlocked = false; - _; - slot0.unlocked = true; - } - - /// @dev Prevents calling a function from anyone except the address returned by IUniswapV3Factory#owner() - modifier onlyFactoryOwner() { - require(msg.sender == IUniswapV3Factory(factory).owner()); - _; - } - - constructor() { - int24 _tickSpacing; - (factory, token0, token1, fee, _tickSpacing) = IUniswapV3PoolDeployer(msg.sender).parameters(); - tickSpacing = _tickSpacing; - - maxLiquidityPerTick = Tick.tickSpacingToMaxLiquidityPerTick(_tickSpacing); - } - - /// @dev Common checks for valid tick inputs. - function checkTicks(int24 tickLower, int24 tickUpper) private pure { - require(tickLower < tickUpper, 'TLU'); - require(tickLower >= TickMath.MIN_TICK, 'TLM'); - require(tickUpper <= TickMath.MAX_TICK, 'TUM'); - } - - /// @dev Returns the block timestamp truncated to 32 bits, i.e. mod 2**32. This method is overridden in tests. - function _blockTimestamp() internal view virtual returns (uint32) { - return uint32(block.timestamp); // truncation is desired - } - - /// @dev Get the pool's balance of token0 - /// @dev This function is gas optimized to avoid a redundant extcodesize check in addition to the returndatasize - /// check - function balance0() private view returns (uint256) { - (bool success, bytes memory data) = - token0.staticcall(abi.encodeWithSelector(IERC20Minimal.balanceOf.selector, address(this))); - require(success && data.length >= 32); - return abi.decode(data, (uint256)); - } - - /// @dev Get the pool's balance of token1 - /// @dev This function is gas optimized to avoid a redundant extcodesize check in addition to the returndatasize - /// check - function balance1() private view returns (uint256) { - (bool success, bytes memory data) = - token1.staticcall(abi.encodeWithSelector(IERC20Minimal.balanceOf.selector, address(this))); - require(success && data.length >= 32); - return abi.decode(data, (uint256)); - } - - /// @inheritdoc IUniswapV3PoolDerivedState - function snapshotCumulativesInside(int24 tickLower, int24 tickUpper) - external - view - override - noDelegateCall - returns ( - int56 tickCumulativeInside, - uint160 secondsPerLiquidityInsideX128, - uint32 secondsInside - ) - { - checkTicks(tickLower, tickUpper); - - int56 tickCumulativeLower; - int56 tickCumulativeUpper; - uint160 secondsPerLiquidityOutsideLowerX128; - uint160 secondsPerLiquidityOutsideUpperX128; - uint32 secondsOutsideLower; - uint32 secondsOutsideUpper; - - { - Tick.Info storage lower = ticks[tickLower]; - Tick.Info storage upper = ticks[tickUpper]; - bool initializedLower; - (tickCumulativeLower, secondsPerLiquidityOutsideLowerX128, secondsOutsideLower, initializedLower) = ( - lower.tickCumulativeOutside, - lower.secondsPerLiquidityOutsideX128, - lower.secondsOutside, - lower.initialized - ); - require(initializedLower); - - bool initializedUpper; - (tickCumulativeUpper, secondsPerLiquidityOutsideUpperX128, secondsOutsideUpper, initializedUpper) = ( - upper.tickCumulativeOutside, - upper.secondsPerLiquidityOutsideX128, - upper.secondsOutside, - upper.initialized - ); - require(initializedUpper); - } - - Slot0 memory _slot0 = slot0; - - if (_slot0.tick < tickLower) { - return ( - tickCumulativeLower - tickCumulativeUpper, - secondsPerLiquidityOutsideLowerX128 - secondsPerLiquidityOutsideUpperX128, - secondsOutsideLower - secondsOutsideUpper - ); - } else if (_slot0.tick < tickUpper) { - uint32 time = _blockTimestamp(); - (int56 tickCumulative, uint160 secondsPerLiquidityCumulativeX128) = - observations.observeSingle( - time, - 0, - _slot0.tick, - _slot0.observationIndex, - liquidity, - _slot0.observationCardinality - ); - return ( - tickCumulative - tickCumulativeLower - tickCumulativeUpper, - secondsPerLiquidityCumulativeX128 - - secondsPerLiquidityOutsideLowerX128 - - secondsPerLiquidityOutsideUpperX128, - time - secondsOutsideLower - secondsOutsideUpper - ); - } else { - return ( - tickCumulativeUpper - tickCumulativeLower, - secondsPerLiquidityOutsideUpperX128 - secondsPerLiquidityOutsideLowerX128, - secondsOutsideUpper - secondsOutsideLower - ); - } - } - - /// @inheritdoc IUniswapV3PoolDerivedState - function observe(uint32[] calldata secondsAgos) - external - view - override - noDelegateCall - returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s) - { - return - observations.observe( - _blockTimestamp(), - secondsAgos, - slot0.tick, - slot0.observationIndex, - liquidity, - slot0.observationCardinality - ); - } - - /// @inheritdoc IUniswapV3PoolActions - function increaseObservationCardinalityNext(uint16 observationCardinalityNext) - external - override - lock - noDelegateCall - { - uint16 observationCardinalityNextOld = slot0.observationCardinalityNext; // for the event - uint16 observationCardinalityNextNew = - observations.grow(observationCardinalityNextOld, observationCardinalityNext); - slot0.observationCardinalityNext = observationCardinalityNextNew; - if (observationCardinalityNextOld != observationCardinalityNextNew) - emit IncreaseObservationCardinalityNext(observationCardinalityNextOld, observationCardinalityNextNew); - } - - /// @inheritdoc IUniswapV3PoolActions - /// @dev not locked because it initializes unlocked - function initialize(uint160 sqrtPriceX96) external override { - require(slot0.sqrtPriceX96 == 0, 'AI'); - - int24 tick = TickMath.getTickAtSqrtRatio(sqrtPriceX96); - - (uint16 cardinality, uint16 cardinalityNext) = observations.initialize(_blockTimestamp()); - - slot0 = Slot0({ - sqrtPriceX96: sqrtPriceX96, - tick: tick, - observationIndex: 0, - observationCardinality: cardinality, - observationCardinalityNext: cardinalityNext, - feeProtocol: 0, - unlocked: true - }); - - emit Initialize(sqrtPriceX96, tick); - } - - struct ModifyPositionParams { - // the address that owns the position - address owner; - // the lower and upper tick of the position - int24 tickLower; - int24 tickUpper; - // any change in liquidity - int128 liquidityDelta; - } - - /// @dev Effect some changes to a position - /// @param params the position details and the change to the position's liquidity to effect - /// @return position a storage pointer referencing the position with the given owner and tick range - /// @return amount0 the amount of token0 owed to the pool, negative if the pool should pay the recipient - /// @return amount1 the amount of token1 owed to the pool, negative if the pool should pay the recipient - function _modifyPosition(ModifyPositionParams memory params) - private - noDelegateCall - returns ( - Position.Info storage position, - int256 amount0, - int256 amount1 - ) - { - checkTicks(params.tickLower, params.tickUpper); - - Slot0 memory _slot0 = slot0; // SLOAD for gas optimization - - position = _updatePosition( - params.owner, - params.tickLower, - params.tickUpper, - params.liquidityDelta, - _slot0.tick - ); - - if (params.liquidityDelta != 0) { - if (_slot0.tick < params.tickLower) { - // current tick is below the passed range; liquidity can only become in range by crossing from left to - // right, when we'll need _more_ token0 (it's becoming more valuable) so user must provide it - amount0 = SqrtPriceMath.getAmount0Delta( - TickMath.getSqrtRatioAtTick(params.tickLower), - TickMath.getSqrtRatioAtTick(params.tickUpper), - params.liquidityDelta - ); - } else if (_slot0.tick < params.tickUpper) { - // current tick is inside the passed range - uint128 liquidityBefore = liquidity; // SLOAD for gas optimization - - // write an oracle entry - (slot0.observationIndex, slot0.observationCardinality) = observations.write( - _slot0.observationIndex, - _blockTimestamp(), - _slot0.tick, - liquidityBefore, - _slot0.observationCardinality, - _slot0.observationCardinalityNext - ); - - amount0 = SqrtPriceMath.getAmount0Delta( - _slot0.sqrtPriceX96, - TickMath.getSqrtRatioAtTick(params.tickUpper), - params.liquidityDelta - ); - amount1 = SqrtPriceMath.getAmount1Delta( - TickMath.getSqrtRatioAtTick(params.tickLower), - _slot0.sqrtPriceX96, - params.liquidityDelta - ); - - liquidity = LiquidityMath.addDelta(liquidityBefore, params.liquidityDelta); - } else { - // current tick is above the passed range; liquidity can only become in range by crossing from right to - // left, when we'll need _more_ token1 (it's becoming more valuable) so user must provide it - amount1 = SqrtPriceMath.getAmount1Delta( - TickMath.getSqrtRatioAtTick(params.tickLower), - TickMath.getSqrtRatioAtTick(params.tickUpper), - params.liquidityDelta - ); - } - } - } - - /// @dev Gets and updates a position with the given liquidity delta - /// @param owner the owner of the position - /// @param tickLower the lower tick of the position's tick range - /// @param tickUpper the upper tick of the position's tick range - /// @param tick the current tick, passed to avoid sloads - function _updatePosition( - address owner, - int24 tickLower, - int24 tickUpper, - int128 liquidityDelta, - int24 tick - ) private returns (Position.Info storage position) { - position = positions.get(owner, tickLower, tickUpper); - - uint256 _feeGrowthGlobal0X128 = feeGrowthGlobal0X128; // SLOAD for gas optimization - uint256 _feeGrowthGlobal1X128 = feeGrowthGlobal1X128; // SLOAD for gas optimization - - // if we need to update the ticks, do it - bool flippedLower; - bool flippedUpper; - if (liquidityDelta != 0) { - uint32 time = _blockTimestamp(); - (int56 tickCumulative, uint160 secondsPerLiquidityCumulativeX128) = - observations.observeSingle( - time, - 0, - slot0.tick, - slot0.observationIndex, - liquidity, - slot0.observationCardinality - ); - - flippedLower = ticks.update( - tickLower, - tick, - liquidityDelta, - _feeGrowthGlobal0X128, - _feeGrowthGlobal1X128, - secondsPerLiquidityCumulativeX128, - tickCumulative, - time, - false, - maxLiquidityPerTick - ); - flippedUpper = ticks.update( - tickUpper, - tick, - liquidityDelta, - _feeGrowthGlobal0X128, - _feeGrowthGlobal1X128, - secondsPerLiquidityCumulativeX128, - tickCumulative, - time, - true, - maxLiquidityPerTick - ); - - if (flippedLower) { - tickBitmap.flipTick(tickLower, tickSpacing); - } - if (flippedUpper) { - tickBitmap.flipTick(tickUpper, tickSpacing); - } - } - - (uint256 feeGrowthInside0X128, uint256 feeGrowthInside1X128) = - ticks.getFeeGrowthInside(tickLower, tickUpper, tick, _feeGrowthGlobal0X128, _feeGrowthGlobal1X128); - - position.update(liquidityDelta, feeGrowthInside0X128, feeGrowthInside1X128); - - // clear any tick data that is no longer needed - if (liquidityDelta < 0) { - if (flippedLower) { - ticks.clear(tickLower); - } - if (flippedUpper) { - ticks.clear(tickUpper); - } - } - } - - /// @inheritdoc IUniswapV3PoolActions - /// @dev noDelegateCall is applied indirectly via _modifyPosition - function mint( - address recipient, - int24 tickLower, - int24 tickUpper, - uint128 amount, - bytes calldata data - ) external override lock returns (uint256 amount0, uint256 amount1) { - require(amount > 0); - (, int256 amount0Int, int256 amount1Int) = - _modifyPosition( - ModifyPositionParams({ - owner: recipient, - tickLower: tickLower, - tickUpper: tickUpper, - liquidityDelta: int256(amount).toInt128() - }) - ); - - amount0 = uint256(amount0Int); - amount1 = uint256(amount1Int); - - uint256 balance0Before; - uint256 balance1Before; - if (amount0 > 0) balance0Before = balance0(); - if (amount1 > 0) balance1Before = balance1(); - IUniswapV3MintCallback(msg.sender).uniswapV3MintCallback(amount0, amount1, data); - if (amount0 > 0) require(balance0Before.add(amount0) <= balance0(), 'M0'); - if (amount1 > 0) require(balance1Before.add(amount1) <= balance1(), 'M1'); - - emit Mint(msg.sender, recipient, tickLower, tickUpper, amount, amount0, amount1); - } - - /// @inheritdoc IUniswapV3PoolActions - function collect( - address recipient, - int24 tickLower, - int24 tickUpper, - uint128 amount0Requested, - uint128 amount1Requested - ) external override lock returns (uint128 amount0, uint128 amount1) { - // we don't need to checkTicks here, because invalid positions will never have non-zero tokensOwed{0,1} - Position.Info storage position = positions.get(msg.sender, tickLower, tickUpper); - - amount0 = amount0Requested > position.tokensOwed0 ? position.tokensOwed0 : amount0Requested; - amount1 = amount1Requested > position.tokensOwed1 ? position.tokensOwed1 : amount1Requested; - - if (amount0 > 0) { - position.tokensOwed0 -= amount0; - TransferHelper.safeTransfer(token0, recipient, amount0); - } - if (amount1 > 0) { - position.tokensOwed1 -= amount1; - TransferHelper.safeTransfer(token1, recipient, amount1); - } - - emit Collect(msg.sender, recipient, tickLower, tickUpper, amount0, amount1); - } - - /// @inheritdoc IUniswapV3PoolActions - /// @dev noDelegateCall is applied indirectly via _modifyPosition - function burn( - int24 tickLower, - int24 tickUpper, - uint128 amount - ) external override lock returns (uint256 amount0, uint256 amount1) { - (Position.Info storage position, int256 amount0Int, int256 amount1Int) = - _modifyPosition( - ModifyPositionParams({ - owner: msg.sender, - tickLower: tickLower, - tickUpper: tickUpper, - liquidityDelta: -int256(amount).toInt128() - }) - ); - - amount0 = uint256(-amount0Int); - amount1 = uint256(-amount1Int); - - if (amount0 > 0 || amount1 > 0) { - (position.tokensOwed0, position.tokensOwed1) = ( - position.tokensOwed0 + uint128(amount0), - position.tokensOwed1 + uint128(amount1) - ); - } - - emit Burn(msg.sender, tickLower, tickUpper, amount, amount0, amount1); - } - - struct SwapCache { - // the protocol fee for the input token - uint8 feeProtocol; - // liquidity at the beginning of the swap - uint128 liquidityStart; - // the timestamp of the current block - uint32 blockTimestamp; - // the current value of the tick accumulator, computed only if we cross an initialized tick - int56 tickCumulative; - // the current value of seconds per liquidity accumulator, computed only if we cross an initialized tick - uint160 secondsPerLiquidityCumulativeX128; - // whether we've computed and cached the above two accumulators - bool computedLatestObservation; - } - - // the top level state of the swap, the results of which are recorded in storage at the end - struct SwapState { - // the amount remaining to be swapped in/out of the input/output asset - int256 amountSpecifiedRemaining; - // the amount already swapped out/in of the output/input asset - int256 amountCalculated; - // current sqrt(price) - uint160 sqrtPriceX96; - // the tick associated with the current price - int24 tick; - // the global fee growth of the input token - uint256 feeGrowthGlobalX128; - // amount of input token paid as protocol fee - uint128 protocolFee; - // the current liquidity in range - uint128 liquidity; - } - - struct StepComputations { - // the price at the beginning of the step - uint160 sqrtPriceStartX96; - // the next tick to swap to from the current tick in the swap direction - int24 tickNext; - // whether tickNext is initialized or not - bool initialized; - // sqrt(price) for the next tick (1/0) - uint160 sqrtPriceNextX96; - // how much is being swapped in in this step - uint256 amountIn; - // how much is being swapped out - uint256 amountOut; - // how much fee is being paid in - uint256 feeAmount; - } - - /// @inheritdoc IUniswapV3PoolActions - function swap( - address recipient, - bool zeroForOne, - int256 amountSpecified, - uint160 sqrtPriceLimitX96, - bytes calldata data - ) external override noDelegateCall returns (int256 amount0, int256 amount1) { - require(amountSpecified != 0, 'AS'); - - Slot0 memory slot0Start = slot0; - - require(slot0Start.unlocked, 'LOK'); - require( - zeroForOne - ? sqrtPriceLimitX96 < slot0Start.sqrtPriceX96 && sqrtPriceLimitX96 > TickMath.MIN_SQRT_RATIO - : sqrtPriceLimitX96 > slot0Start.sqrtPriceX96 && sqrtPriceLimitX96 < TickMath.MAX_SQRT_RATIO, - 'SPL' - ); - - slot0.unlocked = false; - - SwapCache memory cache = - SwapCache({ - liquidityStart: liquidity, - blockTimestamp: _blockTimestamp(), - feeProtocol: zeroForOne ? (slot0Start.feeProtocol % 16) : (slot0Start.feeProtocol >> 4), - secondsPerLiquidityCumulativeX128: 0, - tickCumulative: 0, - computedLatestObservation: false - }); - - bool exactInput = amountSpecified > 0; - - SwapState memory state = - SwapState({ - amountSpecifiedRemaining: amountSpecified, - amountCalculated: 0, - sqrtPriceX96: slot0Start.sqrtPriceX96, - tick: slot0Start.tick, - feeGrowthGlobalX128: zeroForOne ? feeGrowthGlobal0X128 : feeGrowthGlobal1X128, - protocolFee: 0, - liquidity: cache.liquidityStart - }); - - // continue swapping as long as we haven't used the entire input/output and haven't reached the price limit - while (state.amountSpecifiedRemaining != 0 && state.sqrtPriceX96 != sqrtPriceLimitX96) { - StepComputations memory step; - - step.sqrtPriceStartX96 = state.sqrtPriceX96; - - (step.tickNext, step.initialized) = tickBitmap.nextInitializedTickWithinOneWord( - state.tick, - tickSpacing, - zeroForOne - ); - - // ensure that we do not overshoot the min/max tick, as the tick bitmap is not aware of these bounds - if (step.tickNext < TickMath.MIN_TICK) { - step.tickNext = TickMath.MIN_TICK; - } else if (step.tickNext > TickMath.MAX_TICK) { - step.tickNext = TickMath.MAX_TICK; - } - - // get the price for the next tick - step.sqrtPriceNextX96 = TickMath.getSqrtRatioAtTick(step.tickNext); - - // compute values to swap to the target tick, price limit, or point where input/output amount is exhausted - (state.sqrtPriceX96, step.amountIn, step.amountOut, step.feeAmount) = SwapMath.computeSwapStep( - state.sqrtPriceX96, - (zeroForOne ? step.sqrtPriceNextX96 < sqrtPriceLimitX96 : step.sqrtPriceNextX96 > sqrtPriceLimitX96) - ? sqrtPriceLimitX96 - : step.sqrtPriceNextX96, - state.liquidity, - state.amountSpecifiedRemaining, - fee - ); - - if (exactInput) { - state.amountSpecifiedRemaining -= (step.amountIn + step.feeAmount).toInt256(); - state.amountCalculated = state.amountCalculated.sub(step.amountOut.toInt256()); - } else { - state.amountSpecifiedRemaining += step.amountOut.toInt256(); - state.amountCalculated = state.amountCalculated.add((step.amountIn + step.feeAmount).toInt256()); - } - - // if the protocol fee is on, calculate how much is owed, decrement feeAmount, and increment protocolFee - if (cache.feeProtocol > 0) { - uint256 delta = step.feeAmount / cache.feeProtocol; - step.feeAmount -= delta; - state.protocolFee += uint128(delta); - } - - // update global fee tracker - if (state.liquidity > 0) - state.feeGrowthGlobalX128 += FullMath.mulDiv(step.feeAmount, FixedPoint128.Q128, state.liquidity); - - // shift tick if we reached the next price - if (state.sqrtPriceX96 == step.sqrtPriceNextX96) { - // if the tick is initialized, run the tick transition - if (step.initialized) { - // check for the placeholder value, which we replace with the actual value the first time the swap - // crosses an initialized tick - if (!cache.computedLatestObservation) { - (cache.tickCumulative, cache.secondsPerLiquidityCumulativeX128) = observations.observeSingle( - cache.blockTimestamp, - 0, - slot0Start.tick, - slot0Start.observationIndex, - cache.liquidityStart, - slot0Start.observationCardinality - ); - cache.computedLatestObservation = true; - } - int128 liquidityNet = - ticks.cross( - step.tickNext, - (zeroForOne ? state.feeGrowthGlobalX128 : feeGrowthGlobal0X128), - (zeroForOne ? feeGrowthGlobal1X128 : state.feeGrowthGlobalX128), - cache.secondsPerLiquidityCumulativeX128, - cache.tickCumulative, - cache.blockTimestamp - ); - // if we're moving leftward, we interpret liquidityNet as the opposite sign - // safe because liquidityNet cannot be type(int128).min - if (zeroForOne) liquidityNet = -liquidityNet; - - state.liquidity = LiquidityMath.addDelta(state.liquidity, liquidityNet); - } - - state.tick = zeroForOne ? step.tickNext - 1 : step.tickNext; - } else if (state.sqrtPriceX96 != step.sqrtPriceStartX96) { - // recompute unless we're on a lower tick boundary (i.e. already transitioned ticks), and haven't moved - state.tick = TickMath.getTickAtSqrtRatio(state.sqrtPriceX96); - } - } - - // update tick and write an oracle entry if the tick change - if (state.tick != slot0Start.tick) { - (uint16 observationIndex, uint16 observationCardinality) = - observations.write( - slot0Start.observationIndex, - cache.blockTimestamp, - slot0Start.tick, - cache.liquidityStart, - slot0Start.observationCardinality, - slot0Start.observationCardinalityNext - ); - (slot0.sqrtPriceX96, slot0.tick, slot0.observationIndex, slot0.observationCardinality) = ( - state.sqrtPriceX96, - state.tick, - observationIndex, - observationCardinality - ); - } else { - // otherwise just update the price - slot0.sqrtPriceX96 = state.sqrtPriceX96; - } - - // update liquidity if it changed - if (cache.liquidityStart != state.liquidity) liquidity = state.liquidity; - - // update fee growth global and, if necessary, protocol fees - // overflow is acceptable, protocol has to withdraw before it hits type(uint128).max fees - if (zeroForOne) { - feeGrowthGlobal0X128 = state.feeGrowthGlobalX128; - if (state.protocolFee > 0) protocolFees.token0 += state.protocolFee; - } else { - feeGrowthGlobal1X128 = state.feeGrowthGlobalX128; - if (state.protocolFee > 0) protocolFees.token1 += state.protocolFee; - } - - (amount0, amount1) = zeroForOne == exactInput - ? (amountSpecified - state.amountSpecifiedRemaining, state.amountCalculated) - : (state.amountCalculated, amountSpecified - state.amountSpecifiedRemaining); - - // do the transfers and collect payment - if (zeroForOne) { - if (amount1 < 0) TransferHelper.safeTransfer(token1, recipient, uint256(-amount1)); - - uint256 balance0Before = balance0(); - IUniswapV3SwapCallback(msg.sender).uniswapV3SwapCallback(amount0, amount1, data); - require(balance0Before.add(uint256(amount0)) <= balance0(), 'IIA'); - } else { - if (amount0 < 0) TransferHelper.safeTransfer(token0, recipient, uint256(-amount0)); - - uint256 balance1Before = balance1(); - IUniswapV3SwapCallback(msg.sender).uniswapV3SwapCallback(amount0, amount1, data); - require(balance1Before.add(uint256(amount1)) <= balance1(), 'IIA'); - } - - emit Swap(msg.sender, recipient, amount0, amount1, state.sqrtPriceX96, state.liquidity, state.tick); - slot0.unlocked = true; - } - - /// @inheritdoc IUniswapV3PoolActions - function flash( - address recipient, - uint256 amount0, - uint256 amount1, - bytes calldata data - ) external override lock noDelegateCall { - uint128 _liquidity = liquidity; - require(_liquidity > 0, 'L'); - - uint256 fee0 = FullMath.mulDivRoundingUp(amount0, fee, 1e6); - uint256 fee1 = FullMath.mulDivRoundingUp(amount1, fee, 1e6); - uint256 balance0Before = balance0(); - uint256 balance1Before = balance1(); - - if (amount0 > 0) TransferHelper.safeTransfer(token0, recipient, amount0); - if (amount1 > 0) TransferHelper.safeTransfer(token1, recipient, amount1); - - IUniswapV3FlashCallback(msg.sender).uniswapV3FlashCallback(fee0, fee1, data); - - uint256 balance0After = balance0(); - uint256 balance1After = balance1(); - - require(balance0Before.add(fee0) <= balance0After, 'F0'); - require(balance1Before.add(fee1) <= balance1After, 'F1'); - - // sub is safe because we know balanceAfter is gt balanceBefore by at least fee - uint256 paid0 = balance0After - balance0Before; - uint256 paid1 = balance1After - balance1Before; - - if (paid0 > 0) { - uint8 feeProtocol0 = slot0.feeProtocol % 16; - uint256 fees0 = feeProtocol0 == 0 ? 0 : paid0 / feeProtocol0; - if (uint128(fees0) > 0) protocolFees.token0 += uint128(fees0); - feeGrowthGlobal0X128 += FullMath.mulDiv(paid0 - fees0, FixedPoint128.Q128, _liquidity); - } - if (paid1 > 0) { - uint8 feeProtocol1 = slot0.feeProtocol >> 4; - uint256 fees1 = feeProtocol1 == 0 ? 0 : paid1 / feeProtocol1; - if (uint128(fees1) > 0) protocolFees.token1 += uint128(fees1); - feeGrowthGlobal1X128 += FullMath.mulDiv(paid1 - fees1, FixedPoint128.Q128, _liquidity); - } - - emit Flash(msg.sender, recipient, amount0, amount1, paid0, paid1); - } - - /// @inheritdoc IUniswapV3PoolOwnerActions - function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external override lock onlyFactoryOwner { - require( - (feeProtocol0 == 0 || (feeProtocol0 >= 4 && feeProtocol0 <= 10)) && - (feeProtocol1 == 0 || (feeProtocol1 >= 4 && feeProtocol1 <= 10)) - ); - uint8 feeProtocolOld = slot0.feeProtocol; - slot0.feeProtocol = feeProtocol0 + (feeProtocol1 << 4); - emit SetFeeProtocol(feeProtocolOld % 16, feeProtocolOld >> 4, feeProtocol0, feeProtocol1); - } - - /// @inheritdoc IUniswapV3PoolOwnerActions - function collectProtocol( - address recipient, - uint128 amount0Requested, - uint128 amount1Requested - ) external override lock onlyFactoryOwner returns (uint128 amount0, uint128 amount1) { - amount0 = amount0Requested > protocolFees.token0 ? protocolFees.token0 : amount0Requested; - amount1 = amount1Requested > protocolFees.token1 ? protocolFees.token1 : amount1Requested; - - if (amount0 > 0) { - if (amount0 == protocolFees.token0) amount0--; // ensure that the slot is not cleared, for gas savings - protocolFees.token0 -= amount0; - TransferHelper.safeTransfer(token0, recipient, amount0); - } - if (amount1 > 0) { - if (amount1 == protocolFees.token1) amount1--; // ensure that the slot is not cleared, for gas savings - protocolFees.token1 -= amount1; - TransferHelper.safeTransfer(token1, recipient, amount1); - } - - emit CollectProtocol(msg.sender, recipient, amount0, amount1); - } -} diff --git a/lib/v3-core/contracts/UniswapV3PoolDeployer.sol b/lib/v3-core/contracts/UniswapV3PoolDeployer.sol deleted file mode 100644 index 02bfd53..0000000 --- a/lib/v3-core/contracts/UniswapV3PoolDeployer.sol +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity =0.7.6; - -import './interfaces/IUniswapV3PoolDeployer.sol'; - -import './UniswapV3Pool.sol'; - -contract UniswapV3PoolDeployer is IUniswapV3PoolDeployer { - struct Parameters { - address factory; - address token0; - address token1; - uint24 fee; - int24 tickSpacing; - } - - /// @inheritdoc IUniswapV3PoolDeployer - Parameters public override parameters; - - /// @dev Deploys a pool with the given parameters by transiently setting the parameters storage slot and then - /// clearing it after deploying the pool. - /// @param factory The contract address of the Uniswap V3 factory - /// @param token0 The first token of the pool by address sort order - /// @param token1 The second token of the pool by address sort order - /// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip - /// @param tickSpacing The spacing between usable ticks - function deploy( - address factory, - address token0, - address token1, - uint24 fee, - int24 tickSpacing - ) internal returns (address pool) { - parameters = Parameters({factory: factory, token0: token0, token1: token1, fee: fee, tickSpacing: tickSpacing}); - pool = address(new UniswapV3Pool{salt: keccak256(abi.encode(token0, token1, fee))}()); - delete parameters; - } -} diff --git a/lib/v3-core/contracts/interfaces/IERC20Minimal.sol b/lib/v3-core/contracts/interfaces/IERC20Minimal.sol deleted file mode 100644 index c303265..0000000 --- a/lib/v3-core/contracts/interfaces/IERC20Minimal.sol +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title Minimal ERC20 interface for Uniswap -/// @notice Contains a subset of the full ERC20 interface that is used in Uniswap V3 -interface IERC20Minimal { - /// @notice Returns the balance of a token - /// @param account The account for which to look up the number of tokens it has, i.e. its balance - /// @return The number of tokens held by the account - function balanceOf(address account) external view returns (uint256); - - /// @notice Transfers the amount of token from the `msg.sender` to the recipient - /// @param recipient The account that will receive the amount transferred - /// @param amount The number of tokens to send from the sender to the recipient - /// @return Returns true for a successful transfer, false for an unsuccessful transfer - function transfer(address recipient, uint256 amount) external returns (bool); - - /// @notice Returns the current allowance given to a spender by an owner - /// @param owner The account of the token owner - /// @param spender The account of the token spender - /// @return The current allowance granted by `owner` to `spender` - function allowance(address owner, address spender) external view returns (uint256); - - /// @notice Sets the allowance of a spender from the `msg.sender` to the value `amount` - /// @param spender The account which will be allowed to spend a given amount of the owners tokens - /// @param amount The amount of tokens allowed to be used by `spender` - /// @return Returns true for a successful approval, false for unsuccessful - function approve(address spender, uint256 amount) external returns (bool); - - /// @notice Transfers `amount` tokens from `sender` to `recipient` up to the allowance given to the `msg.sender` - /// @param sender The account from which the transfer will be initiated - /// @param recipient The recipient of the transfer - /// @param amount The amount of the transfer - /// @return Returns true for a successful transfer, false for unsuccessful - function transferFrom( - address sender, - address recipient, - uint256 amount - ) external returns (bool); - - /// @notice Event emitted when tokens are transferred from one address to another, either via `#transfer` or `#transferFrom`. - /// @param from The account from which the tokens were sent, i.e. the balance decreased - /// @param to The account to which the tokens were sent, i.e. the balance increased - /// @param value The amount of tokens that were transferred - event Transfer(address indexed from, address indexed to, uint256 value); - - /// @notice Event emitted when the approval amount for the spender of a given owner's tokens changes. - /// @param owner The account that approved spending of its tokens - /// @param spender The account for which the spending allowance was modified - /// @param value The new allowance from the owner to the spender - event Approval(address indexed owner, address indexed spender, uint256 value); -} diff --git a/lib/v3-core/contracts/interfaces/IUniswapV3Factory.sol b/lib/v3-core/contracts/interfaces/IUniswapV3Factory.sol deleted file mode 100644 index 540cfdc..0000000 --- a/lib/v3-core/contracts/interfaces/IUniswapV3Factory.sol +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title The interface for the Uniswap V3 Factory -/// @notice The Uniswap V3 Factory facilitates creation of Uniswap V3 pools and control over the protocol fees -interface IUniswapV3Factory { - /// @notice Emitted when the owner of the factory is changed - /// @param oldOwner The owner before the owner was changed - /// @param newOwner The owner after the owner was changed - event OwnerChanged(address indexed oldOwner, address indexed newOwner); - - /// @notice Emitted when a pool is created - /// @param token0 The first token of the pool by address sort order - /// @param token1 The second token of the pool by address sort order - /// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip - /// @param tickSpacing The minimum number of ticks between initialized ticks - /// @param pool The address of the created pool - event PoolCreated( - address indexed token0, - address indexed token1, - uint24 indexed fee, - int24 tickSpacing, - address pool - ); - - /// @notice Emitted when a new fee amount is enabled for pool creation via the factory - /// @param fee The enabled fee, denominated in hundredths of a bip - /// @param tickSpacing The minimum number of ticks between initialized ticks for pools created with the given fee - event FeeAmountEnabled(uint24 indexed fee, int24 indexed tickSpacing); - - /// @notice Returns the current owner of the factory - /// @dev Can be changed by the current owner via setOwner - /// @return The address of the factory owner - function owner() external view returns (address); - - /// @notice Returns the tick spacing for a given fee amount, if enabled, or 0 if not enabled - /// @dev A fee amount can never be removed, so this value should be hard coded or cached in the calling context - /// @param fee The enabled fee, denominated in hundredths of a bip. Returns 0 in case of unenabled fee - /// @return The tick spacing - function feeAmountTickSpacing(uint24 fee) external view returns (int24); - - /// @notice Returns the pool address for a given pair of tokens and a fee, or address 0 if it does not exist - /// @dev tokenA and tokenB may be passed in either token0/token1 or token1/token0 order - /// @param tokenA The contract address of either token0 or token1 - /// @param tokenB The contract address of the other token - /// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip - /// @return pool The pool address - function getPool( - address tokenA, - address tokenB, - uint24 fee - ) external view returns (address pool); - - /// @notice Creates a pool for the given two tokens and fee - /// @param tokenA One of the two tokens in the desired pool - /// @param tokenB The other of the two tokens in the desired pool - /// @param fee The desired fee for the pool - /// @dev tokenA and tokenB may be passed in either order: token0/token1 or token1/token0. tickSpacing is retrieved - /// from the fee. The call will revert if the pool already exists, the fee is invalid, or the token arguments - /// are invalid. - /// @return pool The address of the newly created pool - function createPool( - address tokenA, - address tokenB, - uint24 fee - ) external returns (address pool); - - /// @notice Updates the owner of the factory - /// @dev Must be called by the current owner - /// @param _owner The new owner of the factory - function setOwner(address _owner) external; - - /// @notice Enables a fee amount with the given tickSpacing - /// @dev Fee amounts may never be removed once enabled - /// @param fee The fee amount to enable, denominated in hundredths of a bip (i.e. 1e-6) - /// @param tickSpacing The spacing between ticks to be enforced for all pools created with the given fee amount - function enableFeeAmount(uint24 fee, int24 tickSpacing) external; -} diff --git a/lib/v3-core/contracts/interfaces/IUniswapV3Pool.sol b/lib/v3-core/contracts/interfaces/IUniswapV3Pool.sol deleted file mode 100644 index 56df050..0000000 --- a/lib/v3-core/contracts/interfaces/IUniswapV3Pool.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -import './pool/IUniswapV3PoolImmutables.sol'; -import './pool/IUniswapV3PoolState.sol'; -import './pool/IUniswapV3PoolDerivedState.sol'; -import './pool/IUniswapV3PoolActions.sol'; -import './pool/IUniswapV3PoolOwnerActions.sol'; -import './pool/IUniswapV3PoolEvents.sol'; - -/// @title The interface for a Uniswap V3 Pool -/// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform -/// to the ERC20 specification -/// @dev The pool interface is broken up into many smaller pieces -interface IUniswapV3Pool is - IUniswapV3PoolImmutables, - IUniswapV3PoolState, - IUniswapV3PoolDerivedState, - IUniswapV3PoolActions, - IUniswapV3PoolOwnerActions, - IUniswapV3PoolEvents -{ - -} diff --git a/lib/v3-core/contracts/interfaces/IUniswapV3PoolDeployer.sol b/lib/v3-core/contracts/interfaces/IUniswapV3PoolDeployer.sol deleted file mode 100644 index 72096c1..0000000 --- a/lib/v3-core/contracts/interfaces/IUniswapV3PoolDeployer.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title An interface for a contract that is capable of deploying Uniswap V3 Pools -/// @notice A contract that constructs a pool must implement this to pass arguments to the pool -/// @dev This is used to avoid having constructor arguments in the pool contract, which results in the init code hash -/// of the pool being constant allowing the CREATE2 address of the pool to be cheaply computed on-chain -interface IUniswapV3PoolDeployer { - /// @notice Get the parameters to be used in constructing the pool, set transiently during pool creation. - /// @dev Called by the pool constructor to fetch the parameters of the pool - /// Returns factory The factory address - /// Returns token0 The first token of the pool by address sort order - /// Returns token1 The second token of the pool by address sort order - /// Returns fee The fee collected upon every swap in the pool, denominated in hundredths of a bip - /// Returns tickSpacing The minimum number of ticks between initialized ticks - function parameters() - external - view - returns ( - address factory, - address token0, - address token1, - uint24 fee, - int24 tickSpacing - ); -} diff --git a/lib/v3-core/contracts/interfaces/LICENSE b/lib/v3-core/contracts/interfaces/LICENSE deleted file mode 100644 index 7f6aca7..0000000 --- a/lib/v3-core/contracts/interfaces/LICENSE +++ /dev/null @@ -1,445 +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 - - 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 -convey 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 2 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, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision 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, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This 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. - - -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: Uniswap Labs - -Licensed Work: Uniswap V3 Core - The Licensed Work is (c) 2021 Uniswap Labs - -Additional Use Grant: Any uses listed and defined at - v3-core-license-grants.uniswap.eth - -Change Date: The earlier of 2023-04-01 or a date specified at - v3-core-license-date.uniswap.eth - -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/v3-core/contracts/interfaces/callback/IUniswapV3FlashCallback.sol b/lib/v3-core/contracts/interfaces/callback/IUniswapV3FlashCallback.sol deleted file mode 100644 index 18e54c4..0000000 --- a/lib/v3-core/contracts/interfaces/callback/IUniswapV3FlashCallback.sol +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title Callback for IUniswapV3PoolActions#flash -/// @notice Any contract that calls IUniswapV3PoolActions#flash must implement this interface -interface IUniswapV3FlashCallback { - /// @notice Called to `msg.sender` after transferring to the recipient from IUniswapV3Pool#flash. - /// @dev In the implementation you must repay the pool the tokens sent by flash plus the computed fee amounts. - /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory. - /// @param fee0 The fee amount in token0 due to the pool by the end of the flash - /// @param fee1 The fee amount in token1 due to the pool by the end of the flash - /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#flash call - function uniswapV3FlashCallback( - uint256 fee0, - uint256 fee1, - bytes calldata data - ) external; -} diff --git a/lib/v3-core/contracts/interfaces/callback/IUniswapV3MintCallback.sol b/lib/v3-core/contracts/interfaces/callback/IUniswapV3MintCallback.sol deleted file mode 100644 index 85447e8..0000000 --- a/lib/v3-core/contracts/interfaces/callback/IUniswapV3MintCallback.sol +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title Callback for IUniswapV3PoolActions#mint -/// @notice Any contract that calls IUniswapV3PoolActions#mint must implement this interface -interface IUniswapV3MintCallback { - /// @notice Called to `msg.sender` after minting liquidity to a position from IUniswapV3Pool#mint. - /// @dev In the implementation you must pay the pool tokens owed for the minted liquidity. - /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory. - /// @param amount0Owed The amount of token0 due to the pool for the minted liquidity - /// @param amount1Owed The amount of token1 due to the pool for the minted liquidity - /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#mint call - function uniswapV3MintCallback( - uint256 amount0Owed, - uint256 amount1Owed, - bytes calldata data - ) external; -} diff --git a/lib/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol b/lib/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol deleted file mode 100644 index 9f183b2..0000000 --- a/lib/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title Callback for IUniswapV3PoolActions#swap -/// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface -interface IUniswapV3SwapCallback { - /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap. - /// @dev In the implementation you must pay the pool tokens owed for the swap. - /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory. - /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped. - /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by - /// the end of the swap. If positive, the callback must send that amount of token0 to the pool. - /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by - /// the end of the swap. If positive, the callback must send that amount of token1 to the pool. - /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call - function uniswapV3SwapCallback( - int256 amount0Delta, - int256 amount1Delta, - bytes calldata data - ) external; -} diff --git a/lib/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol b/lib/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol deleted file mode 100644 index 44fb61c..0000000 --- a/lib/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol +++ /dev/null @@ -1,103 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title Permissionless pool actions -/// @notice Contains pool methods that can be called by anyone -interface IUniswapV3PoolActions { - /// @notice Sets the initial price for the pool - /// @dev Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value - /// @param sqrtPriceX96 the initial sqrt price of the pool as a Q64.96 - function initialize(uint160 sqrtPriceX96) external; - - /// @notice Adds liquidity for the given recipient/tickLower/tickUpper position - /// @dev The caller of this method receives a callback in the form of IUniswapV3MintCallback#uniswapV3MintCallback - /// in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends - /// on tickLower, tickUpper, the amount of liquidity, and the current price. - /// @param recipient The address for which the liquidity will be created - /// @param tickLower The lower tick of the position in which to add liquidity - /// @param tickUpper The upper tick of the position in which to add liquidity - /// @param amount The amount of liquidity to mint - /// @param data Any data that should be passed through to the callback - /// @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback - /// @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback - function mint( - address recipient, - int24 tickLower, - int24 tickUpper, - uint128 amount, - bytes calldata data - ) external returns (uint256 amount0, uint256 amount1); - - /// @notice Collects tokens owed to a position - /// @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity. - /// Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or - /// amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the - /// actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity. - /// @param recipient The address which should receive the fees collected - /// @param tickLower The lower tick of the position for which to collect fees - /// @param tickUpper The upper tick of the position for which to collect fees - /// @param amount0Requested How much token0 should be withdrawn from the fees owed - /// @param amount1Requested How much token1 should be withdrawn from the fees owed - /// @return amount0 The amount of fees collected in token0 - /// @return amount1 The amount of fees collected in token1 - function collect( - address recipient, - int24 tickLower, - int24 tickUpper, - uint128 amount0Requested, - uint128 amount1Requested - ) external returns (uint128 amount0, uint128 amount1); - - /// @notice Burn liquidity from the sender and account tokens owed for the liquidity to the position - /// @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0 - /// @dev Fees must be collected separately via a call to #collect - /// @param tickLower The lower tick of the position for which to burn liquidity - /// @param tickUpper The upper tick of the position for which to burn liquidity - /// @param amount How much liquidity to burn - /// @return amount0 The amount of token0 sent to the recipient - /// @return amount1 The amount of token1 sent to the recipient - function burn( - int24 tickLower, - int24 tickUpper, - uint128 amount - ) external returns (uint256 amount0, uint256 amount1); - - /// @notice Swap token0 for token1, or token1 for token0 - /// @dev The caller of this method receives a callback in the form of IUniswapV3SwapCallback#uniswapV3SwapCallback - /// @param recipient The address to receive the output of the swap - /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0 - /// @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative) - /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this - /// value after the swap. If one for zero, the price cannot be greater than this value after the swap - /// @param data Any data to be passed through to the callback - /// @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive - /// @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive - function swap( - address recipient, - bool zeroForOne, - int256 amountSpecified, - uint160 sqrtPriceLimitX96, - bytes calldata data - ) external returns (int256 amount0, int256 amount1); - - /// @notice Receive token0 and/or token1 and pay it back, plus a fee, in the callback - /// @dev The caller of this method receives a callback in the form of IUniswapV3FlashCallback#uniswapV3FlashCallback - /// @dev Can be used to donate underlying tokens pro-rata to currently in-range liquidity providers by calling - /// with 0 amount{0,1} and sending the donation amount(s) from the callback - /// @param recipient The address which will receive the token0 and token1 amounts - /// @param amount0 The amount of token0 to send - /// @param amount1 The amount of token1 to send - /// @param data Any data to be passed through to the callback - function flash( - address recipient, - uint256 amount0, - uint256 amount1, - bytes calldata data - ) external; - - /// @notice Increase the maximum number of price and liquidity observations that this pool will store - /// @dev This method is no-op if the pool already has an observationCardinalityNext greater than or equal to - /// the input observationCardinalityNext. - /// @param observationCardinalityNext The desired minimum number of observations for the pool to store - function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external; -} diff --git a/lib/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol b/lib/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol deleted file mode 100644 index eda3a00..0000000 --- a/lib/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title Pool state that is not stored -/// @notice Contains view functions to provide information about the pool that is computed rather than stored on the -/// blockchain. The functions here may have variable gas costs. -interface IUniswapV3PoolDerivedState { - /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp - /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing - /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick, - /// you must call it with secondsAgos = [3600, 0]. - /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in - /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio. - /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned - /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp - /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block - /// timestamp - function observe(uint32[] calldata secondsAgos) - external - view - returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s); - - /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range - /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed. - /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first - /// snapshot is taken and the second snapshot is taken. - /// @param tickLower The lower tick of the range - /// @param tickUpper The upper tick of the range - /// @return tickCumulativeInside The snapshot of the tick accumulator for the range - /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range - /// @return secondsInside The snapshot of seconds per liquidity for the range - function snapshotCumulativesInside(int24 tickLower, int24 tickUpper) - external - view - returns ( - int56 tickCumulativeInside, - uint160 secondsPerLiquidityInsideX128, - uint32 secondsInside - ); -} diff --git a/lib/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol b/lib/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol deleted file mode 100644 index 9d915dd..0000000 --- a/lib/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol +++ /dev/null @@ -1,121 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title Events emitted by a pool -/// @notice Contains all events emitted by the pool -interface IUniswapV3PoolEvents { - /// @notice Emitted exactly once by a pool when #initialize is first called on the pool - /// @dev Mint/Burn/Swap cannot be emitted by the pool before Initialize - /// @param sqrtPriceX96 The initial sqrt price of the pool, as a Q64.96 - /// @param tick The initial tick of the pool, i.e. log base 1.0001 of the starting price of the pool - event Initialize(uint160 sqrtPriceX96, int24 tick); - - /// @notice Emitted when liquidity is minted for a given position - /// @param sender The address that minted the liquidity - /// @param owner The owner of the position and recipient of any minted liquidity - /// @param tickLower The lower tick of the position - /// @param tickUpper The upper tick of the position - /// @param amount The amount of liquidity minted to the position range - /// @param amount0 How much token0 was required for the minted liquidity - /// @param amount1 How much token1 was required for the minted liquidity - event Mint( - address sender, - address indexed owner, - int24 indexed tickLower, - int24 indexed tickUpper, - uint128 amount, - uint256 amount0, - uint256 amount1 - ); - - /// @notice Emitted when fees are collected by the owner of a position - /// @dev Collect events may be emitted with zero amount0 and amount1 when the caller chooses not to collect fees - /// @param owner The owner of the position for which fees are collected - /// @param tickLower The lower tick of the position - /// @param tickUpper The upper tick of the position - /// @param amount0 The amount of token0 fees collected - /// @param amount1 The amount of token1 fees collected - event Collect( - address indexed owner, - address recipient, - int24 indexed tickLower, - int24 indexed tickUpper, - uint128 amount0, - uint128 amount1 - ); - - /// @notice Emitted when a position's liquidity is removed - /// @dev Does not withdraw any fees earned by the liquidity position, which must be withdrawn via #collect - /// @param owner The owner of the position for which liquidity is removed - /// @param tickLower The lower tick of the position - /// @param tickUpper The upper tick of the position - /// @param amount The amount of liquidity to remove - /// @param amount0 The amount of token0 withdrawn - /// @param amount1 The amount of token1 withdrawn - event Burn( - address indexed owner, - int24 indexed tickLower, - int24 indexed tickUpper, - uint128 amount, - uint256 amount0, - uint256 amount1 - ); - - /// @notice Emitted by the pool for any swaps between token0 and token1 - /// @param sender The address that initiated the swap call, and that received the callback - /// @param recipient The address that received the output of the swap - /// @param amount0 The delta of the token0 balance of the pool - /// @param amount1 The delta of the token1 balance of the pool - /// @param sqrtPriceX96 The sqrt(price) of the pool after the swap, as a Q64.96 - /// @param liquidity The liquidity of the pool after the swap - /// @param tick The log base 1.0001 of price of the pool after the swap - event Swap( - address indexed sender, - address indexed recipient, - int256 amount0, - int256 amount1, - uint160 sqrtPriceX96, - uint128 liquidity, - int24 tick - ); - - /// @notice Emitted by the pool for any flashes of token0/token1 - /// @param sender The address that initiated the swap call, and that received the callback - /// @param recipient The address that received the tokens from flash - /// @param amount0 The amount of token0 that was flashed - /// @param amount1 The amount of token1 that was flashed - /// @param paid0 The amount of token0 paid for the flash, which can exceed the amount0 plus the fee - /// @param paid1 The amount of token1 paid for the flash, which can exceed the amount1 plus the fee - event Flash( - address indexed sender, - address indexed recipient, - uint256 amount0, - uint256 amount1, - uint256 paid0, - uint256 paid1 - ); - - /// @notice Emitted by the pool for increases to the number of observations that can be stored - /// @dev observationCardinalityNext is not the observation cardinality until an observation is written at the index - /// just before a mint/swap/burn. - /// @param observationCardinalityNextOld The previous value of the next observation cardinality - /// @param observationCardinalityNextNew The updated value of the next observation cardinality - event IncreaseObservationCardinalityNext( - uint16 observationCardinalityNextOld, - uint16 observationCardinalityNextNew - ); - - /// @notice Emitted when the protocol fee is changed by the pool - /// @param feeProtocol0Old The previous value of the token0 protocol fee - /// @param feeProtocol1Old The previous value of the token1 protocol fee - /// @param feeProtocol0New The updated value of the token0 protocol fee - /// @param feeProtocol1New The updated value of the token1 protocol fee - event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New); - - /// @notice Emitted when the collected protocol fees are withdrawn by the factory owner - /// @param sender The address that collects the protocol fees - /// @param recipient The address that receives the collected protocol fees - /// @param amount0 The amount of token0 protocol fees that is withdrawn - /// @param amount0 The amount of token1 protocol fees that is withdrawn - event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount0, uint128 amount1); -} diff --git a/lib/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol b/lib/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol deleted file mode 100644 index c9beb15..0000000 --- a/lib/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title Pool state that never changes -/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values -interface IUniswapV3PoolImmutables { - /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface - /// @return The contract address - function factory() external view returns (address); - - /// @notice The first of the two tokens of the pool, sorted by address - /// @return The token contract address - function token0() external view returns (address); - - /// @notice The second of the two tokens of the pool, sorted by address - /// @return The token contract address - function token1() external view returns (address); - - /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6 - /// @return The fee - function fee() external view returns (uint24); - - /// @notice The pool tick spacing - /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive - /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ... - /// This value is an int24 to avoid casting even though it is always positive. - /// @return The tick spacing - function tickSpacing() external view returns (int24); - - /// @notice The maximum amount of position liquidity that can use any tick in the range - /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and - /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool - /// @return The max amount of liquidity per tick - function maxLiquidityPerTick() external view returns (uint128); -} diff --git a/lib/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol b/lib/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol deleted file mode 100644 index 2395ed3..0000000 --- a/lib/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title Permissioned pool actions -/// @notice Contains pool methods that may only be called by the factory owner -interface IUniswapV3PoolOwnerActions { - /// @notice Set the denominator of the protocol's % share of the fees - /// @param feeProtocol0 new protocol fee for token0 of the pool - /// @param feeProtocol1 new protocol fee for token1 of the pool - function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external; - - /// @notice Collect the protocol fee accrued to the pool - /// @param recipient The address to which collected protocol fees should be sent - /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1 - /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0 - /// @return amount0 The protocol fee collected in token0 - /// @return amount1 The protocol fee collected in token1 - function collectProtocol( - address recipient, - uint128 amount0Requested, - uint128 amount1Requested - ) external returns (uint128 amount0, uint128 amount1); -} diff --git a/lib/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol b/lib/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol deleted file mode 100644 index 620256c..0000000 --- a/lib/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol +++ /dev/null @@ -1,116 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title Pool state that can change -/// @notice These methods compose the pool's state, and can change with any frequency including multiple times -/// per transaction -interface IUniswapV3PoolState { - /// @notice The 0th storage slot in the pool stores many values, and is exposed as a single method to save gas - /// when accessed externally. - /// @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value - /// tick The current tick of the pool, i.e. according to the last tick transition that was run. - /// This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick - /// boundary. - /// observationIndex The index of the last oracle observation that was written, - /// observationCardinality The current maximum number of observations stored in the pool, - /// observationCardinalityNext The next maximum number of observations, to be updated when the observation. - /// feeProtocol The protocol fee for both tokens of the pool. - /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted 4 bits and the protocol fee of token0 - /// is the lower 4 bits. Used as the denominator of a fraction of the swap fee, e.g. 4 means 1/4th of the swap fee. - /// unlocked Whether the pool is currently locked to reentrancy - function slot0() - external - view - returns ( - uint160 sqrtPriceX96, - int24 tick, - uint16 observationIndex, - uint16 observationCardinality, - uint16 observationCardinalityNext, - uint8 feeProtocol, - bool unlocked - ); - - /// @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool - /// @dev This value can overflow the uint256 - function feeGrowthGlobal0X128() external view returns (uint256); - - /// @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool - /// @dev This value can overflow the uint256 - function feeGrowthGlobal1X128() external view returns (uint256); - - /// @notice The amounts of token0 and token1 that are owed to the protocol - /// @dev Protocol fees will never exceed uint128 max in either token - function protocolFees() external view returns (uint128 token0, uint128 token1); - - /// @notice The currently in range liquidity available to the pool - /// @dev This value has no relationship to the total liquidity across all ticks - function liquidity() external view returns (uint128); - - /// @notice Look up information about a specific tick in the pool - /// @param tick The tick to look up - /// @return liquidityGross the total amount of position liquidity that uses the pool either as tick lower or - /// tick upper, - /// liquidityNet how much liquidity changes when the pool price crosses the tick, - /// feeGrowthOutside0X128 the fee growth on the other side of the tick from the current tick in token0, - /// feeGrowthOutside1X128 the fee growth on the other side of the tick from the current tick in token1, - /// tickCumulativeOutside the cumulative tick value on the other side of the tick from the current tick - /// secondsPerLiquidityOutsideX128 the seconds spent per liquidity on the other side of the tick from the current tick, - /// secondsOutside the seconds spent on the other side of the tick from the current tick, - /// initialized Set to true if the tick is initialized, i.e. liquidityGross is greater than 0, otherwise equal to false. - /// Outside values can only be used if the tick is initialized, i.e. if liquidityGross is greater than 0. - /// In addition, these values are only relative and must be used only in comparison to previous snapshots for - /// a specific position. - function ticks(int24 tick) - external - view - returns ( - uint128 liquidityGross, - int128 liquidityNet, - uint256 feeGrowthOutside0X128, - uint256 feeGrowthOutside1X128, - int56 tickCumulativeOutside, - uint160 secondsPerLiquidityOutsideX128, - uint32 secondsOutside, - bool initialized - ); - - /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information - function tickBitmap(int16 wordPosition) external view returns (uint256); - - /// @notice Returns the information about a position by the position's key - /// @param key The position's key is a hash of a preimage composed by the owner, tickLower and tickUpper - /// @return _liquidity The amount of liquidity in the position, - /// Returns feeGrowthInside0LastX128 fee growth of token0 inside the tick range as of the last mint/burn/poke, - /// Returns feeGrowthInside1LastX128 fee growth of token1 inside the tick range as of the last mint/burn/poke, - /// Returns tokensOwed0 the computed amount of token0 owed to the position as of the last mint/burn/poke, - /// Returns tokensOwed1 the computed amount of token1 owed to the position as of the last mint/burn/poke - function positions(bytes32 key) - external - view - returns ( - uint128 _liquidity, - uint256 feeGrowthInside0LastX128, - uint256 feeGrowthInside1LastX128, - uint128 tokensOwed0, - uint128 tokensOwed1 - ); - - /// @notice Returns data about a specific observation index - /// @param index The element of the observations array to fetch - /// @dev You most likely want to use #observe() instead of this method to get an observation as of some amount of time - /// ago, rather than at a specific index in the array. - /// @return blockTimestamp The timestamp of the observation, - /// Returns tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp, - /// Returns secondsPerLiquidityCumulativeX128 the seconds per in range liquidity for the life of the pool as of the observation timestamp, - /// Returns initialized whether the observation has been initialized and the values are safe to use - function observations(uint256 index) - external - view - returns ( - uint32 blockTimestamp, - int56 tickCumulative, - uint160 secondsPerLiquidityCumulativeX128, - bool initialized - ); -} diff --git a/lib/v3-core/contracts/libraries/BitMath.sol b/lib/v3-core/contracts/libraries/BitMath.sol deleted file mode 100644 index 3a7216c..0000000 --- a/lib/v3-core/contracts/libraries/BitMath.sol +++ /dev/null @@ -1,94 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title BitMath -/// @dev This library provides functionality for computing bit properties of an unsigned integer -library BitMath { - /// @notice Returns the index of the most significant bit of the number, - /// where the least significant bit is at index 0 and the most significant bit is at index 255 - /// @dev The function satisfies the property: - /// x >= 2**mostSignificantBit(x) and x < 2**(mostSignificantBit(x)+1) - /// @param x the value for which to compute the most significant bit, must be greater than 0 - /// @return r the index of the most significant bit - function mostSignificantBit(uint256 x) internal pure returns (uint8 r) { - require(x > 0); - - if (x >= 0x100000000000000000000000000000000) { - x >>= 128; - r += 128; - } - if (x >= 0x10000000000000000) { - x >>= 64; - r += 64; - } - if (x >= 0x100000000) { - x >>= 32; - r += 32; - } - if (x >= 0x10000) { - x >>= 16; - r += 16; - } - if (x >= 0x100) { - x >>= 8; - r += 8; - } - if (x >= 0x10) { - x >>= 4; - r += 4; - } - if (x >= 0x4) { - x >>= 2; - r += 2; - } - if (x >= 0x2) r += 1; - } - - /// @notice Returns the index of the least significant bit of the number, - /// where the least significant bit is at index 0 and the most significant bit is at index 255 - /// @dev The function satisfies the property: - /// (x & 2**leastSignificantBit(x)) != 0 and (x & (2**(leastSignificantBit(x)) - 1)) == 0) - /// @param x the value for which to compute the least significant bit, must be greater than 0 - /// @return r the index of the least significant bit - function leastSignificantBit(uint256 x) internal pure returns (uint8 r) { - require(x > 0); - - r = 255; - if (x & type(uint128).max > 0) { - r -= 128; - } else { - x >>= 128; - } - if (x & type(uint64).max > 0) { - r -= 64; - } else { - x >>= 64; - } - if (x & type(uint32).max > 0) { - r -= 32; - } else { - x >>= 32; - } - if (x & type(uint16).max > 0) { - r -= 16; - } else { - x >>= 16; - } - if (x & type(uint8).max > 0) { - r -= 8; - } else { - x >>= 8; - } - if (x & 0xf > 0) { - r -= 4; - } else { - x >>= 4; - } - if (x & 0x3 > 0) { - r -= 2; - } else { - x >>= 2; - } - if (x & 0x1 > 0) r -= 1; - } -} diff --git a/lib/v3-core/contracts/libraries/FixedPoint128.sol b/lib/v3-core/contracts/libraries/FixedPoint128.sol deleted file mode 100644 index 6d6948b..0000000 --- a/lib/v3-core/contracts/libraries/FixedPoint128.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.4.0; - -/// @title FixedPoint128 -/// @notice A library for handling binary fixed point numbers, see https://en.wikipedia.org/wiki/Q_(number_format) -library FixedPoint128 { - uint256 internal constant Q128 = 0x100000000000000000000000000000000; -} diff --git a/lib/v3-core/contracts/libraries/FixedPoint96.sol b/lib/v3-core/contracts/libraries/FixedPoint96.sol deleted file mode 100644 index 63b42c2..0000000 --- a/lib/v3-core/contracts/libraries/FixedPoint96.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.4.0; - -/// @title FixedPoint96 -/// @notice A library for handling binary fixed point numbers, see https://en.wikipedia.org/wiki/Q_(number_format) -/// @dev Used in SqrtPriceMath.sol -library FixedPoint96 { - uint8 internal constant RESOLUTION = 96; - uint256 internal constant Q96 = 0x1000000000000000000000000; -} diff --git a/lib/v3-core/contracts/libraries/FullMath.sol b/lib/v3-core/contracts/libraries/FullMath.sol deleted file mode 100644 index 9985059..0000000 --- a/lib/v3-core/contracts/libraries/FullMath.sol +++ /dev/null @@ -1,124 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.4.0 <0.8.0; - -/// @title Contains 512-bit math functions -/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision -/// @dev Handles "phantom overflow" i.e., allows multiplication and division where an intermediate value overflows 256 bits -library FullMath { - /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 - /// @param a The multiplicand - /// @param b The multiplier - /// @param denominator The divisor - /// @return result The 256-bit result - /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv - function mulDiv( - uint256 a, - uint256 b, - uint256 denominator - ) internal pure returns (uint256 result) { - // 512-bit multiply [prod1 prod0] = a * b - // Compute the product mod 2**256 and mod 2**256 - 1 - // then 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(a, b, not(0)) - prod0 := mul(a, b) - prod1 := sub(sub(mm, prod0), lt(mm, prod0)) - } - - // Handle non-overflow cases, 256 by 256 division - if (prod1 == 0) { - require(denominator > 0); - assembly { - result := div(prod0, denominator) - } - return result; - } - - // 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] - // Compute remainder using mulmod - uint256 remainder; - assembly { - remainder := mulmod(a, b, denominator) - } - // Subtract 256 bit number from 512 bit number - assembly { - prod1 := sub(prod1, gt(remainder, prod0)) - prod0 := sub(prod0, remainder) - } - - // Factor powers of two out of denominator - // Compute largest power of two divisor of denominator. - // Always >= 1. - uint256 twos = -denominator & denominator; - // Divide denominator by power of two - assembly { - denominator := div(denominator, twos) - } - - // Divide [prod1 prod0] by the factors of two - assembly { - prod0 := div(prod0, twos) - } - // Shift in bits from prod1 into prod0. For this we need - // to flip `twos` such that it is 2**256 / twos. - // If twos is zero, then it becomes one - assembly { - twos := add(div(sub(0, twos), twos), 1) - } - 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 - // correct for four bits. That is, denominator * inv = 1 mod 2**4 - uint256 inv = (3 * denominator) ^ 2; - // Now use 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. - inv *= 2 - denominator * inv; // inverse mod 2**8 - inv *= 2 - denominator * inv; // inverse mod 2**16 - inv *= 2 - denominator * inv; // inverse mod 2**32 - inv *= 2 - denominator * inv; // inverse mod 2**64 - inv *= 2 - denominator * inv; // inverse mod 2**128 - inv *= 2 - denominator * inv; // 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 precoditions 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 * inv; - return result; - } - - /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 - /// @param a The multiplicand - /// @param b The multiplier - /// @param denominator The divisor - /// @return result The 256-bit result - function mulDivRoundingUp( - uint256 a, - uint256 b, - uint256 denominator - ) internal pure returns (uint256 result) { - result = mulDiv(a, b, denominator); - if (mulmod(a, b, denominator) > 0) { - require(result < type(uint256).max); - result++; - } - } -} diff --git a/lib/v3-core/contracts/libraries/LICENSE b/lib/v3-core/contracts/libraries/LICENSE deleted file mode 100644 index 7f6aca7..0000000 --- a/lib/v3-core/contracts/libraries/LICENSE +++ /dev/null @@ -1,445 +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 - - 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 -convey 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 2 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, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision 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, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This 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. - - -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: Uniswap Labs - -Licensed Work: Uniswap V3 Core - The Licensed Work is (c) 2021 Uniswap Labs - -Additional Use Grant: Any uses listed and defined at - v3-core-license-grants.uniswap.eth - -Change Date: The earlier of 2023-04-01 or a date specified at - v3-core-license-date.uniswap.eth - -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/v3-core/contracts/libraries/LICENSE_MIT b/lib/v3-core/contracts/libraries/LICENSE_MIT deleted file mode 100644 index bf4f90a..0000000 --- a/lib/v3-core/contracts/libraries/LICENSE_MIT +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2021 Remco Bloemen - -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. \ No newline at end of file diff --git a/lib/v3-core/contracts/libraries/LiquidityMath.sol b/lib/v3-core/contracts/libraries/LiquidityMath.sol deleted file mode 100644 index d5e2303..0000000 --- a/lib/v3-core/contracts/libraries/LiquidityMath.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title Math library for liquidity -library LiquidityMath { - /// @notice Add a signed liquidity delta to liquidity and revert if it overflows or underflows - /// @param x The liquidity before change - /// @param y The delta by which liquidity should be changed - /// @return z The liquidity delta - function addDelta(uint128 x, int128 y) internal pure returns (uint128 z) { - if (y < 0) { - require((z = x - uint128(-y)) < x, 'LS'); - } else { - require((z = x + uint128(y)) >= x, 'LA'); - } - } -} diff --git a/lib/v3-core/contracts/libraries/LowGasSafeMath.sol b/lib/v3-core/contracts/libraries/LowGasSafeMath.sol deleted file mode 100644 index dbc817c..0000000 --- a/lib/v3-core/contracts/libraries/LowGasSafeMath.sol +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.7.0; - -/// @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 LowGasSafeMath { - /// @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) { - 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) { - require((z = x - y) <= x); - } - - /// @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) { - require(x == 0 || (z = x * y) / x == y); - } - - /// @notice Returns x + y, reverts if overflows or underflows - /// @param x The augend - /// @param y The addend - /// @return z The sum of x and y - function add(int256 x, int256 y) internal pure returns (int256 z) { - require((z = x + y) >= x == (y >= 0)); - } - - /// @notice Returns x - y, reverts if overflows or underflows - /// @param x The minuend - /// @param y The subtrahend - /// @return z The difference of x and y - function sub(int256 x, int256 y) internal pure returns (int256 z) { - require((z = x - y) <= x == (y >= 0)); - } -} diff --git a/lib/v3-core/contracts/libraries/Oracle.sol b/lib/v3-core/contracts/libraries/Oracle.sol deleted file mode 100644 index d386328..0000000 --- a/lib/v3-core/contracts/libraries/Oracle.sol +++ /dev/null @@ -1,325 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity >=0.5.0 <0.8.0; - -/// @title Oracle -/// @notice Provides price and liquidity data useful for a wide variety of system designs -/// @dev Instances of stored oracle data, "observations", are collected in the oracle array -/// Every pool is initialized with an oracle array length of 1. Anyone can pay the SSTOREs to increase the -/// maximum length of the oracle array. New slots will be added when the array is fully populated. -/// Observations are overwritten when the full length of the oracle array is populated. -/// The most recent observation is available, independent of the length of the oracle array, by passing 0 to observe() -library Oracle { - struct Observation { - // the block timestamp of the observation - uint32 blockTimestamp; - // the tick accumulator, i.e. tick * time elapsed since the pool was first initialized - int56 tickCumulative; - // the seconds per liquidity, i.e. seconds elapsed / max(1, liquidity) since the pool was first initialized - uint160 secondsPerLiquidityCumulativeX128; - // whether or not the observation is initialized - bool initialized; - } - - /// @notice Transforms a previous observation into a new observation, given the passage of time and the current tick and liquidity values - /// @dev blockTimestamp _must_ be chronologically equal to or greater than last.blockTimestamp, safe for 0 or 1 overflows - /// @param last The specified observation to be transformed - /// @param blockTimestamp The timestamp of the new observation - /// @param tick The active tick at the time of the new observation - /// @param liquidity The total in-range liquidity at the time of the new observation - /// @return Observation The newly populated observation - function transform( - Observation memory last, - uint32 blockTimestamp, - int24 tick, - uint128 liquidity - ) private pure returns (Observation memory) { - uint32 delta = blockTimestamp - last.blockTimestamp; - return - Observation({ - blockTimestamp: blockTimestamp, - tickCumulative: last.tickCumulative + int56(tick) * delta, - secondsPerLiquidityCumulativeX128: last.secondsPerLiquidityCumulativeX128 + - ((uint160(delta) << 128) / (liquidity > 0 ? liquidity : 1)), - initialized: true - }); - } - - /// @notice Initialize the oracle array by writing the first slot. Called once for the lifecycle of the observations array - /// @param self The stored oracle array - /// @param time The time of the oracle initialization, via block.timestamp truncated to uint32 - /// @return cardinality The number of populated elements in the oracle array - /// @return cardinalityNext The new length of the oracle array, independent of population - function initialize(Observation[65535] storage self, uint32 time) - internal - returns (uint16 cardinality, uint16 cardinalityNext) - { - self[0] = Observation({ - blockTimestamp: time, - tickCumulative: 0, - secondsPerLiquidityCumulativeX128: 0, - initialized: true - }); - return (1, 1); - } - - /// @notice Writes an oracle observation to the array - /// @dev Writable at most once per block. Index represents the most recently written element. cardinality and index must be tracked externally. - /// If the index is at the end of the allowable array length (according to cardinality), and the next cardinality - /// is greater than the current one, cardinality may be increased. This restriction is created to preserve ordering. - /// @param self The stored oracle array - /// @param index The index of the observation that was most recently written to the observations array - /// @param blockTimestamp The timestamp of the new observation - /// @param tick The active tick at the time of the new observation - /// @param liquidity The total in-range liquidity at the time of the new observation - /// @param cardinality The number of populated elements in the oracle array - /// @param cardinalityNext The new length of the oracle array, independent of population - /// @return indexUpdated The new index of the most recently written element in the oracle array - /// @return cardinalityUpdated The new cardinality of the oracle array - function write( - Observation[65535] storage self, - uint16 index, - uint32 blockTimestamp, - int24 tick, - uint128 liquidity, - uint16 cardinality, - uint16 cardinalityNext - ) internal returns (uint16 indexUpdated, uint16 cardinalityUpdated) { - Observation memory last = self[index]; - - // early return if we've already written an observation this block - if (last.blockTimestamp == blockTimestamp) return (index, cardinality); - - // if the conditions are right, we can bump the cardinality - if (cardinalityNext > cardinality && index == (cardinality - 1)) { - cardinalityUpdated = cardinalityNext; - } else { - cardinalityUpdated = cardinality; - } - - indexUpdated = (index + 1) % cardinalityUpdated; - self[indexUpdated] = transform(last, blockTimestamp, tick, liquidity); - } - - /// @notice Prepares the oracle array to store up to `next` observations - /// @param self The stored oracle array - /// @param current The current next cardinality of the oracle array - /// @param next The proposed next cardinality which will be populated in the oracle array - /// @return next The next cardinality which will be populated in the oracle array - function grow( - Observation[65535] storage self, - uint16 current, - uint16 next - ) internal returns (uint16) { - require(current > 0, 'I'); - // no-op if the passed next value isn't greater than the current next value - if (next <= current) return current; - // store in each slot to prevent fresh SSTOREs in swaps - // this data will not be used because the initialized boolean is still false - for (uint16 i = current; i < next; i++) self[i].blockTimestamp = 1; - return next; - } - - /// @notice comparator for 32-bit timestamps - /// @dev safe for 0 or 1 overflows, a and b _must_ be chronologically before or equal to time - /// @param time A timestamp truncated to 32 bits - /// @param a A comparison timestamp from which to determine the relative position of `time` - /// @param b From which to determine the relative position of `time` - /// @return bool Whether `a` is chronologically <= `b` - function lte( - uint32 time, - uint32 a, - uint32 b - ) private pure returns (bool) { - // if there hasn't been overflow, no need to adjust - if (a <= time && b <= time) return a <= b; - - uint256 aAdjusted = a > time ? a : a + 2**32; - uint256 bAdjusted = b > time ? b : b + 2**32; - - return aAdjusted <= bAdjusted; - } - - /// @notice Fetches the observations beforeOrAt and atOrAfter a target, i.e. where [beforeOrAt, atOrAfter] is satisfied. - /// The result may be the same observation, or adjacent observations. - /// @dev The answer must be contained in the array, used when the target is located within the stored observation - /// boundaries: older than the most recent observation and younger, or the same age as, the oldest observation - /// @param self The stored oracle array - /// @param time The current block.timestamp - /// @param target The timestamp at which the reserved observation should be for - /// @param index The index of the observation that was most recently written to the observations array - /// @param cardinality The number of populated elements in the oracle array - /// @return beforeOrAt The observation recorded before, or at, the target - /// @return atOrAfter The observation recorded at, or after, the target - function binarySearch( - Observation[65535] storage self, - uint32 time, - uint32 target, - uint16 index, - uint16 cardinality - ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) { - uint256 l = (index + 1) % cardinality; // oldest observation - uint256 r = l + cardinality - 1; // newest observation - uint256 i; - while (true) { - i = (l + r) / 2; - - beforeOrAt = self[i % cardinality]; - - // we've landed on an uninitialized tick, keep searching higher (more recently) - if (!beforeOrAt.initialized) { - l = i + 1; - continue; - } - - atOrAfter = self[(i + 1) % cardinality]; - - bool targetAtOrAfter = lte(time, beforeOrAt.blockTimestamp, target); - - // check if we've found the answer! - if (targetAtOrAfter && lte(time, target, atOrAfter.blockTimestamp)) break; - - if (!targetAtOrAfter) r = i - 1; - else l = i + 1; - } - } - - /// @notice Fetches the observations beforeOrAt and atOrAfter a given target, i.e. where [beforeOrAt, atOrAfter] is satisfied - /// @dev Assumes there is at least 1 initialized observation. - /// Used by observeSingle() to compute the counterfactual accumulator values as of a given block timestamp. - /// @param self The stored oracle array - /// @param time The current block.timestamp - /// @param target The timestamp at which the reserved observation should be for - /// @param tick The active tick at the time of the returned or simulated observation - /// @param index The index of the observation that was most recently written to the observations array - /// @param liquidity The total pool liquidity at the time of the call - /// @param cardinality The number of populated elements in the oracle array - /// @return beforeOrAt The observation which occurred at, or before, the given timestamp - /// @return atOrAfter The observation which occurred at, or after, the given timestamp - function getSurroundingObservations( - Observation[65535] storage self, - uint32 time, - uint32 target, - int24 tick, - uint16 index, - uint128 liquidity, - uint16 cardinality - ) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) { - // optimistically set before to the newest observation - beforeOrAt = self[index]; - - // if the target is chronologically at or after the newest observation, we can early return - if (lte(time, beforeOrAt.blockTimestamp, target)) { - if (beforeOrAt.blockTimestamp == target) { - // if newest observation equals target, we're in the same block, so we can ignore atOrAfter - return (beforeOrAt, atOrAfter); - } else { - // otherwise, we need to transform - return (beforeOrAt, transform(beforeOrAt, target, tick, liquidity)); - } - } - - // now, set before to the oldest observation - beforeOrAt = self[(index + 1) % cardinality]; - if (!beforeOrAt.initialized) beforeOrAt = self[0]; - - // ensure that the target is chronologically at or after the oldest observation - require(lte(time, beforeOrAt.blockTimestamp, target), 'OLD'); - - // if we've reached this point, we have to binary search - return binarySearch(self, time, target, index, cardinality); - } - - /// @dev Reverts if an observation at or before the desired observation timestamp does not exist. - /// 0 may be passed as `secondsAgo' to return the current cumulative values. - /// If called with a timestamp falling between two observations, returns the counterfactual accumulator values - /// at exactly the timestamp between the two observations. - /// @param self The stored oracle array - /// @param time The current block timestamp - /// @param secondsAgo The amount of time to look back, in seconds, at which point to return an observation - /// @param tick The current tick - /// @param index The index of the observation that was most recently written to the observations array - /// @param liquidity The current in-range pool liquidity - /// @param cardinality The number of populated elements in the oracle array - /// @return tickCumulative The tick * time elapsed since the pool was first initialized, as of `secondsAgo` - /// @return secondsPerLiquidityCumulativeX128 The time elapsed / max(1, liquidity) since the pool was first initialized, as of `secondsAgo` - function observeSingle( - Observation[65535] storage self, - uint32 time, - uint32 secondsAgo, - int24 tick, - uint16 index, - uint128 liquidity, - uint16 cardinality - ) internal view returns (int56 tickCumulative, uint160 secondsPerLiquidityCumulativeX128) { - if (secondsAgo == 0) { - Observation memory last = self[index]; - if (last.blockTimestamp != time) last = transform(last, time, tick, liquidity); - return (last.tickCumulative, last.secondsPerLiquidityCumulativeX128); - } - - uint32 target = time - secondsAgo; - - (Observation memory beforeOrAt, Observation memory atOrAfter) = - getSurroundingObservations(self, time, target, tick, index, liquidity, cardinality); - - if (target == beforeOrAt.blockTimestamp) { - // we're at the left boundary - return (beforeOrAt.tickCumulative, beforeOrAt.secondsPerLiquidityCumulativeX128); - } else if (target == atOrAfter.blockTimestamp) { - // we're at the right boundary - return (atOrAfter.tickCumulative, atOrAfter.secondsPerLiquidityCumulativeX128); - } else { - // we're in the middle - uint32 observationTimeDelta = atOrAfter.blockTimestamp - beforeOrAt.blockTimestamp; - uint32 targetDelta = target - beforeOrAt.blockTimestamp; - return ( - beforeOrAt.tickCumulative + - ((atOrAfter.tickCumulative - beforeOrAt.tickCumulative) / observationTimeDelta) * - targetDelta, - beforeOrAt.secondsPerLiquidityCumulativeX128 + - uint160( - (uint256( - atOrAfter.secondsPerLiquidityCumulativeX128 - beforeOrAt.secondsPerLiquidityCumulativeX128 - ) * targetDelta) / observationTimeDelta - ) - ); - } - } - - /// @notice Returns the accumulator values as of each time seconds ago from the given time in the array of `secondsAgos` - /// @dev Reverts if `secondsAgos` > oldest observation - /// @param self The stored oracle array - /// @param time The current block.timestamp - /// @param secondsAgos Each amount of time to look back, in seconds, at which point to return an observation - /// @param tick The current tick - /// @param index The index of the observation that was most recently written to the observations array - /// @param liquidity The current in-range pool liquidity - /// @param cardinality The number of populated elements in the oracle array - /// @return tickCumulatives The tick * time elapsed since the pool was first initialized, as of each `secondsAgo` - /// @return secondsPerLiquidityCumulativeX128s The cumulative seconds / max(1, liquidity) since the pool was first initialized, as of each `secondsAgo` - function observe( - Observation[65535] storage self, - uint32 time, - uint32[] memory secondsAgos, - int24 tick, - uint16 index, - uint128 liquidity, - uint16 cardinality - ) internal view returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s) { - require(cardinality > 0, 'I'); - - tickCumulatives = new int56[](secondsAgos.length); - secondsPerLiquidityCumulativeX128s = new uint160[](secondsAgos.length); - for (uint256 i = 0; i < secondsAgos.length; i++) { - (tickCumulatives[i], secondsPerLiquidityCumulativeX128s[i]) = observeSingle( - self, - time, - secondsAgos[i], - tick, - index, - liquidity, - cardinality - ); - } - } -} diff --git a/lib/v3-core/contracts/libraries/Position.sol b/lib/v3-core/contracts/libraries/Position.sol deleted file mode 100644 index 41829b0..0000000 --- a/lib/v3-core/contracts/libraries/Position.sol +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity >=0.5.0 <0.8.0; - -import './FullMath.sol'; -import './FixedPoint128.sol'; -import './LiquidityMath.sol'; - -/// @title Position -/// @notice Positions represent an owner address' liquidity between a lower and upper tick boundary -/// @dev Positions store additional state for tracking fees owed to the position -library Position { - // info stored for each user's position - struct Info { - // the amount of liquidity owned by this position - uint128 liquidity; - // fee growth per unit of liquidity as of the last update to liquidity or fees owed - uint256 feeGrowthInside0LastX128; - uint256 feeGrowthInside1LastX128; - // the fees owed to the position owner in token0/token1 - uint128 tokensOwed0; - uint128 tokensOwed1; - } - - /// @notice Returns the Info struct of a position, given an owner and position boundaries - /// @param self The mapping containing all user positions - /// @param owner The address of the position owner - /// @param tickLower The lower tick boundary of the position - /// @param tickUpper The upper tick boundary of the position - /// @return position The position info struct of the given owners' position - function get( - mapping(bytes32 => Info) storage self, - address owner, - int24 tickLower, - int24 tickUpper - ) internal view returns (Position.Info storage position) { - position = self[keccak256(abi.encodePacked(owner, tickLower, tickUpper))]; - } - - /// @notice Credits accumulated fees to a user's position - /// @param self The individual position to update - /// @param liquidityDelta The change in pool liquidity as a result of the position update - /// @param feeGrowthInside0X128 The all-time fee growth in token0, per unit of liquidity, inside the position's tick boundaries - /// @param feeGrowthInside1X128 The all-time fee growth in token1, per unit of liquidity, inside the position's tick boundaries - function update( - Info storage self, - int128 liquidityDelta, - uint256 feeGrowthInside0X128, - uint256 feeGrowthInside1X128 - ) internal { - Info memory _self = self; - - uint128 liquidityNext; - if (liquidityDelta == 0) { - require(_self.liquidity > 0, 'NP'); // disallow pokes for 0 liquidity positions - liquidityNext = _self.liquidity; - } else { - liquidityNext = LiquidityMath.addDelta(_self.liquidity, liquidityDelta); - } - - // calculate accumulated fees - uint128 tokensOwed0 = - uint128( - FullMath.mulDiv( - feeGrowthInside0X128 - _self.feeGrowthInside0LastX128, - _self.liquidity, - FixedPoint128.Q128 - ) - ); - uint128 tokensOwed1 = - uint128( - FullMath.mulDiv( - feeGrowthInside1X128 - _self.feeGrowthInside1LastX128, - _self.liquidity, - FixedPoint128.Q128 - ) - ); - - // update the position - if (liquidityDelta != 0) self.liquidity = liquidityNext; - self.feeGrowthInside0LastX128 = feeGrowthInside0X128; - self.feeGrowthInside1LastX128 = feeGrowthInside1X128; - if (tokensOwed0 > 0 || tokensOwed1 > 0) { - // overflow is acceptable, have to withdraw before you hit type(uint128).max fees - self.tokensOwed0 += tokensOwed0; - self.tokensOwed1 += tokensOwed1; - } - } -} diff --git a/lib/v3-core/contracts/libraries/SafeCast.sol b/lib/v3-core/contracts/libraries/SafeCast.sol deleted file mode 100644 index a8ea229..0000000 --- a/lib/v3-core/contracts/libraries/SafeCast.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title Safe casting methods -/// @notice Contains methods for safely casting between types -library SafeCast { - /// @notice Cast a uint256 to a uint160, revert on overflow - /// @param y The uint256 to be downcasted - /// @return z The downcasted integer, now type uint160 - function toUint160(uint256 y) internal pure returns (uint160 z) { - require((z = uint160(y)) == y); - } - - /// @notice Cast a int256 to a int128, revert on overflow or underflow - /// @param y The int256 to be downcasted - /// @return z The downcasted integer, now type int128 - function toInt128(int256 y) internal pure returns (int128 z) { - require((z = int128(y)) == y); - } - - /// @notice Cast a uint256 to a int256, revert on overflow - /// @param y The uint256 to be casted - /// @return z The casted integer, now type int256 - function toInt256(uint256 y) internal pure returns (int256 z) { - require(y < 2**255); - z = int256(y); - } -} diff --git a/lib/v3-core/contracts/libraries/SqrtPriceMath.sol b/lib/v3-core/contracts/libraries/SqrtPriceMath.sol deleted file mode 100644 index 685f485..0000000 --- a/lib/v3-core/contracts/libraries/SqrtPriceMath.sol +++ /dev/null @@ -1,227 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity >=0.5.0; - -import './LowGasSafeMath.sol'; -import './SafeCast.sol'; - -import './FullMath.sol'; -import './UnsafeMath.sol'; -import './FixedPoint96.sol'; - -/// @title Functions based on Q64.96 sqrt price and liquidity -/// @notice Contains the math that uses square root of price as a Q64.96 and liquidity to compute deltas -library SqrtPriceMath { - using LowGasSafeMath for uint256; - using SafeCast for uint256; - - /// @notice Gets the next sqrt price given a delta of token0 - /// @dev Always rounds up, because in the exact output case (increasing price) we need to move the price at least - /// far enough to get the desired output amount, and in the exact input case (decreasing price) we need to move the - /// price less in order to not send too much output. - /// The most precise formula for this is liquidity * sqrtPX96 / (liquidity +- amount * sqrtPX96), - /// if this is impossible because of overflow, we calculate liquidity / (liquidity / sqrtPX96 +- amount). - /// @param sqrtPX96 The starting price, i.e. before accounting for the token0 delta - /// @param liquidity The amount of usable liquidity - /// @param amount How much of token0 to add or remove from virtual reserves - /// @param add Whether to add or remove the amount of token0 - /// @return The price after adding or removing amount, depending on add - function getNextSqrtPriceFromAmount0RoundingUp( - uint160 sqrtPX96, - uint128 liquidity, - uint256 amount, - bool add - ) internal pure returns (uint160) { - // we short circuit amount == 0 because the result is otherwise not guaranteed to equal the input price - if (amount == 0) return sqrtPX96; - uint256 numerator1 = uint256(liquidity) << FixedPoint96.RESOLUTION; - - if (add) { - uint256 product; - if ((product = amount * sqrtPX96) / amount == sqrtPX96) { - uint256 denominator = numerator1 + product; - if (denominator >= numerator1) - // always fits in 160 bits - return uint160(FullMath.mulDivRoundingUp(numerator1, sqrtPX96, denominator)); - } - - return uint160(UnsafeMath.divRoundingUp(numerator1, (numerator1 / sqrtPX96).add(amount))); - } else { - uint256 product; - // if the product overflows, we know the denominator underflows - // in addition, we must check that the denominator does not underflow - require((product = amount * sqrtPX96) / amount == sqrtPX96 && numerator1 > product); - uint256 denominator = numerator1 - product; - return FullMath.mulDivRoundingUp(numerator1, sqrtPX96, denominator).toUint160(); - } - } - - /// @notice Gets the next sqrt price given a delta of token1 - /// @dev Always rounds down, because in the exact output case (decreasing price) we need to move the price at least - /// far enough to get the desired output amount, and in the exact input case (increasing price) we need to move the - /// price less in order to not send too much output. - /// The formula we compute is within <1 wei of the lossless version: sqrtPX96 +- amount / liquidity - /// @param sqrtPX96 The starting price, i.e., before accounting for the token1 delta - /// @param liquidity The amount of usable liquidity - /// @param amount How much of token1 to add, or remove, from virtual reserves - /// @param add Whether to add, or remove, the amount of token1 - /// @return The price after adding or removing `amount` - function getNextSqrtPriceFromAmount1RoundingDown( - uint160 sqrtPX96, - uint128 liquidity, - uint256 amount, - bool add - ) internal pure returns (uint160) { - // if we're adding (subtracting), rounding down requires rounding the quotient down (up) - // in both cases, avoid a mulDiv for most inputs - if (add) { - uint256 quotient = - ( - amount <= type(uint160).max - ? (amount << FixedPoint96.RESOLUTION) / liquidity - : FullMath.mulDiv(amount, FixedPoint96.Q96, liquidity) - ); - - return uint256(sqrtPX96).add(quotient).toUint160(); - } else { - uint256 quotient = - ( - amount <= type(uint160).max - ? UnsafeMath.divRoundingUp(amount << FixedPoint96.RESOLUTION, liquidity) - : FullMath.mulDivRoundingUp(amount, FixedPoint96.Q96, liquidity) - ); - - require(sqrtPX96 > quotient); - // always fits 160 bits - return uint160(sqrtPX96 - quotient); - } - } - - /// @notice Gets the next sqrt price given an input amount of token0 or token1 - /// @dev Throws if price or liquidity are 0, or if the next price is out of bounds - /// @param sqrtPX96 The starting price, i.e., before accounting for the input amount - /// @param liquidity The amount of usable liquidity - /// @param amountIn How much of token0, or token1, is being swapped in - /// @param zeroForOne Whether the amount in is token0 or token1 - /// @return sqrtQX96 The price after adding the input amount to token0 or token1 - function getNextSqrtPriceFromInput( - uint160 sqrtPX96, - uint128 liquidity, - uint256 amountIn, - bool zeroForOne - ) internal pure returns (uint160 sqrtQX96) { - require(sqrtPX96 > 0); - require(liquidity > 0); - - // round to make sure that we don't pass the target price - return - zeroForOne - ? getNextSqrtPriceFromAmount0RoundingUp(sqrtPX96, liquidity, amountIn, true) - : getNextSqrtPriceFromAmount1RoundingDown(sqrtPX96, liquidity, amountIn, true); - } - - /// @notice Gets the next sqrt price given an output amount of token0 or token1 - /// @dev Throws if price or liquidity are 0 or the next price is out of bounds - /// @param sqrtPX96 The starting price before accounting for the output amount - /// @param liquidity The amount of usable liquidity - /// @param amountOut How much of token0, or token1, is being swapped out - /// @param zeroForOne Whether the amount out is token0 or token1 - /// @return sqrtQX96 The price after removing the output amount of token0 or token1 - function getNextSqrtPriceFromOutput( - uint160 sqrtPX96, - uint128 liquidity, - uint256 amountOut, - bool zeroForOne - ) internal pure returns (uint160 sqrtQX96) { - require(sqrtPX96 > 0); - require(liquidity > 0); - - // round to make sure that we pass the target price - return - zeroForOne - ? getNextSqrtPriceFromAmount1RoundingDown(sqrtPX96, liquidity, amountOut, false) - : getNextSqrtPriceFromAmount0RoundingUp(sqrtPX96, liquidity, amountOut, false); - } - - /// @notice Gets the amount0 delta between two prices - /// @dev Calculates liquidity / sqrt(lower) - liquidity / sqrt(upper), - /// i.e. liquidity * (sqrt(upper) - sqrt(lower)) / (sqrt(upper) * sqrt(lower)) - /// @param sqrtRatioAX96 A sqrt price - /// @param sqrtRatioBX96 Another sqrt price - /// @param liquidity The amount of usable liquidity - /// @param roundUp Whether to round the amount up or down - /// @return amount0 Amount of token0 required to cover a position of size liquidity between the two passed prices - function getAmount0Delta( - uint160 sqrtRatioAX96, - uint160 sqrtRatioBX96, - uint128 liquidity, - bool roundUp - ) internal pure returns (uint256 amount0) { - if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96); - - uint256 numerator1 = uint256(liquidity) << FixedPoint96.RESOLUTION; - uint256 numerator2 = sqrtRatioBX96 - sqrtRatioAX96; - - require(sqrtRatioAX96 > 0); - - return - roundUp - ? UnsafeMath.divRoundingUp( - FullMath.mulDivRoundingUp(numerator1, numerator2, sqrtRatioBX96), - sqrtRatioAX96 - ) - : FullMath.mulDiv(numerator1, numerator2, sqrtRatioBX96) / sqrtRatioAX96; - } - - /// @notice Gets the amount1 delta between two prices - /// @dev Calculates liquidity * (sqrt(upper) - sqrt(lower)) - /// @param sqrtRatioAX96 A sqrt price - /// @param sqrtRatioBX96 Another sqrt price - /// @param liquidity The amount of usable liquidity - /// @param roundUp Whether to round the amount up, or down - /// @return amount1 Amount of token1 required to cover a position of size liquidity between the two passed prices - function getAmount1Delta( - uint160 sqrtRatioAX96, - uint160 sqrtRatioBX96, - uint128 liquidity, - bool roundUp - ) internal pure returns (uint256 amount1) { - if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96); - - return - roundUp - ? FullMath.mulDivRoundingUp(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96) - : FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96); - } - - /// @notice Helper that gets signed token0 delta - /// @param sqrtRatioAX96 A sqrt price - /// @param sqrtRatioBX96 Another sqrt price - /// @param liquidity The change in liquidity for which to compute the amount0 delta - /// @return amount0 Amount of token0 corresponding to the passed liquidityDelta between the two prices - function getAmount0Delta( - uint160 sqrtRatioAX96, - uint160 sqrtRatioBX96, - int128 liquidity - ) internal pure returns (int256 amount0) { - return - liquidity < 0 - ? -getAmount0Delta(sqrtRatioAX96, sqrtRatioBX96, uint128(-liquidity), false).toInt256() - : getAmount0Delta(sqrtRatioAX96, sqrtRatioBX96, uint128(liquidity), true).toInt256(); - } - - /// @notice Helper that gets signed token1 delta - /// @param sqrtRatioAX96 A sqrt price - /// @param sqrtRatioBX96 Another sqrt price - /// @param liquidity The change in liquidity for which to compute the amount1 delta - /// @return amount1 Amount of token1 corresponding to the passed liquidityDelta between the two prices - function getAmount1Delta( - uint160 sqrtRatioAX96, - uint160 sqrtRatioBX96, - int128 liquidity - ) internal pure returns (int256 amount1) { - return - liquidity < 0 - ? -getAmount1Delta(sqrtRatioAX96, sqrtRatioBX96, uint128(-liquidity), false).toInt256() - : getAmount1Delta(sqrtRatioAX96, sqrtRatioBX96, uint128(liquidity), true).toInt256(); - } -} diff --git a/lib/v3-core/contracts/libraries/SwapMath.sol b/lib/v3-core/contracts/libraries/SwapMath.sol deleted file mode 100644 index ee176fb..0000000 --- a/lib/v3-core/contracts/libraries/SwapMath.sol +++ /dev/null @@ -1,98 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity >=0.5.0; - -import './FullMath.sol'; -import './SqrtPriceMath.sol'; - -/// @title Computes the result of a swap within ticks -/// @notice Contains methods for computing the result of a swap within a single tick price range, i.e., a single tick. -library SwapMath { - /// @notice Computes the result of swapping some amount in, or amount out, given the parameters of the swap - /// @dev The fee, plus the amount in, will never exceed the amount remaining if the swap's `amountSpecified` is positive - /// @param sqrtRatioCurrentX96 The current sqrt price of the pool - /// @param sqrtRatioTargetX96 The price that cannot be exceeded, from which the direction of the swap is inferred - /// @param liquidity The usable liquidity - /// @param amountRemaining How much input or output amount is remaining to be swapped in/out - /// @param feePips The fee taken from the input amount, expressed in hundredths of a bip - /// @return sqrtRatioNextX96 The price after swapping the amount in/out, not to exceed the price target - /// @return amountIn The amount to be swapped in, of either token0 or token1, based on the direction of the swap - /// @return amountOut The amount to be received, of either token0 or token1, based on the direction of the swap - /// @return feeAmount The amount of input that will be taken as a fee - function computeSwapStep( - uint160 sqrtRatioCurrentX96, - uint160 sqrtRatioTargetX96, - uint128 liquidity, - int256 amountRemaining, - uint24 feePips - ) - internal - pure - returns ( - uint160 sqrtRatioNextX96, - uint256 amountIn, - uint256 amountOut, - uint256 feeAmount - ) - { - bool zeroForOne = sqrtRatioCurrentX96 >= sqrtRatioTargetX96; - bool exactIn = amountRemaining >= 0; - - if (exactIn) { - uint256 amountRemainingLessFee = FullMath.mulDiv(uint256(amountRemaining), 1e6 - feePips, 1e6); - amountIn = zeroForOne - ? SqrtPriceMath.getAmount0Delta(sqrtRatioTargetX96, sqrtRatioCurrentX96, liquidity, true) - : SqrtPriceMath.getAmount1Delta(sqrtRatioCurrentX96, sqrtRatioTargetX96, liquidity, true); - if (amountRemainingLessFee >= amountIn) sqrtRatioNextX96 = sqrtRatioTargetX96; - else - sqrtRatioNextX96 = SqrtPriceMath.getNextSqrtPriceFromInput( - sqrtRatioCurrentX96, - liquidity, - amountRemainingLessFee, - zeroForOne - ); - } else { - amountOut = zeroForOne - ? SqrtPriceMath.getAmount1Delta(sqrtRatioTargetX96, sqrtRatioCurrentX96, liquidity, false) - : SqrtPriceMath.getAmount0Delta(sqrtRatioCurrentX96, sqrtRatioTargetX96, liquidity, false); - if (uint256(-amountRemaining) >= amountOut) sqrtRatioNextX96 = sqrtRatioTargetX96; - else - sqrtRatioNextX96 = SqrtPriceMath.getNextSqrtPriceFromOutput( - sqrtRatioCurrentX96, - liquidity, - uint256(-amountRemaining), - zeroForOne - ); - } - - bool max = sqrtRatioTargetX96 == sqrtRatioNextX96; - - // get the input/output amounts - if (zeroForOne) { - amountIn = max && exactIn - ? amountIn - : SqrtPriceMath.getAmount0Delta(sqrtRatioNextX96, sqrtRatioCurrentX96, liquidity, true); - amountOut = max && !exactIn - ? amountOut - : SqrtPriceMath.getAmount1Delta(sqrtRatioNextX96, sqrtRatioCurrentX96, liquidity, false); - } else { - amountIn = max && exactIn - ? amountIn - : SqrtPriceMath.getAmount1Delta(sqrtRatioCurrentX96, sqrtRatioNextX96, liquidity, true); - amountOut = max && !exactIn - ? amountOut - : SqrtPriceMath.getAmount0Delta(sqrtRatioCurrentX96, sqrtRatioNextX96, liquidity, false); - } - - // cap the output amount to not exceed the remaining output amount - if (!exactIn && amountOut > uint256(-amountRemaining)) { - amountOut = uint256(-amountRemaining); - } - - if (exactIn && sqrtRatioNextX96 != sqrtRatioTargetX96) { - // we didn't reach the target, so take the remainder of the maximum input as fee - feeAmount = uint256(amountRemaining) - amountIn; - } else { - feeAmount = FullMath.mulDivRoundingUp(amountIn, feePips, 1e6 - feePips); - } - } -} diff --git a/lib/v3-core/contracts/libraries/Tick.sol b/lib/v3-core/contracts/libraries/Tick.sol deleted file mode 100644 index 7ceed03..0000000 --- a/lib/v3-core/contracts/libraries/Tick.sol +++ /dev/null @@ -1,185 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity >=0.5.0 <0.8.0; - -import './LowGasSafeMath.sol'; -import './SafeCast.sol'; - -import './TickMath.sol'; -import './LiquidityMath.sol'; - -/// @title Tick -/// @notice Contains functions for managing tick processes and relevant calculations -library Tick { - using LowGasSafeMath for int256; - using SafeCast for int256; - - // info stored for each initialized individual tick - struct Info { - // the total position liquidity that references this tick - uint128 liquidityGross; - // amount of net liquidity added (subtracted) when tick is crossed from left to right (right to left), - int128 liquidityNet; - // fee growth per unit of liquidity on the _other_ side of this tick (relative to the current tick) - // only has relative meaning, not absolute — the value depends on when the tick is initialized - uint256 feeGrowthOutside0X128; - uint256 feeGrowthOutside1X128; - // the cumulative tick value on the other side of the tick - int56 tickCumulativeOutside; - // the seconds per unit of liquidity on the _other_ side of this tick (relative to the current tick) - // only has relative meaning, not absolute — the value depends on when the tick is initialized - uint160 secondsPerLiquidityOutsideX128; - // the seconds spent on the other side of the tick (relative to the current tick) - // only has relative meaning, not absolute — the value depends on when the tick is initialized - uint32 secondsOutside; - // true iff the tick is initialized, i.e. the value is exactly equivalent to the expression liquidityGross != 0 - // these 8 bits are set to prevent fresh sstores when crossing newly initialized ticks - bool initialized; - } - - /// @notice Derives max liquidity per tick from given tick spacing - /// @dev Executed within the pool constructor - /// @param tickSpacing The amount of required tick separation, realized in multiples of `tickSpacing` - /// e.g., a tickSpacing of 3 requires ticks to be initialized every 3rd tick i.e., ..., -6, -3, 0, 3, 6, ... - /// @return The max liquidity per tick - function tickSpacingToMaxLiquidityPerTick(int24 tickSpacing) internal pure returns (uint128) { - int24 minTick = (TickMath.MIN_TICK / tickSpacing) * tickSpacing; - int24 maxTick = (TickMath.MAX_TICK / tickSpacing) * tickSpacing; - uint24 numTicks = uint24((maxTick - minTick) / tickSpacing) + 1; - return type(uint128).max / numTicks; - } - - /// @notice Retrieves fee growth data - /// @param self The mapping containing all tick information for initialized ticks - /// @param tickLower The lower tick boundary of the position - /// @param tickUpper The upper tick boundary of the position - /// @param tickCurrent The current tick - /// @param feeGrowthGlobal0X128 The all-time global fee growth, per unit of liquidity, in token0 - /// @param feeGrowthGlobal1X128 The all-time global fee growth, per unit of liquidity, in token1 - /// @return feeGrowthInside0X128 The all-time fee growth in token0, per unit of liquidity, inside the position's tick boundaries - /// @return feeGrowthInside1X128 The all-time fee growth in token1, per unit of liquidity, inside the position's tick boundaries - function getFeeGrowthInside( - mapping(int24 => Tick.Info) storage self, - int24 tickLower, - int24 tickUpper, - int24 tickCurrent, - uint256 feeGrowthGlobal0X128, - uint256 feeGrowthGlobal1X128 - ) internal view returns (uint256 feeGrowthInside0X128, uint256 feeGrowthInside1X128) { - Info storage lower = self[tickLower]; - Info storage upper = self[tickUpper]; - - // calculate fee growth below - uint256 feeGrowthBelow0X128; - uint256 feeGrowthBelow1X128; - if (tickCurrent >= tickLower) { - feeGrowthBelow0X128 = lower.feeGrowthOutside0X128; - feeGrowthBelow1X128 = lower.feeGrowthOutside1X128; - } else { - feeGrowthBelow0X128 = feeGrowthGlobal0X128 - lower.feeGrowthOutside0X128; - feeGrowthBelow1X128 = feeGrowthGlobal1X128 - lower.feeGrowthOutside1X128; - } - - // calculate fee growth above - uint256 feeGrowthAbove0X128; - uint256 feeGrowthAbove1X128; - if (tickCurrent < tickUpper) { - feeGrowthAbove0X128 = upper.feeGrowthOutside0X128; - feeGrowthAbove1X128 = upper.feeGrowthOutside1X128; - } else { - feeGrowthAbove0X128 = feeGrowthGlobal0X128 - upper.feeGrowthOutside0X128; - feeGrowthAbove1X128 = feeGrowthGlobal1X128 - upper.feeGrowthOutside1X128; - } - - feeGrowthInside0X128 = feeGrowthGlobal0X128 - feeGrowthBelow0X128 - feeGrowthAbove0X128; - feeGrowthInside1X128 = feeGrowthGlobal1X128 - feeGrowthBelow1X128 - feeGrowthAbove1X128; - } - - /// @notice Updates a tick and returns true if the tick was flipped from initialized to uninitialized, or vice versa - /// @param self The mapping containing all tick information for initialized ticks - /// @param tick The tick that will be updated - /// @param tickCurrent The current tick - /// @param liquidityDelta A new amount of liquidity to be added (subtracted) when tick is crossed from left to right (right to left) - /// @param feeGrowthGlobal0X128 The all-time global fee growth, per unit of liquidity, in token0 - /// @param feeGrowthGlobal1X128 The all-time global fee growth, per unit of liquidity, in token1 - /// @param secondsPerLiquidityCumulativeX128 The all-time seconds per max(1, liquidity) of the pool - /// @param tickCumulative The tick * time elapsed since the pool was first initialized - /// @param time The current block timestamp cast to a uint32 - /// @param upper true for updating a position's upper tick, or false for updating a position's lower tick - /// @param maxLiquidity The maximum liquidity allocation for a single tick - /// @return flipped Whether the tick was flipped from initialized to uninitialized, or vice versa - function update( - mapping(int24 => Tick.Info) storage self, - int24 tick, - int24 tickCurrent, - int128 liquidityDelta, - uint256 feeGrowthGlobal0X128, - uint256 feeGrowthGlobal1X128, - uint160 secondsPerLiquidityCumulativeX128, - int56 tickCumulative, - uint32 time, - bool upper, - uint128 maxLiquidity - ) internal returns (bool flipped) { - Tick.Info storage info = self[tick]; - - uint128 liquidityGrossBefore = info.liquidityGross; - uint128 liquidityGrossAfter = LiquidityMath.addDelta(liquidityGrossBefore, liquidityDelta); - - require(liquidityGrossAfter <= maxLiquidity, 'LO'); - - flipped = (liquidityGrossAfter == 0) != (liquidityGrossBefore == 0); - - if (liquidityGrossBefore == 0) { - // by convention, we assume that all growth before a tick was initialized happened _below_ the tick - if (tick <= tickCurrent) { - info.feeGrowthOutside0X128 = feeGrowthGlobal0X128; - info.feeGrowthOutside1X128 = feeGrowthGlobal1X128; - info.secondsPerLiquidityOutsideX128 = secondsPerLiquidityCumulativeX128; - info.tickCumulativeOutside = tickCumulative; - info.secondsOutside = time; - } - info.initialized = true; - } - - info.liquidityGross = liquidityGrossAfter; - - // when the lower (upper) tick is crossed left to right (right to left), liquidity must be added (removed) - info.liquidityNet = upper - ? int256(info.liquidityNet).sub(liquidityDelta).toInt128() - : int256(info.liquidityNet).add(liquidityDelta).toInt128(); - } - - /// @notice Clears tick data - /// @param self The mapping containing all initialized tick information for initialized ticks - /// @param tick The tick that will be cleared - function clear(mapping(int24 => Tick.Info) storage self, int24 tick) internal { - delete self[tick]; - } - - /// @notice Transitions to next tick as needed by price movement - /// @param self The mapping containing all tick information for initialized ticks - /// @param tick The destination tick of the transition - /// @param feeGrowthGlobal0X128 The all-time global fee growth, per unit of liquidity, in token0 - /// @param feeGrowthGlobal1X128 The all-time global fee growth, per unit of liquidity, in token1 - /// @param secondsPerLiquidityCumulativeX128 The current seconds per liquidity - /// @param tickCumulative The tick * time elapsed since the pool was first initialized - /// @param time The current block.timestamp - /// @return liquidityNet The amount of liquidity added (subtracted) when tick is crossed from left to right (right to left) - function cross( - mapping(int24 => Tick.Info) storage self, - int24 tick, - uint256 feeGrowthGlobal0X128, - uint256 feeGrowthGlobal1X128, - uint160 secondsPerLiquidityCumulativeX128, - int56 tickCumulative, - uint32 time - ) internal returns (int128 liquidityNet) { - Tick.Info storage info = self[tick]; - info.feeGrowthOutside0X128 = feeGrowthGlobal0X128 - info.feeGrowthOutside0X128; - info.feeGrowthOutside1X128 = feeGrowthGlobal1X128 - info.feeGrowthOutside1X128; - info.secondsPerLiquidityOutsideX128 = secondsPerLiquidityCumulativeX128 - info.secondsPerLiquidityOutsideX128; - info.tickCumulativeOutside = tickCumulative - info.tickCumulativeOutside; - info.secondsOutside = time - info.secondsOutside; - liquidityNet = info.liquidityNet; - } -} diff --git a/lib/v3-core/contracts/libraries/TickBitmap.sol b/lib/v3-core/contracts/libraries/TickBitmap.sol deleted file mode 100644 index 3c43585..0000000 --- a/lib/v3-core/contracts/libraries/TickBitmap.sol +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity >=0.5.0; - -import './BitMath.sol'; - -/// @title Packed tick initialized state library -/// @notice Stores a packed mapping of tick index to its initialized state -/// @dev The mapping uses int16 for keys since ticks are represented as int24 and there are 256 (2^8) values per word. -library TickBitmap { - /// @notice Computes the position in the mapping where the initialized bit for a tick lives - /// @param tick The tick for which to compute the position - /// @return wordPos The key in the mapping containing the word in which the bit is stored - /// @return bitPos The bit position in the word where the flag is stored - function position(int24 tick) private pure returns (int16 wordPos, uint8 bitPos) { - wordPos = int16(tick >> 8); - bitPos = uint8(tick % 256); - } - - /// @notice Flips the initialized state for a given tick from false to true, or vice versa - /// @param self The mapping in which to flip the tick - /// @param tick The tick to flip - /// @param tickSpacing The spacing between usable ticks - function flipTick( - mapping(int16 => uint256) storage self, - int24 tick, - int24 tickSpacing - ) internal { - require(tick % tickSpacing == 0); // ensure that the tick is spaced - (int16 wordPos, uint8 bitPos) = position(tick / tickSpacing); - uint256 mask = 1 << bitPos; - self[wordPos] ^= mask; - } - - /// @notice Returns the next initialized tick contained in the same word (or adjacent word) as the tick that is either - /// to the left (less than or equal to) or right (greater than) of the given tick - /// @param self The mapping in which to compute the next initialized tick - /// @param tick The starting tick - /// @param tickSpacing The spacing between usable ticks - /// @param lte Whether to search for the next initialized tick to the left (less than or equal to the starting tick) - /// @return next The next initialized or uninitialized tick up to 256 ticks away from the current tick - /// @return initialized Whether the next tick is initialized, as the function only searches within up to 256 ticks - function nextInitializedTickWithinOneWord( - mapping(int16 => uint256) storage self, - int24 tick, - int24 tickSpacing, - bool lte - ) internal view returns (int24 next, bool initialized) { - int24 compressed = tick / tickSpacing; - if (tick < 0 && tick % tickSpacing != 0) compressed--; // round towards negative infinity - - if (lte) { - (int16 wordPos, uint8 bitPos) = position(compressed); - // all the 1s at or to the right of the current bitPos - uint256 mask = (1 << bitPos) - 1 + (1 << bitPos); - uint256 masked = self[wordPos] & mask; - - // if there are no initialized ticks to the right of or at the current tick, return rightmost in the word - initialized = masked != 0; - // overflow/underflow is possible, but prevented externally by limiting both tickSpacing and tick - next = initialized - ? (compressed - int24(bitPos - BitMath.mostSignificantBit(masked))) * tickSpacing - : (compressed - int24(bitPos)) * tickSpacing; - } else { - // start from the word of the next tick, since the current tick state doesn't matter - (int16 wordPos, uint8 bitPos) = position(compressed + 1); - // all the 1s at or to the left of the bitPos - uint256 mask = ~((1 << bitPos) - 1); - uint256 masked = self[wordPos] & mask; - - // if there are no initialized ticks to the left of the current tick, return leftmost in the word - initialized = masked != 0; - // overflow/underflow is possible, but prevented externally by limiting both tickSpacing and tick - next = initialized - ? (compressed + 1 + int24(BitMath.leastSignificantBit(masked) - bitPos)) * tickSpacing - : (compressed + 1 + int24(type(uint8).max - bitPos)) * tickSpacing; - } - } -} diff --git a/lib/v3-core/contracts/libraries/TickMath.sol b/lib/v3-core/contracts/libraries/TickMath.sol deleted file mode 100644 index ee48fee..0000000 --- a/lib/v3-core/contracts/libraries/TickMath.sol +++ /dev/null @@ -1,205 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0 <0.8.0; - -/// @title Math library for computing sqrt prices from ticks and vice versa -/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports -/// prices between 2**-128 and 2**128 -library TickMath { - /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128 - int24 internal constant MIN_TICK = -887272; - /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128 - int24 internal constant MAX_TICK = -MIN_TICK; - - /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK) - uint160 internal constant MIN_SQRT_RATIO = 4295128739; - /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK) - uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342; - - /// @notice Calculates sqrt(1.0001^tick) * 2^96 - /// @dev Throws if |tick| > max tick - /// @param tick The input tick for the above formula - /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0) - /// at the given tick - function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) { - uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick)); - require(absTick <= uint256(MAX_TICK), 'T'); - - uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000; - if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128; - if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128; - if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128; - if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128; - if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128; - if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128; - if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128; - if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128; - if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128; - if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128; - if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128; - if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128; - if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128; - if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128; - if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128; - if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128; - if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128; - if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128; - if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128; - - if (tick > 0) ratio = type(uint256).max / ratio; - - // this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96. - // we then downcast because we know the result always fits within 160 bits due to our tick input constraint - // we round up in the division so getTickAtSqrtRatio of the output price is always consistent - sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1)); - } - - /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio - /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may - /// ever return. - /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96 - /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio - function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) { - // second inequality must be < because the price can never reach the price at the max tick - require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, 'R'); - uint256 ratio = uint256(sqrtPriceX96) << 32; - - uint256 r = ratio; - uint256 msb = 0; - - assembly { - let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) - msb := or(msb, f) - r := shr(f, r) - } - assembly { - let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF)) - msb := or(msb, f) - r := shr(f, r) - } - assembly { - let f := shl(5, gt(r, 0xFFFFFFFF)) - msb := or(msb, f) - r := shr(f, r) - } - assembly { - let f := shl(4, gt(r, 0xFFFF)) - msb := or(msb, f) - r := shr(f, r) - } - assembly { - let f := shl(3, gt(r, 0xFF)) - msb := or(msb, f) - r := shr(f, r) - } - assembly { - let f := shl(2, gt(r, 0xF)) - msb := or(msb, f) - r := shr(f, r) - } - assembly { - let f := shl(1, gt(r, 0x3)) - msb := or(msb, f) - r := shr(f, r) - } - assembly { - let f := gt(r, 0x1) - msb := or(msb, f) - } - - if (msb >= 128) r = ratio >> (msb - 127); - else r = ratio << (127 - msb); - - int256 log_2 = (int256(msb) - 128) << 64; - - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(63, f)) - r := shr(f, r) - } - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(62, f)) - r := shr(f, r) - } - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(61, f)) - r := shr(f, r) - } - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(60, f)) - r := shr(f, r) - } - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(59, f)) - r := shr(f, r) - } - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(58, f)) - r := shr(f, r) - } - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(57, f)) - r := shr(f, r) - } - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(56, f)) - r := shr(f, r) - } - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(55, f)) - r := shr(f, r) - } - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(54, f)) - r := shr(f, r) - } - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(53, f)) - r := shr(f, r) - } - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(52, f)) - r := shr(f, r) - } - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(51, f)) - r := shr(f, r) - } - assembly { - r := shr(127, mul(r, r)) - let f := shr(128, r) - log_2 := or(log_2, shl(50, f)) - } - - int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number - - int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128); - int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128); - - tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow; - } -} diff --git a/lib/v3-core/contracts/libraries/TransferHelper.sol b/lib/v3-core/contracts/libraries/TransferHelper.sol deleted file mode 100644 index 25d6309..0000000 --- a/lib/v3-core/contracts/libraries/TransferHelper.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.6.0; - -import '../interfaces/IERC20Minimal.sol'; - -/// @title TransferHelper -/// @notice Contains helper methods for interacting with ERC20 tokens that do not consistently return true/false -library TransferHelper { - /// @notice Transfers tokens from msg.sender to a recipient - /// @dev Calls transfer on token contract, errors with TF if transfer fails - /// @param token The contract address of the token which will be transferred - /// @param to The recipient of the transfer - /// @param value The value of the transfer - function safeTransfer( - address token, - address to, - uint256 value - ) internal { - (bool success, bytes memory data) = - token.call(abi.encodeWithSelector(IERC20Minimal.transfer.selector, to, value)); - require(success && (data.length == 0 || abi.decode(data, (bool))), 'TF'); - } -} diff --git a/lib/v3-core/contracts/libraries/UnsafeMath.sol b/lib/v3-core/contracts/libraries/UnsafeMath.sol deleted file mode 100644 index f62f846..0000000 --- a/lib/v3-core/contracts/libraries/UnsafeMath.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title Math functions that do not check inputs or outputs -/// @notice Contains methods that perform common math functions but do not do any overflow or underflow checks -library UnsafeMath { - /// @notice Returns ceil(x / y) - /// @dev division by 0 has unspecified behavior, and must be checked externally - /// @param x The dividend - /// @param y The divisor - /// @return z The quotient, ceil(x / y) - function divRoundingUp(uint256 x, uint256 y) internal pure returns (uint256 z) { - assembly { - z := add(div(x, y), gt(mod(x, y), 0)) - } - } -} diff --git a/lib/v3-core/contracts/test/BitMathEchidnaTest.sol b/lib/v3-core/contracts/test/BitMathEchidnaTest.sol deleted file mode 100644 index ca7d34f..0000000 --- a/lib/v3-core/contracts/test/BitMathEchidnaTest.sol +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../libraries/BitMath.sol'; - -contract BitMathEchidnaTest { - function mostSignificantBitInvariant(uint256 input) external pure { - uint8 msb = BitMath.mostSignificantBit(input); - assert(input >= (uint256(2)**msb)); - assert(msb == 255 || input < uint256(2)**(msb + 1)); - } - - function leastSignificantBitInvariant(uint256 input) external pure { - uint8 lsb = BitMath.leastSignificantBit(input); - assert(input & (uint256(2)**lsb) != 0); - assert(input & (uint256(2)**lsb - 1) == 0); - } -} diff --git a/lib/v3-core/contracts/test/BitMathTest.sol b/lib/v3-core/contracts/test/BitMathTest.sol deleted file mode 100644 index 2b387be..0000000 --- a/lib/v3-core/contracts/test/BitMathTest.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../libraries/BitMath.sol'; - -contract BitMathTest { - function mostSignificantBit(uint256 x) external pure returns (uint8 r) { - return BitMath.mostSignificantBit(x); - } - - function getGasCostOfMostSignificantBit(uint256 x) external view returns (uint256) { - uint256 gasBefore = gasleft(); - BitMath.mostSignificantBit(x); - return gasBefore - gasleft(); - } - - function leastSignificantBit(uint256 x) external pure returns (uint8 r) { - return BitMath.leastSignificantBit(x); - } - - function getGasCostOfLeastSignificantBit(uint256 x) external view returns (uint256) { - uint256 gasBefore = gasleft(); - BitMath.leastSignificantBit(x); - return gasBefore - gasleft(); - } -} diff --git a/lib/v3-core/contracts/test/FullMathEchidnaTest.sol b/lib/v3-core/contracts/test/FullMathEchidnaTest.sol deleted file mode 100644 index 9e1063d..0000000 --- a/lib/v3-core/contracts/test/FullMathEchidnaTest.sol +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../libraries/FullMath.sol'; - -contract FullMathEchidnaTest { - function checkMulDivRounding( - uint256 x, - uint256 y, - uint256 d - ) external pure { - require(d > 0); - - uint256 ceiled = FullMath.mulDivRoundingUp(x, y, d); - uint256 floored = FullMath.mulDiv(x, y, d); - - if (mulmod(x, y, d) > 0) { - assert(ceiled - floored == 1); - } else { - assert(ceiled == floored); - } - } - - function checkMulDiv( - uint256 x, - uint256 y, - uint256 d - ) external pure { - require(d > 0); - uint256 z = FullMath.mulDiv(x, y, d); - if (x == 0 || y == 0) { - assert(z == 0); - return; - } - - // recompute x and y via mulDiv of the result of floor(x*y/d), should always be less than original inputs by < d - uint256 x2 = FullMath.mulDiv(z, d, y); - uint256 y2 = FullMath.mulDiv(z, d, x); - assert(x2 <= x); - assert(y2 <= y); - - assert(x - x2 < d); - assert(y - y2 < d); - } - - function checkMulDivRoundingUp( - uint256 x, - uint256 y, - uint256 d - ) external pure { - require(d > 0); - uint256 z = FullMath.mulDivRoundingUp(x, y, d); - if (x == 0 || y == 0) { - assert(z == 0); - return; - } - - // recompute x and y via mulDiv of the result of floor(x*y/d), should always be less than original inputs by < d - uint256 x2 = FullMath.mulDiv(z, d, y); - uint256 y2 = FullMath.mulDiv(z, d, x); - assert(x2 >= x); - assert(y2 >= y); - - assert(x2 - x < d); - assert(y2 - y < d); - } -} diff --git a/lib/v3-core/contracts/test/FullMathTest.sol b/lib/v3-core/contracts/test/FullMathTest.sol deleted file mode 100644 index ec59bc9..0000000 --- a/lib/v3-core/contracts/test/FullMathTest.sol +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../libraries/FullMath.sol'; - -contract FullMathTest { - function mulDiv( - uint256 x, - uint256 y, - uint256 z - ) external pure returns (uint256) { - return FullMath.mulDiv(x, y, z); - } - - function mulDivRoundingUp( - uint256 x, - uint256 y, - uint256 z - ) external pure returns (uint256) { - return FullMath.mulDivRoundingUp(x, y, z); - } -} diff --git a/lib/v3-core/contracts/test/LiquidityMathTest.sol b/lib/v3-core/contracts/test/LiquidityMathTest.sol deleted file mode 100644 index d85e0f1..0000000 --- a/lib/v3-core/contracts/test/LiquidityMathTest.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../libraries/LiquidityMath.sol'; - -contract LiquidityMathTest { - function addDelta(uint128 x, int128 y) external pure returns (uint128 z) { - return LiquidityMath.addDelta(x, y); - } - - function getGasCostOfAddDelta(uint128 x, int128 y) external view returns (uint256) { - uint256 gasBefore = gasleft(); - LiquidityMath.addDelta(x, y); - return gasBefore - gasleft(); - } -} diff --git a/lib/v3-core/contracts/test/LowGasSafeMathEchidnaTest.sol b/lib/v3-core/contracts/test/LowGasSafeMathEchidnaTest.sol deleted file mode 100644 index 315531d..0000000 --- a/lib/v3-core/contracts/test/LowGasSafeMathEchidnaTest.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../libraries/LowGasSafeMath.sol'; - -contract LowGasSafeMathEchidnaTest { - function checkAdd(uint256 x, uint256 y) external pure { - uint256 z = LowGasSafeMath.add(x, y); - assert(z == x + y); - assert(z >= x && z >= y); - } - - function checkSub(uint256 x, uint256 y) external pure { - uint256 z = LowGasSafeMath.sub(x, y); - assert(z == x - y); - assert(z <= x); - } - - function checkMul(uint256 x, uint256 y) external pure { - uint256 z = LowGasSafeMath.mul(x, y); - assert(z == x * y); - assert(x == 0 || y == 0 || (z >= x && z >= y)); - } - - function checkAddi(int256 x, int256 y) external pure { - int256 z = LowGasSafeMath.add(x, y); - assert(z == x + y); - assert(y < 0 ? z < x : z >= x); - } - - function checkSubi(int256 x, int256 y) external pure { - int256 z = LowGasSafeMath.sub(x, y); - assert(z == x - y); - assert(y < 0 ? z > x : z <= x); - } -} diff --git a/lib/v3-core/contracts/test/MockTimeUniswapV3Pool.sol b/lib/v3-core/contracts/test/MockTimeUniswapV3Pool.sol deleted file mode 100644 index 66d2566..0000000 --- a/lib/v3-core/contracts/test/MockTimeUniswapV3Pool.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../UniswapV3Pool.sol'; - -// used for testing time dependent behavior -contract MockTimeUniswapV3Pool is UniswapV3Pool { - // Monday, October 5, 2020 9:00:00 AM GMT-05:00 - uint256 public time = 1601906400; - - function setFeeGrowthGlobal0X128(uint256 _feeGrowthGlobal0X128) external { - feeGrowthGlobal0X128 = _feeGrowthGlobal0X128; - } - - function setFeeGrowthGlobal1X128(uint256 _feeGrowthGlobal1X128) external { - feeGrowthGlobal1X128 = _feeGrowthGlobal1X128; - } - - function advanceTime(uint256 by) external { - time += by; - } - - function _blockTimestamp() internal view override returns (uint32) { - return uint32(time); - } -} diff --git a/lib/v3-core/contracts/test/MockTimeUniswapV3PoolDeployer.sol b/lib/v3-core/contracts/test/MockTimeUniswapV3PoolDeployer.sol deleted file mode 100644 index a274fb7..0000000 --- a/lib/v3-core/contracts/test/MockTimeUniswapV3PoolDeployer.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../interfaces/IUniswapV3PoolDeployer.sol'; - -import './MockTimeUniswapV3Pool.sol'; - -contract MockTimeUniswapV3PoolDeployer is IUniswapV3PoolDeployer { - struct Parameters { - address factory; - address token0; - address token1; - uint24 fee; - int24 tickSpacing; - } - - Parameters public override parameters; - - event PoolDeployed(address pool); - - function deploy( - address factory, - address token0, - address token1, - uint24 fee, - int24 tickSpacing - ) external returns (address pool) { - parameters = Parameters({factory: factory, token0: token0, token1: token1, fee: fee, tickSpacing: tickSpacing}); - pool = address( - new MockTimeUniswapV3Pool{salt: keccak256(abi.encodePacked(token0, token1, fee, tickSpacing))}() - ); - emit PoolDeployed(pool); - delete parameters; - } -} diff --git a/lib/v3-core/contracts/test/NoDelegateCallTest.sol b/lib/v3-core/contracts/test/NoDelegateCallTest.sol deleted file mode 100644 index 8830d5c..0000000 --- a/lib/v3-core/contracts/test/NoDelegateCallTest.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../NoDelegateCall.sol'; - -contract NoDelegateCallTest is NoDelegateCall { - function canBeDelegateCalled() public view returns (uint256) { - return block.timestamp / 5; - } - - function cannotBeDelegateCalled() public view noDelegateCall returns (uint256) { - return block.timestamp / 5; - } - - function getGasCostOfCanBeDelegateCalled() external view returns (uint256) { - uint256 gasBefore = gasleft(); - canBeDelegateCalled(); - return gasBefore - gasleft(); - } - - function getGasCostOfCannotBeDelegateCalled() external view returns (uint256) { - uint256 gasBefore = gasleft(); - cannotBeDelegateCalled(); - return gasBefore - gasleft(); - } - - function callsIntoNoDelegateCallFunction() external view { - noDelegateCallPrivate(); - } - - function noDelegateCallPrivate() private view noDelegateCall {} -} diff --git a/lib/v3-core/contracts/test/OracleEchidnaTest.sol b/lib/v3-core/contracts/test/OracleEchidnaTest.sol deleted file mode 100644 index 2cf5f2e..0000000 --- a/lib/v3-core/contracts/test/OracleEchidnaTest.sol +++ /dev/null @@ -1,137 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; -pragma abicoder v2; - -import './OracleTest.sol'; - -contract OracleEchidnaTest { - OracleTest private oracle; - - bool private initialized; - uint32 private timePassed; - - constructor() { - oracle = new OracleTest(); - } - - function initialize( - uint32 time, - int24 tick, - uint128 liquidity - ) external { - oracle.initialize(OracleTest.InitializeParams({time: time, tick: tick, liquidity: liquidity})); - initialized = true; - } - - function limitTimePassed(uint32 by) private { - require(timePassed + by >= timePassed); - timePassed += by; - } - - function advanceTime(uint32 by) public { - limitTimePassed(by); - oracle.advanceTime(by); - } - - // write an observation, then change tick and liquidity - function update( - uint32 advanceTimeBy, - int24 tick, - uint128 liquidity - ) external { - limitTimePassed(advanceTimeBy); - oracle.update(OracleTest.UpdateParams({advanceTimeBy: advanceTimeBy, tick: tick, liquidity: liquidity})); - } - - function grow(uint16 cardinality) external { - oracle.grow(cardinality); - } - - function checkTimeWeightedResultAssertions(uint32 secondsAgo0, uint32 secondsAgo1) private view { - require(secondsAgo0 != secondsAgo1); - require(initialized); - // secondsAgo0 should be the larger one - if (secondsAgo0 < secondsAgo1) (secondsAgo0, secondsAgo1) = (secondsAgo1, secondsAgo0); - - uint32 timeElapsed = secondsAgo0 - secondsAgo1; - - uint32[] memory secondsAgos = new uint32[](2); - secondsAgos[0] = secondsAgo0; - secondsAgos[1] = secondsAgo1; - - (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s) = - oracle.observe(secondsAgos); - int56 timeWeightedTick = (tickCumulatives[1] - tickCumulatives[0]) / timeElapsed; - uint256 timeWeightedHarmonicMeanLiquidity = - (uint256(timeElapsed) * type(uint160).max) / - (uint256(secondsPerLiquidityCumulativeX128s[1] - secondsPerLiquidityCumulativeX128s[0]) << 32); - assert(timeWeightedHarmonicMeanLiquidity <= type(uint128).max); - assert(timeWeightedTick <= type(int24).max); - assert(timeWeightedTick >= type(int24).min); - } - - function echidna_indexAlwaysLtCardinality() external view returns (bool) { - return oracle.index() < oracle.cardinality() || !initialized; - } - - function echidna_AlwaysInitialized() external view returns (bool) { - (, , , bool isInitialized) = oracle.observations(0); - return oracle.cardinality() == 0 || isInitialized; - } - - function echidna_cardinalityAlwaysLteNext() external view returns (bool) { - return oracle.cardinality() <= oracle.cardinalityNext(); - } - - function echidna_canAlwaysObserve0IfInitialized() external view returns (bool) { - if (!initialized) { - return true; - } - uint32[] memory arr = new uint32[](1); - arr[0] = 0; - (bool success, ) = address(oracle).staticcall(abi.encodeWithSelector(OracleTest.observe.selector, arr)); - return success; - } - - function checkTwoAdjacentObservationsTickCumulativeModTimeElapsedAlways0(uint16 index) external view { - uint16 cardinality = oracle.cardinality(); - // check that the observations are initialized, and that the index is not the oldest observation - require(index < cardinality && index != (oracle.index() + 1) % cardinality); - - (uint32 blockTimestamp0, int56 tickCumulative0, , bool initialized0) = - oracle.observations(index == 0 ? cardinality - 1 : index - 1); - (uint32 blockTimestamp1, int56 tickCumulative1, , bool initialized1) = oracle.observations(index); - - require(initialized0); - require(initialized1); - - uint32 timeElapsed = blockTimestamp1 - blockTimestamp0; - assert(timeElapsed > 0); - assert((tickCumulative1 - tickCumulative0) % timeElapsed == 0); - } - - function checkTimeWeightedAveragesAlwaysFitsType(uint32 secondsAgo) external view { - require(initialized); - require(secondsAgo > 0); - uint32[] memory secondsAgos = new uint32[](2); - secondsAgos[0] = secondsAgo; - secondsAgos[1] = 0; - (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s) = - oracle.observe(secondsAgos); - - // compute the time weighted tick, rounded towards negative infinity - int56 numerator = tickCumulatives[1] - tickCumulatives[0]; - int56 timeWeightedTick = numerator / int56(secondsAgo); - if (numerator < 0 && numerator % int56(secondsAgo) != 0) { - timeWeightedTick--; - } - - // the time weighted averages fit in their respective accumulated types - assert(timeWeightedTick <= type(int24).max && timeWeightedTick >= type(int24).min); - - uint256 timeWeightedHarmonicMeanLiquidity = - (uint256(secondsAgo) * type(uint160).max) / - (uint256(secondsPerLiquidityCumulativeX128s[1] - secondsPerLiquidityCumulativeX128s[0]) << 32); - assert(timeWeightedHarmonicMeanLiquidity <= type(uint128).max); - } -} diff --git a/lib/v3-core/contracts/test/OracleTest.sol b/lib/v3-core/contracts/test/OracleTest.sol deleted file mode 100644 index c0c83b1..0000000 --- a/lib/v3-core/contracts/test/OracleTest.sol +++ /dev/null @@ -1,100 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; -pragma abicoder v2; - -import '../libraries/Oracle.sol'; - -contract OracleTest { - using Oracle for Oracle.Observation[65535]; - - Oracle.Observation[65535] public observations; - - uint32 public time; - int24 public tick; - uint128 public liquidity; - uint16 public index; - uint16 public cardinality; - uint16 public cardinalityNext; - - struct InitializeParams { - uint32 time; - int24 tick; - uint128 liquidity; - } - - function initialize(InitializeParams calldata params) external { - require(cardinality == 0, 'already initialized'); - time = params.time; - tick = params.tick; - liquidity = params.liquidity; - (cardinality, cardinalityNext) = observations.initialize(params.time); - } - - function advanceTime(uint32 by) public { - time += by; - } - - struct UpdateParams { - uint32 advanceTimeBy; - int24 tick; - uint128 liquidity; - } - - // write an observation, then change tick and liquidity - function update(UpdateParams calldata params) external { - advanceTime(params.advanceTimeBy); - (index, cardinality) = observations.write(index, time, tick, liquidity, cardinality, cardinalityNext); - tick = params.tick; - liquidity = params.liquidity; - } - - function batchUpdate(UpdateParams[] calldata params) external { - // sload everything - int24 _tick = tick; - uint128 _liquidity = liquidity; - uint16 _index = index; - uint16 _cardinality = cardinality; - uint16 _cardinalityNext = cardinalityNext; - uint32 _time = time; - - for (uint256 i = 0; i < params.length; i++) { - _time += params[i].advanceTimeBy; - (_index, _cardinality) = observations.write( - _index, - _time, - _tick, - _liquidity, - _cardinality, - _cardinalityNext - ); - _tick = params[i].tick; - _liquidity = params[i].liquidity; - } - - // sstore everything - tick = _tick; - liquidity = _liquidity; - index = _index; - cardinality = _cardinality; - time = _time; - } - - function grow(uint16 _cardinalityNext) external { - cardinalityNext = observations.grow(cardinalityNext, _cardinalityNext); - } - - function observe(uint32[] calldata secondsAgos) - external - view - returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s) - { - return observations.observe(time, secondsAgos, tick, index, liquidity, cardinality); - } - - function getGasCostOfObserve(uint32[] calldata secondsAgos) external view returns (uint256) { - (uint32 _time, int24 _tick, uint128 _liquidity, uint16 _index) = (time, tick, liquidity, index); - uint256 gasBefore = gasleft(); - observations.observe(_time, secondsAgos, _tick, _index, _liquidity, cardinality); - return gasBefore - gasleft(); - } -} diff --git a/lib/v3-core/contracts/test/SqrtPriceMathEchidnaTest.sol b/lib/v3-core/contracts/test/SqrtPriceMathEchidnaTest.sol deleted file mode 100644 index 48010d9..0000000 --- a/lib/v3-core/contracts/test/SqrtPriceMathEchidnaTest.sol +++ /dev/null @@ -1,232 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../libraries/FullMath.sol'; -import '../libraries/SqrtPriceMath.sol'; -import '../libraries/FixedPoint96.sol'; - -contract SqrtPriceMathEchidnaTest { - function mulDivRoundingUpInvariants( - uint256 x, - uint256 y, - uint256 z - ) external pure { - require(z > 0); - uint256 notRoundedUp = FullMath.mulDiv(x, y, z); - uint256 roundedUp = FullMath.mulDivRoundingUp(x, y, z); - assert(roundedUp >= notRoundedUp); - assert(roundedUp - notRoundedUp < 2); - if (roundedUp - notRoundedUp == 1) { - assert(mulmod(x, y, z) > 0); - } else { - assert(mulmod(x, y, z) == 0); - } - } - - function getNextSqrtPriceFromInputInvariants( - uint160 sqrtP, - uint128 liquidity, - uint256 amountIn, - bool zeroForOne - ) external pure { - uint160 sqrtQ = SqrtPriceMath.getNextSqrtPriceFromInput(sqrtP, liquidity, amountIn, zeroForOne); - - if (zeroForOne) { - assert(sqrtQ <= sqrtP); - assert(amountIn >= SqrtPriceMath.getAmount0Delta(sqrtQ, sqrtP, liquidity, true)); - } else { - assert(sqrtQ >= sqrtP); - assert(amountIn >= SqrtPriceMath.getAmount1Delta(sqrtP, sqrtQ, liquidity, true)); - } - } - - function getNextSqrtPriceFromOutputInvariants( - uint160 sqrtP, - uint128 liquidity, - uint256 amountOut, - bool zeroForOne - ) external pure { - uint160 sqrtQ = SqrtPriceMath.getNextSqrtPriceFromOutput(sqrtP, liquidity, amountOut, zeroForOne); - - if (zeroForOne) { - assert(sqrtQ <= sqrtP); - assert(amountOut <= SqrtPriceMath.getAmount1Delta(sqrtQ, sqrtP, liquidity, false)); - } else { - assert(sqrtQ > 0); // this has to be true, otherwise we need another require - assert(sqrtQ >= sqrtP); - assert(amountOut <= SqrtPriceMath.getAmount0Delta(sqrtP, sqrtQ, liquidity, false)); - } - } - - function getNextSqrtPriceFromAmount0RoundingUpInvariants( - uint160 sqrtPX96, - uint128 liquidity, - uint256 amount, - bool add - ) external pure { - require(sqrtPX96 > 0); - require(liquidity > 0); - uint160 sqrtQX96 = SqrtPriceMath.getNextSqrtPriceFromAmount0RoundingUp(sqrtPX96, liquidity, amount, add); - - if (add) { - assert(sqrtQX96 <= sqrtPX96); - } else { - assert(sqrtQX96 >= sqrtPX96); - } - - if (amount == 0) { - assert(sqrtPX96 == sqrtQX96); - } - } - - function getNextSqrtPriceFromAmount1RoundingDownInvariants( - uint160 sqrtPX96, - uint128 liquidity, - uint256 amount, - bool add - ) external pure { - require(sqrtPX96 > 0); - require(liquidity > 0); - uint160 sqrtQX96 = SqrtPriceMath.getNextSqrtPriceFromAmount1RoundingDown(sqrtPX96, liquidity, amount, add); - - if (add) { - assert(sqrtQX96 >= sqrtPX96); - } else { - assert(sqrtQX96 <= sqrtPX96); - } - - if (amount == 0) { - assert(sqrtPX96 == sqrtQX96); - } - } - - function getAmount0DeltaInvariants( - uint160 sqrtP, - uint160 sqrtQ, - uint128 liquidity - ) external pure { - require(sqrtP > 0 && sqrtQ > 0); - - uint256 amount0Down = SqrtPriceMath.getAmount0Delta(sqrtQ, sqrtP, liquidity, false); - assert(amount0Down == SqrtPriceMath.getAmount0Delta(sqrtP, sqrtQ, liquidity, false)); - - uint256 amount0Up = SqrtPriceMath.getAmount0Delta(sqrtQ, sqrtP, liquidity, true); - assert(amount0Up == SqrtPriceMath.getAmount0Delta(sqrtP, sqrtQ, liquidity, true)); - - assert(amount0Down <= amount0Up); - // diff is 0 or 1 - assert(amount0Up - amount0Down < 2); - } - - // ensure that chained division is always equal to the full-precision case for - // liquidity * (sqrt(P) - sqrt(Q)) / (sqrt(P) * sqrt(Q)) - function getAmount0DeltaEquivalency( - uint160 sqrtP, - uint160 sqrtQ, - uint128 liquidity, - bool roundUp - ) external pure { - require(sqrtP >= sqrtQ); - require(sqrtP > 0 && sqrtQ > 0); - require((sqrtP * sqrtQ) / sqrtP == sqrtQ); - - uint256 numerator1 = uint256(liquidity) << FixedPoint96.RESOLUTION; - uint256 numerator2 = sqrtP - sqrtQ; - uint256 denominator = uint256(sqrtP) * sqrtQ; - - uint256 safeResult = - roundUp - ? FullMath.mulDivRoundingUp(numerator1, numerator2, denominator) - : FullMath.mulDiv(numerator1, numerator2, denominator); - uint256 fullResult = SqrtPriceMath.getAmount0Delta(sqrtQ, sqrtP, liquidity, roundUp); - - assert(safeResult == fullResult); - } - - function getAmount1DeltaInvariants( - uint160 sqrtP, - uint160 sqrtQ, - uint128 liquidity - ) external pure { - require(sqrtP > 0 && sqrtQ > 0); - - uint256 amount1Down = SqrtPriceMath.getAmount1Delta(sqrtP, sqrtQ, liquidity, false); - assert(amount1Down == SqrtPriceMath.getAmount1Delta(sqrtQ, sqrtP, liquidity, false)); - - uint256 amount1Up = SqrtPriceMath.getAmount1Delta(sqrtP, sqrtQ, liquidity, true); - assert(amount1Up == SqrtPriceMath.getAmount1Delta(sqrtQ, sqrtP, liquidity, true)); - - assert(amount1Down <= amount1Up); - // diff is 0 or 1 - assert(amount1Up - amount1Down < 2); - } - - function getAmount0DeltaSignedInvariants( - uint160 sqrtP, - uint160 sqrtQ, - int128 liquidity - ) external pure { - require(sqrtP > 0 && sqrtQ > 0); - - int256 amount0 = SqrtPriceMath.getAmount0Delta(sqrtQ, sqrtP, liquidity); - if (liquidity < 0) assert(amount0 <= 0); - if (liquidity > 0) { - if (sqrtP == sqrtQ) assert(amount0 == 0); - else assert(amount0 > 0); - } - if (liquidity == 0) assert(amount0 == 0); - } - - function getAmount1DeltaSignedInvariants( - uint160 sqrtP, - uint160 sqrtQ, - int128 liquidity - ) external pure { - require(sqrtP > 0 && sqrtQ > 0); - - int256 amount1 = SqrtPriceMath.getAmount1Delta(sqrtP, sqrtQ, liquidity); - if (liquidity < 0) assert(amount1 <= 0); - if (liquidity > 0) { - if (sqrtP == sqrtQ) assert(amount1 == 0); - else assert(amount1 > 0); - } - if (liquidity == 0) assert(amount1 == 0); - } - - function getOutOfRangeMintInvariants( - uint160 sqrtA, - uint160 sqrtB, - int128 liquidity - ) external pure { - require(sqrtA > 0 && sqrtB > 0); - require(liquidity > 0); - - int256 amount0 = SqrtPriceMath.getAmount0Delta(sqrtA, sqrtB, liquidity); - int256 amount1 = SqrtPriceMath.getAmount1Delta(sqrtA, sqrtB, liquidity); - - if (sqrtA == sqrtB) { - assert(amount0 == 0); - assert(amount1 == 0); - } else { - assert(amount0 > 0); - assert(amount1 > 0); - } - } - - function getInRangeMintInvariants( - uint160 sqrtLower, - uint160 sqrtCurrent, - uint160 sqrtUpper, - int128 liquidity - ) external pure { - require(sqrtLower > 0); - require(sqrtLower < sqrtUpper); - require(sqrtLower <= sqrtCurrent && sqrtCurrent <= sqrtUpper); - require(liquidity > 0); - - int256 amount0 = SqrtPriceMath.getAmount0Delta(sqrtCurrent, sqrtUpper, liquidity); - int256 amount1 = SqrtPriceMath.getAmount1Delta(sqrtLower, sqrtCurrent, liquidity); - - assert(amount0 > 0 || amount1 > 0); - } -} diff --git a/lib/v3-core/contracts/test/SqrtPriceMathTest.sol b/lib/v3-core/contracts/test/SqrtPriceMathTest.sol deleted file mode 100644 index 41fec2f..0000000 --- a/lib/v3-core/contracts/test/SqrtPriceMathTest.sol +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../libraries/SqrtPriceMath.sol'; - -contract SqrtPriceMathTest { - function getNextSqrtPriceFromInput( - uint160 sqrtP, - uint128 liquidity, - uint256 amountIn, - bool zeroForOne - ) external pure returns (uint160 sqrtQ) { - return SqrtPriceMath.getNextSqrtPriceFromInput(sqrtP, liquidity, amountIn, zeroForOne); - } - - function getGasCostOfGetNextSqrtPriceFromInput( - uint160 sqrtP, - uint128 liquidity, - uint256 amountIn, - bool zeroForOne - ) external view returns (uint256) { - uint256 gasBefore = gasleft(); - SqrtPriceMath.getNextSqrtPriceFromInput(sqrtP, liquidity, amountIn, zeroForOne); - return gasBefore - gasleft(); - } - - function getNextSqrtPriceFromOutput( - uint160 sqrtP, - uint128 liquidity, - uint256 amountOut, - bool zeroForOne - ) external pure returns (uint160 sqrtQ) { - return SqrtPriceMath.getNextSqrtPriceFromOutput(sqrtP, liquidity, amountOut, zeroForOne); - } - - function getGasCostOfGetNextSqrtPriceFromOutput( - uint160 sqrtP, - uint128 liquidity, - uint256 amountOut, - bool zeroForOne - ) external view returns (uint256) { - uint256 gasBefore = gasleft(); - SqrtPriceMath.getNextSqrtPriceFromOutput(sqrtP, liquidity, amountOut, zeroForOne); - return gasBefore - gasleft(); - } - - function getAmount0Delta( - uint160 sqrtLower, - uint160 sqrtUpper, - uint128 liquidity, - bool roundUp - ) external pure returns (uint256 amount0) { - return SqrtPriceMath.getAmount0Delta(sqrtLower, sqrtUpper, liquidity, roundUp); - } - - function getAmount1Delta( - uint160 sqrtLower, - uint160 sqrtUpper, - uint128 liquidity, - bool roundUp - ) external pure returns (uint256 amount1) { - return SqrtPriceMath.getAmount1Delta(sqrtLower, sqrtUpper, liquidity, roundUp); - } - - function getGasCostOfGetAmount0Delta( - uint160 sqrtLower, - uint160 sqrtUpper, - uint128 liquidity, - bool roundUp - ) external view returns (uint256) { - uint256 gasBefore = gasleft(); - SqrtPriceMath.getAmount0Delta(sqrtLower, sqrtUpper, liquidity, roundUp); - return gasBefore - gasleft(); - } - - function getGasCostOfGetAmount1Delta( - uint160 sqrtLower, - uint160 sqrtUpper, - uint128 liquidity, - bool roundUp - ) external view returns (uint256) { - uint256 gasBefore = gasleft(); - SqrtPriceMath.getAmount1Delta(sqrtLower, sqrtUpper, liquidity, roundUp); - return gasBefore - gasleft(); - } -} diff --git a/lib/v3-core/contracts/test/SwapMathEchidnaTest.sol b/lib/v3-core/contracts/test/SwapMathEchidnaTest.sol deleted file mode 100644 index 67bf861..0000000 --- a/lib/v3-core/contracts/test/SwapMathEchidnaTest.sol +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../libraries/SwapMath.sol'; - -contract SwapMathEchidnaTest { - function checkComputeSwapStepInvariants( - uint160 sqrtPriceRaw, - uint160 sqrtPriceTargetRaw, - uint128 liquidity, - int256 amountRemaining, - uint24 feePips - ) external pure { - require(sqrtPriceRaw > 0); - require(sqrtPriceTargetRaw > 0); - require(feePips > 0); - require(feePips < 1e6); - - (uint160 sqrtQ, uint256 amountIn, uint256 amountOut, uint256 feeAmount) = - SwapMath.computeSwapStep(sqrtPriceRaw, sqrtPriceTargetRaw, liquidity, amountRemaining, feePips); - - assert(amountIn <= type(uint256).max - feeAmount); - - if (amountRemaining < 0) { - assert(amountOut <= uint256(-amountRemaining)); - } else { - assert(amountIn + feeAmount <= uint256(amountRemaining)); - } - - if (sqrtPriceRaw == sqrtPriceTargetRaw) { - assert(amountIn == 0); - assert(amountOut == 0); - assert(feeAmount == 0); - assert(sqrtQ == sqrtPriceTargetRaw); - } - - // didn't reach price target, entire amount must be consumed - if (sqrtQ != sqrtPriceTargetRaw) { - if (amountRemaining < 0) assert(amountOut == uint256(-amountRemaining)); - else assert(amountIn + feeAmount == uint256(amountRemaining)); - } - - // next price is between price and price target - if (sqrtPriceTargetRaw <= sqrtPriceRaw) { - assert(sqrtQ <= sqrtPriceRaw); - assert(sqrtQ >= sqrtPriceTargetRaw); - } else { - assert(sqrtQ >= sqrtPriceRaw); - assert(sqrtQ <= sqrtPriceTargetRaw); - } - } -} diff --git a/lib/v3-core/contracts/test/SwapMathTest.sol b/lib/v3-core/contracts/test/SwapMathTest.sol deleted file mode 100644 index b0f59df..0000000 --- a/lib/v3-core/contracts/test/SwapMathTest.sol +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../libraries/SwapMath.sol'; - -contract SwapMathTest { - function computeSwapStep( - uint160 sqrtP, - uint160 sqrtPTarget, - uint128 liquidity, - int256 amountRemaining, - uint24 feePips - ) - external - pure - returns ( - uint160 sqrtQ, - uint256 amountIn, - uint256 amountOut, - uint256 feeAmount - ) - { - return SwapMath.computeSwapStep(sqrtP, sqrtPTarget, liquidity, amountRemaining, feePips); - } - - function getGasCostOfComputeSwapStep( - uint160 sqrtP, - uint160 sqrtPTarget, - uint128 liquidity, - int256 amountRemaining, - uint24 feePips - ) external view returns (uint256) { - uint256 gasBefore = gasleft(); - SwapMath.computeSwapStep(sqrtP, sqrtPTarget, liquidity, amountRemaining, feePips); - return gasBefore - gasleft(); - } -} diff --git a/lib/v3-core/contracts/test/TestERC20.sol b/lib/v3-core/contracts/test/TestERC20.sol deleted file mode 100644 index 411e0ea..0000000 --- a/lib/v3-core/contracts/test/TestERC20.sol +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../interfaces/IERC20Minimal.sol'; - -contract TestERC20 is IERC20Minimal { - mapping(address => uint256) public override balanceOf; - mapping(address => mapping(address => uint256)) public override allowance; - - constructor(uint256 amountToMint) { - mint(msg.sender, amountToMint); - } - - function mint(address to, uint256 amount) public { - uint256 balanceNext = balanceOf[to] + amount; - require(balanceNext >= amount, 'overflow balance'); - balanceOf[to] = balanceNext; - } - - function transfer(address recipient, uint256 amount) external override returns (bool) { - uint256 balanceBefore = balanceOf[msg.sender]; - require(balanceBefore >= amount, 'insufficient balance'); - balanceOf[msg.sender] = balanceBefore - amount; - - uint256 balanceRecipient = balanceOf[recipient]; - require(balanceRecipient + amount >= balanceRecipient, 'recipient balance overflow'); - balanceOf[recipient] = balanceRecipient + amount; - - emit Transfer(msg.sender, recipient, amount); - return true; - } - - function approve(address spender, uint256 amount) external override returns (bool) { - allowance[msg.sender][spender] = amount; - emit Approval(msg.sender, spender, amount); - return true; - } - - function transferFrom( - address sender, - address recipient, - uint256 amount - ) external override returns (bool) { - uint256 allowanceBefore = allowance[sender][msg.sender]; - require(allowanceBefore >= amount, 'allowance insufficient'); - - allowance[sender][msg.sender] = allowanceBefore - amount; - - uint256 balanceRecipient = balanceOf[recipient]; - require(balanceRecipient + amount >= balanceRecipient, 'overflow balance recipient'); - balanceOf[recipient] = balanceRecipient + amount; - uint256 balanceSender = balanceOf[sender]; - require(balanceSender >= amount, 'underflow balance sender'); - balanceOf[sender] = balanceSender - amount; - - emit Transfer(sender, recipient, amount); - return true; - } -} diff --git a/lib/v3-core/contracts/test/TestUniswapV3Callee.sol b/lib/v3-core/contracts/test/TestUniswapV3Callee.sol deleted file mode 100644 index b569935..0000000 --- a/lib/v3-core/contracts/test/TestUniswapV3Callee.sol +++ /dev/null @@ -1,142 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../interfaces/IERC20Minimal.sol'; - -import '../libraries/SafeCast.sol'; -import '../libraries/TickMath.sol'; - -import '../interfaces/callback/IUniswapV3MintCallback.sol'; -import '../interfaces/callback/IUniswapV3SwapCallback.sol'; -import '../interfaces/callback/IUniswapV3FlashCallback.sol'; - -import '../interfaces/IUniswapV3Pool.sol'; - -contract TestUniswapV3Callee is IUniswapV3MintCallback, IUniswapV3SwapCallback, IUniswapV3FlashCallback { - using SafeCast for uint256; - - function swapExact0For1( - address pool, - uint256 amount0In, - address recipient, - uint160 sqrtPriceLimitX96 - ) external { - IUniswapV3Pool(pool).swap(recipient, true, amount0In.toInt256(), sqrtPriceLimitX96, abi.encode(msg.sender)); - } - - function swap0ForExact1( - address pool, - uint256 amount1Out, - address recipient, - uint160 sqrtPriceLimitX96 - ) external { - IUniswapV3Pool(pool).swap(recipient, true, -amount1Out.toInt256(), sqrtPriceLimitX96, abi.encode(msg.sender)); - } - - function swapExact1For0( - address pool, - uint256 amount1In, - address recipient, - uint160 sqrtPriceLimitX96 - ) external { - IUniswapV3Pool(pool).swap(recipient, false, amount1In.toInt256(), sqrtPriceLimitX96, abi.encode(msg.sender)); - } - - function swap1ForExact0( - address pool, - uint256 amount0Out, - address recipient, - uint160 sqrtPriceLimitX96 - ) external { - IUniswapV3Pool(pool).swap(recipient, false, -amount0Out.toInt256(), sqrtPriceLimitX96, abi.encode(msg.sender)); - } - - function swapToLowerSqrtPrice( - address pool, - uint160 sqrtPriceX96, - address recipient - ) external { - IUniswapV3Pool(pool).swap(recipient, true, type(int256).max, sqrtPriceX96, abi.encode(msg.sender)); - } - - function swapToHigherSqrtPrice( - address pool, - uint160 sqrtPriceX96, - address recipient - ) external { - IUniswapV3Pool(pool).swap(recipient, false, type(int256).max, sqrtPriceX96, abi.encode(msg.sender)); - } - - event SwapCallback(int256 amount0Delta, int256 amount1Delta); - - function uniswapV3SwapCallback( - int256 amount0Delta, - int256 amount1Delta, - bytes calldata data - ) external override { - address sender = abi.decode(data, (address)); - - emit SwapCallback(amount0Delta, amount1Delta); - - if (amount0Delta > 0) { - IERC20Minimal(IUniswapV3Pool(msg.sender).token0()).transferFrom(sender, msg.sender, uint256(amount0Delta)); - } else if (amount1Delta > 0) { - IERC20Minimal(IUniswapV3Pool(msg.sender).token1()).transferFrom(sender, msg.sender, uint256(amount1Delta)); - } else { - // if both are not gt 0, both must be 0. - assert(amount0Delta == 0 && amount1Delta == 0); - } - } - - function mint( - address pool, - address recipient, - int24 tickLower, - int24 tickUpper, - uint128 amount - ) external { - IUniswapV3Pool(pool).mint(recipient, tickLower, tickUpper, amount, abi.encode(msg.sender)); - } - - event MintCallback(uint256 amount0Owed, uint256 amount1Owed); - - function uniswapV3MintCallback( - uint256 amount0Owed, - uint256 amount1Owed, - bytes calldata data - ) external override { - address sender = abi.decode(data, (address)); - - emit MintCallback(amount0Owed, amount1Owed); - if (amount0Owed > 0) - IERC20Minimal(IUniswapV3Pool(msg.sender).token0()).transferFrom(sender, msg.sender, amount0Owed); - if (amount1Owed > 0) - IERC20Minimal(IUniswapV3Pool(msg.sender).token1()).transferFrom(sender, msg.sender, amount1Owed); - } - - event FlashCallback(uint256 fee0, uint256 fee1); - - function flash( - address pool, - address recipient, - uint256 amount0, - uint256 amount1, - uint256 pay0, - uint256 pay1 - ) external { - IUniswapV3Pool(pool).flash(recipient, amount0, amount1, abi.encode(msg.sender, pay0, pay1)); - } - - function uniswapV3FlashCallback( - uint256 fee0, - uint256 fee1, - bytes calldata data - ) external override { - emit FlashCallback(fee0, fee1); - - (address sender, uint256 pay0, uint256 pay1) = abi.decode(data, (address, uint256, uint256)); - - if (pay0 > 0) IERC20Minimal(IUniswapV3Pool(msg.sender).token0()).transferFrom(sender, msg.sender, pay0); - if (pay1 > 0) IERC20Minimal(IUniswapV3Pool(msg.sender).token1()).transferFrom(sender, msg.sender, pay1); - } -} diff --git a/lib/v3-core/contracts/test/TestUniswapV3ReentrantCallee.sol b/lib/v3-core/contracts/test/TestUniswapV3ReentrantCallee.sol deleted file mode 100644 index fbd0b2a..0000000 --- a/lib/v3-core/contracts/test/TestUniswapV3ReentrantCallee.sol +++ /dev/null @@ -1,56 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../libraries/TickMath.sol'; - -import '../interfaces/callback/IUniswapV3SwapCallback.sol'; - -import '../interfaces/IUniswapV3Pool.sol'; - -contract TestUniswapV3ReentrantCallee is IUniswapV3SwapCallback { - string private constant expectedReason = 'LOK'; - - function swapToReenter(address pool) external { - IUniswapV3Pool(pool).swap(address(0), false, 1, TickMath.MAX_SQRT_RATIO - 1, new bytes(0)); - } - - function uniswapV3SwapCallback( - int256, - int256, - bytes calldata - ) external override { - // try to reenter swap - try IUniswapV3Pool(msg.sender).swap(address(0), false, 1, 0, new bytes(0)) {} catch Error( - string memory reason - ) { - require(keccak256(abi.encode(reason)) == keccak256(abi.encode(expectedReason))); - } - - // try to reenter mint - try IUniswapV3Pool(msg.sender).mint(address(0), 0, 0, 0, new bytes(0)) {} catch Error(string memory reason) { - require(keccak256(abi.encode(reason)) == keccak256(abi.encode(expectedReason))); - } - - // try to reenter collect - try IUniswapV3Pool(msg.sender).collect(address(0), 0, 0, 0, 0) {} catch Error(string memory reason) { - require(keccak256(abi.encode(reason)) == keccak256(abi.encode(expectedReason))); - } - - // try to reenter burn - try IUniswapV3Pool(msg.sender).burn(0, 0, 0) {} catch Error(string memory reason) { - require(keccak256(abi.encode(reason)) == keccak256(abi.encode(expectedReason))); - } - - // try to reenter flash - try IUniswapV3Pool(msg.sender).flash(address(0), 0, 0, new bytes(0)) {} catch Error(string memory reason) { - require(keccak256(abi.encode(reason)) == keccak256(abi.encode(expectedReason))); - } - - // try to reenter collectProtocol - try IUniswapV3Pool(msg.sender).collectProtocol(address(0), 0, 0) {} catch Error(string memory reason) { - require(keccak256(abi.encode(reason)) == keccak256(abi.encode(expectedReason))); - } - - require(false, 'Unable to reenter'); - } -} diff --git a/lib/v3-core/contracts/test/TestUniswapV3Router.sol b/lib/v3-core/contracts/test/TestUniswapV3Router.sol deleted file mode 100644 index 8f916dd..0000000 --- a/lib/v3-core/contracts/test/TestUniswapV3Router.sol +++ /dev/null @@ -1,91 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../libraries/SafeCast.sol'; -import '../libraries/TickMath.sol'; - -import '../interfaces/IERC20Minimal.sol'; -import '../interfaces/callback/IUniswapV3SwapCallback.sol'; -import '../interfaces/IUniswapV3Pool.sol'; - -contract TestUniswapV3Router is IUniswapV3SwapCallback { - using SafeCast for uint256; - - // flash swaps for an exact amount of token0 in the output pool - function swapForExact0Multi( - address recipient, - address poolInput, - address poolOutput, - uint256 amount0Out - ) external { - address[] memory pools = new address[](1); - pools[0] = poolInput; - IUniswapV3Pool(poolOutput).swap( - recipient, - false, - -amount0Out.toInt256(), - TickMath.MAX_SQRT_RATIO - 1, - abi.encode(pools, msg.sender) - ); - } - - // flash swaps for an exact amount of token1 in the output pool - function swapForExact1Multi( - address recipient, - address poolInput, - address poolOutput, - uint256 amount1Out - ) external { - address[] memory pools = new address[](1); - pools[0] = poolInput; - IUniswapV3Pool(poolOutput).swap( - recipient, - true, - -amount1Out.toInt256(), - TickMath.MIN_SQRT_RATIO + 1, - abi.encode(pools, msg.sender) - ); - } - - event SwapCallback(int256 amount0Delta, int256 amount1Delta); - - function uniswapV3SwapCallback( - int256 amount0Delta, - int256 amount1Delta, - bytes calldata data - ) public override { - emit SwapCallback(amount0Delta, amount1Delta); - - (address[] memory pools, address payer) = abi.decode(data, (address[], address)); - - if (pools.length == 1) { - // get the address and amount of the token that we need to pay - address tokenToBePaid = - amount0Delta > 0 ? IUniswapV3Pool(msg.sender).token0() : IUniswapV3Pool(msg.sender).token1(); - int256 amountToBePaid = amount0Delta > 0 ? amount0Delta : amount1Delta; - - bool zeroForOne = tokenToBePaid == IUniswapV3Pool(pools[0]).token1(); - IUniswapV3Pool(pools[0]).swap( - msg.sender, - zeroForOne, - -amountToBePaid, - zeroForOne ? TickMath.MIN_SQRT_RATIO + 1 : TickMath.MAX_SQRT_RATIO - 1, - abi.encode(new address[](0), payer) - ); - } else { - if (amount0Delta > 0) { - IERC20Minimal(IUniswapV3Pool(msg.sender).token0()).transferFrom( - payer, - msg.sender, - uint256(amount0Delta) - ); - } else { - IERC20Minimal(IUniswapV3Pool(msg.sender).token1()).transferFrom( - payer, - msg.sender, - uint256(amount1Delta) - ); - } - } - } -} diff --git a/lib/v3-core/contracts/test/TestUniswapV3SwapPay.sol b/lib/v3-core/contracts/test/TestUniswapV3SwapPay.sol deleted file mode 100644 index 0a78c88..0000000 --- a/lib/v3-core/contracts/test/TestUniswapV3SwapPay.sol +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../interfaces/IERC20Minimal.sol'; - -import '../interfaces/callback/IUniswapV3SwapCallback.sol'; -import '../interfaces/IUniswapV3Pool.sol'; - -contract TestUniswapV3SwapPay is IUniswapV3SwapCallback { - function swap( - address pool, - address recipient, - bool zeroForOne, - uint160 sqrtPriceX96, - int256 amountSpecified, - uint256 pay0, - uint256 pay1 - ) external { - IUniswapV3Pool(pool).swap( - recipient, - zeroForOne, - amountSpecified, - sqrtPriceX96, - abi.encode(msg.sender, pay0, pay1) - ); - } - - function uniswapV3SwapCallback( - int256, - int256, - bytes calldata data - ) external override { - (address sender, uint256 pay0, uint256 pay1) = abi.decode(data, (address, uint256, uint256)); - - if (pay0 > 0) { - IERC20Minimal(IUniswapV3Pool(msg.sender).token0()).transferFrom(sender, msg.sender, uint256(pay0)); - } else if (pay1 > 0) { - IERC20Minimal(IUniswapV3Pool(msg.sender).token1()).transferFrom(sender, msg.sender, uint256(pay1)); - } - } -} diff --git a/lib/v3-core/contracts/test/TickBitmapEchidnaTest.sol b/lib/v3-core/contracts/test/TickBitmapEchidnaTest.sol deleted file mode 100644 index 675798a..0000000 --- a/lib/v3-core/contracts/test/TickBitmapEchidnaTest.sol +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../libraries/TickBitmap.sol'; - -contract TickBitmapEchidnaTest { - using TickBitmap for mapping(int16 => uint256); - - mapping(int16 => uint256) private bitmap; - - // returns whether the given tick is initialized - function isInitialized(int24 tick) private view returns (bool) { - (int24 next, bool initialized) = bitmap.nextInitializedTickWithinOneWord(tick, 1, true); - return next == tick ? initialized : false; - } - - function flipTick(int24 tick) external { - bool before = isInitialized(tick); - bitmap.flipTick(tick, 1); - assert(isInitialized(tick) == !before); - } - - function checkNextInitializedTickWithinOneWordInvariants(int24 tick, bool lte) external view { - (int24 next, bool initialized) = bitmap.nextInitializedTickWithinOneWord(tick, 1, lte); - if (lte) { - // type(int24).min + 256 - require(tick >= -8388352); - assert(next <= tick); - assert(tick - next < 256); - // all the ticks between the input tick and the next tick should be uninitialized - for (int24 i = tick; i > next; i--) { - assert(!isInitialized(i)); - } - assert(isInitialized(next) == initialized); - } else { - // type(int24).max - 256 - require(tick < 8388351); - assert(next > tick); - assert(next - tick <= 256); - // all the ticks between the input tick and the next tick should be uninitialized - for (int24 i = tick + 1; i < next; i++) { - assert(!isInitialized(i)); - } - assert(isInitialized(next) == initialized); - } - } -} diff --git a/lib/v3-core/contracts/test/TickBitmapTest.sol b/lib/v3-core/contracts/test/TickBitmapTest.sol deleted file mode 100644 index c6fb6b0..0000000 --- a/lib/v3-core/contracts/test/TickBitmapTest.sol +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../libraries/TickBitmap.sol'; - -contract TickBitmapTest { - using TickBitmap for mapping(int16 => uint256); - - mapping(int16 => uint256) public bitmap; - - function flipTick(int24 tick) external { - bitmap.flipTick(tick, 1); - } - - function getGasCostOfFlipTick(int24 tick) external returns (uint256) { - uint256 gasBefore = gasleft(); - bitmap.flipTick(tick, 1); - return gasBefore - gasleft(); - } - - function nextInitializedTickWithinOneWord(int24 tick, bool lte) - external - view - returns (int24 next, bool initialized) - { - return bitmap.nextInitializedTickWithinOneWord(tick, 1, lte); - } - - function getGasCostOfNextInitializedTickWithinOneWord(int24 tick, bool lte) external view returns (uint256) { - uint256 gasBefore = gasleft(); - bitmap.nextInitializedTickWithinOneWord(tick, 1, lte); - return gasBefore - gasleft(); - } - - // returns whether the given tick is initialized - function isInitialized(int24 tick) external view returns (bool) { - (int24 next, bool initialized) = bitmap.nextInitializedTickWithinOneWord(tick, 1, true); - return next == tick ? initialized : false; - } -} diff --git a/lib/v3-core/contracts/test/TickEchidnaTest.sol b/lib/v3-core/contracts/test/TickEchidnaTest.sol deleted file mode 100644 index 1d5514f..0000000 --- a/lib/v3-core/contracts/test/TickEchidnaTest.sol +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../libraries/Tick.sol'; - -contract TickEchidnaTest { - function checkTickSpacingToParametersInvariants(int24 tickSpacing) external pure { - require(tickSpacing <= TickMath.MAX_TICK); - require(tickSpacing > 0); - - int24 minTick = (TickMath.MIN_TICK / tickSpacing) * tickSpacing; - int24 maxTick = (TickMath.MAX_TICK / tickSpacing) * tickSpacing; - - uint128 maxLiquidityPerTick = Tick.tickSpacingToMaxLiquidityPerTick(tickSpacing); - - // symmetry around 0 tick - assert(maxTick == -minTick); - // positive max tick - assert(maxTick > 0); - // divisibility - assert((maxTick - minTick) % tickSpacing == 0); - - uint256 numTicks = uint256((maxTick - minTick) / tickSpacing) + 1; - // max liquidity at every tick is less than the cap - assert(uint256(maxLiquidityPerTick) * numTicks <= type(uint128).max); - } -} diff --git a/lib/v3-core/contracts/test/TickMathEchidnaTest.sol b/lib/v3-core/contracts/test/TickMathEchidnaTest.sol deleted file mode 100644 index 91064b0..0000000 --- a/lib/v3-core/contracts/test/TickMathEchidnaTest.sol +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../libraries/TickMath.sol'; - -contract TickMathEchidnaTest { - // uniqueness and increasing order - function checkGetSqrtRatioAtTickInvariants(int24 tick) external pure { - uint160 ratio = TickMath.getSqrtRatioAtTick(tick); - assert(TickMath.getSqrtRatioAtTick(tick - 1) < ratio && ratio < TickMath.getSqrtRatioAtTick(tick + 1)); - assert(ratio >= TickMath.MIN_SQRT_RATIO); - assert(ratio <= TickMath.MAX_SQRT_RATIO); - } - - // the ratio is always between the returned tick and the returned tick+1 - function checkGetTickAtSqrtRatioInvariants(uint160 ratio) external pure { - int24 tick = TickMath.getTickAtSqrtRatio(ratio); - assert(ratio >= TickMath.getSqrtRatioAtTick(tick) && ratio < TickMath.getSqrtRatioAtTick(tick + 1)); - assert(tick >= TickMath.MIN_TICK); - assert(tick < TickMath.MAX_TICK); - } -} diff --git a/lib/v3-core/contracts/test/TickMathTest.sol b/lib/v3-core/contracts/test/TickMathTest.sol deleted file mode 100644 index 2816e57..0000000 --- a/lib/v3-core/contracts/test/TickMathTest.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../libraries/TickMath.sol'; - -contract TickMathTest { - function getSqrtRatioAtTick(int24 tick) external pure returns (uint160) { - return TickMath.getSqrtRatioAtTick(tick); - } - - function getGasCostOfGetSqrtRatioAtTick(int24 tick) external view returns (uint256) { - uint256 gasBefore = gasleft(); - TickMath.getSqrtRatioAtTick(tick); - return gasBefore - gasleft(); - } - - function getTickAtSqrtRatio(uint160 sqrtPriceX96) external pure returns (int24) { - return TickMath.getTickAtSqrtRatio(sqrtPriceX96); - } - - function getGasCostOfGetTickAtSqrtRatio(uint160 sqrtPriceX96) external view returns (uint256) { - uint256 gasBefore = gasleft(); - TickMath.getTickAtSqrtRatio(sqrtPriceX96); - return gasBefore - gasleft(); - } - - function MIN_SQRT_RATIO() external pure returns (uint160) { - return TickMath.MIN_SQRT_RATIO; - } - - function MAX_SQRT_RATIO() external pure returns (uint160) { - return TickMath.MAX_SQRT_RATIO; - } -} diff --git a/lib/v3-core/contracts/test/TickOverflowSafetyEchidnaTest.sol b/lib/v3-core/contracts/test/TickOverflowSafetyEchidnaTest.sol deleted file mode 100644 index fcda269..0000000 --- a/lib/v3-core/contracts/test/TickOverflowSafetyEchidnaTest.sol +++ /dev/null @@ -1,111 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../libraries/Tick.sol'; - -contract TickOverflowSafetyEchidnaTest { - using Tick for mapping(int24 => Tick.Info); - - int24 private constant MIN_TICK = -16; - int24 private constant MAX_TICK = 16; - uint128 private constant MAX_LIQUIDITY = type(uint128).max / 32; - - mapping(int24 => Tick.Info) private ticks; - int24 private tick = 0; - - // used to track how much total liquidity has been added. should never be negative - int256 totalLiquidity = 0; - // half the cap of fee growth has happened, this can overflow - uint256 private feeGrowthGlobal0X128 = type(uint256).max / 2; - uint256 private feeGrowthGlobal1X128 = type(uint256).max / 2; - // how much total growth has happened, this cannot overflow - uint256 private totalGrowth0 = 0; - uint256 private totalGrowth1 = 0; - - function increaseFeeGrowthGlobal0X128(uint256 amount) external { - require(totalGrowth0 + amount > totalGrowth0); // overflow check - feeGrowthGlobal0X128 += amount; // overflow desired - totalGrowth0 += amount; - } - - function increaseFeeGrowthGlobal1X128(uint256 amount) external { - require(totalGrowth1 + amount > totalGrowth1); // overflow check - feeGrowthGlobal1X128 += amount; // overflow desired - totalGrowth1 += amount; - } - - function setPosition( - int24 tickLower, - int24 tickUpper, - int128 liquidityDelta - ) external { - require(tickLower > MIN_TICK); - require(tickUpper < MAX_TICK); - require(tickLower < tickUpper); - bool flippedLower = - ticks.update( - tickLower, - tick, - liquidityDelta, - feeGrowthGlobal0X128, - feeGrowthGlobal1X128, - 0, - 0, - uint32(block.timestamp), - false, - MAX_LIQUIDITY - ); - bool flippedUpper = - ticks.update( - tickUpper, - tick, - liquidityDelta, - feeGrowthGlobal0X128, - feeGrowthGlobal1X128, - 0, - 0, - uint32(block.timestamp), - true, - MAX_LIQUIDITY - ); - - if (flippedLower) { - if (liquidityDelta < 0) { - assert(ticks[tickLower].liquidityGross == 0); - ticks.clear(tickLower); - } else assert(ticks[tickLower].liquidityGross > 0); - } - - if (flippedUpper) { - if (liquidityDelta < 0) { - assert(ticks[tickUpper].liquidityGross == 0); - ticks.clear(tickUpper); - } else assert(ticks[tickUpper].liquidityGross > 0); - } - - totalLiquidity += liquidityDelta; - // requires should have prevented this - assert(totalLiquidity >= 0); - - if (totalLiquidity == 0) { - totalGrowth0 = 0; - totalGrowth1 = 0; - } - } - - function moveToTick(int24 target) external { - require(target > MIN_TICK); - require(target < MAX_TICK); - while (tick != target) { - if (tick < target) { - if (ticks[tick + 1].liquidityGross > 0) - ticks.cross(tick + 1, feeGrowthGlobal0X128, feeGrowthGlobal1X128, 0, 0, uint32(block.timestamp)); - tick++; - } else { - if (ticks[tick].liquidityGross > 0) - ticks.cross(tick, feeGrowthGlobal0X128, feeGrowthGlobal1X128, 0, 0, uint32(block.timestamp)); - tick--; - } - } - } -} diff --git a/lib/v3-core/contracts/test/TickTest.sol b/lib/v3-core/contracts/test/TickTest.sol deleted file mode 100644 index d9fa7cb..0000000 --- a/lib/v3-core/contracts/test/TickTest.sol +++ /dev/null @@ -1,79 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; -pragma abicoder v2; - -import '../libraries/Tick.sol'; - -contract TickTest { - using Tick for mapping(int24 => Tick.Info); - - mapping(int24 => Tick.Info) public ticks; - - function tickSpacingToMaxLiquidityPerTick(int24 tickSpacing) external pure returns (uint128) { - return Tick.tickSpacingToMaxLiquidityPerTick(tickSpacing); - } - - function setTick(int24 tick, Tick.Info memory info) external { - ticks[tick] = info; - } - - function getFeeGrowthInside( - int24 tickLower, - int24 tickUpper, - int24 tickCurrent, - uint256 feeGrowthGlobal0X128, - uint256 feeGrowthGlobal1X128 - ) external view returns (uint256 feeGrowthInside0X128, uint256 feeGrowthInside1X128) { - return ticks.getFeeGrowthInside(tickLower, tickUpper, tickCurrent, feeGrowthGlobal0X128, feeGrowthGlobal1X128); - } - - function update( - int24 tick, - int24 tickCurrent, - int128 liquidityDelta, - uint256 feeGrowthGlobal0X128, - uint256 feeGrowthGlobal1X128, - uint160 secondsPerLiquidityCumulativeX128, - int56 tickCumulative, - uint32 time, - bool upper, - uint128 maxLiquidity - ) external returns (bool flipped) { - return - ticks.update( - tick, - tickCurrent, - liquidityDelta, - feeGrowthGlobal0X128, - feeGrowthGlobal1X128, - secondsPerLiquidityCumulativeX128, - tickCumulative, - time, - upper, - maxLiquidity - ); - } - - function clear(int24 tick) external { - ticks.clear(tick); - } - - function cross( - int24 tick, - uint256 feeGrowthGlobal0X128, - uint256 feeGrowthGlobal1X128, - uint160 secondsPerLiquidityCumulativeX128, - int56 tickCumulative, - uint32 time - ) external returns (int128 liquidityNet) { - return - ticks.cross( - tick, - feeGrowthGlobal0X128, - feeGrowthGlobal1X128, - secondsPerLiquidityCumulativeX128, - tickCumulative, - time - ); - } -} diff --git a/lib/v3-core/contracts/test/UniswapV3PoolSwapTest.sol b/lib/v3-core/contracts/test/UniswapV3PoolSwapTest.sol deleted file mode 100644 index d1f900b..0000000 --- a/lib/v3-core/contracts/test/UniswapV3PoolSwapTest.sol +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../interfaces/IERC20Minimal.sol'; - -import '../interfaces/callback/IUniswapV3SwapCallback.sol'; -import '../interfaces/IUniswapV3Pool.sol'; - -contract UniswapV3PoolSwapTest is IUniswapV3SwapCallback { - int256 private _amount0Delta; - int256 private _amount1Delta; - - function getSwapResult( - address pool, - bool zeroForOne, - int256 amountSpecified, - uint160 sqrtPriceLimitX96 - ) - external - returns ( - int256 amount0Delta, - int256 amount1Delta, - uint160 nextSqrtRatio - ) - { - (amount0Delta, amount1Delta) = IUniswapV3Pool(pool).swap( - address(0), - zeroForOne, - amountSpecified, - sqrtPriceLimitX96, - abi.encode(msg.sender) - ); - - (nextSqrtRatio, , , , , , ) = IUniswapV3Pool(pool).slot0(); - } - - function uniswapV3SwapCallback( - int256 amount0Delta, - int256 amount1Delta, - bytes calldata data - ) external override { - address sender = abi.decode(data, (address)); - - if (amount0Delta > 0) { - IERC20Minimal(IUniswapV3Pool(msg.sender).token0()).transferFrom(sender, msg.sender, uint256(amount0Delta)); - } else if (amount1Delta > 0) { - IERC20Minimal(IUniswapV3Pool(msg.sender).token1()).transferFrom(sender, msg.sender, uint256(amount1Delta)); - } - } -} diff --git a/lib/v3-core/contracts/test/UnsafeMathEchidnaTest.sol b/lib/v3-core/contracts/test/UnsafeMathEchidnaTest.sol deleted file mode 100644 index 0a44d7e..0000000 --- a/lib/v3-core/contracts/test/UnsafeMathEchidnaTest.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../libraries/UnsafeMath.sol'; - -contract UnsafeMathEchidnaTest { - function checkDivRoundingUp(uint256 x, uint256 d) external pure { - require(d > 0); - uint256 z = UnsafeMath.divRoundingUp(x, d); - uint256 diff = z - (x / d); - if (x % d == 0) { - assert(diff == 0); - } else { - assert(diff == 1); - } - } -} diff --git a/lib/v3-core/echidna.config.yml b/lib/v3-core/echidna.config.yml deleted file mode 100644 index 64a761d..0000000 --- a/lib/v3-core/echidna.config.yml +++ /dev/null @@ -1,74 +0,0 @@ -#format can be "text" or "json" for different output (human or machine readable) -format: 'text' -#checkAsserts checks assertions -checkAsserts: true -#coverage controls coverage guided testing -coverage: false -# #psender is the sender for property transactions; by default intentionally -# #the same as contract deployer -# psender: "0x00a329c0648769a73afac7f9381e08fb43dbea70" -# #prefix is the prefix for Boolean functions that are properties to be checked -# prefix: "echidna_" -# #propMaxGas defines gas cost at which a property fails -# propMaxGas: 8000030 -# #testMaxGas is a gas limit; does not cause failure, but terminates sequence -# testMaxGas: 8000030 -# #maxGasprice is the maximum gas price -# maxGasprice: 100000000000 -# #testLimit is the number of test sequences to run -# testLimit: 50000 -# #stopOnFail makes echidna terminate as soon as any property fails and has been shrunk -# stopOnFail: false -# #estimateGas makes echidna perform analysis of maximum gas costs for functions (experimental) -# estimateGas: false -# #seqLen defines how many transactions are in a test sequence -# seqLen: 100 -# #shrinkLimit determines how much effort is spent shrinking failing sequences -# shrinkLimit: 5000 -# #contractAddr is the address of the contract itself -# contractAddr: "0x00a329c0648769a73afac7f9381e08fb43dbea72" -# #deployer is address of the contract deployer (who often is privileged owner, etc.) -# deployer: "0x00a329c0648769a73afac7f9381e08fb43dbea70" -# #sender is set of addresses transactions may originate from -# sender: ["0x10000", "0x20000", "0x00a329c0648769a73afac7f9381e08fb43dbea70"] -# #balanceAddr is default balance for addresses -# balanceAddr: 0xffffffff -# #balanceContract overrides balanceAddr for the contract address -# balanceContract: 0 -# #solcArgs allows special args to solc -# solcArgs: "" -# #solcLibs is solc libraries -# solcLibs: [] -# #cryticArgs allows special args to crytic -# cryticArgs: [] -# #quiet produces (much) less verbose output -# quiet: false -# #initialize the blockchain with some data -# initialize: null -# #whether ot not to use the multi-abi mode of testing -# multi-abi: false -# #benchmarkMode enables benchmark mode -# benchmarkMode: false -# #timeout controls test timeout settings -# timeout: null -# #seed not defined by default, is the random seed -# #seed: 0 -# #dictFreq controls how often to use echidna's internal dictionary vs random -# #values -# dictFreq: 0.40 -# maxTimeDelay: 604800 -# #maximum time between generated txs; default is one week -# maxBlockDelay: 60480 -# #maximum number of blocks elapsed between generated txs; default is expected increment in one week -# # timeout: -# #campaign timeout (in seconds) -# # list of methods to filter -# filterFunctions: [] -# # by default, blacklist methods in filterFunctions -# filterBlacklist: true -# #directory to save the corpus; by default is disabled -# corpusDir: null -# # constants for corpus mutations (for experimentation only) -# mutConsts: [100, 1, 1] -# # maximum value to send to payable functions -# maxValue: 100000000000000000000 # 100 eth diff --git a/lib/v3-core/hardhat.config.ts b/lib/v3-core/hardhat.config.ts deleted file mode 100644 index 1b0971b..0000000 --- a/lib/v3-core/hardhat.config.ts +++ /dev/null @@ -1,68 +0,0 @@ -import 'hardhat-typechain' -import '@nomiclabs/hardhat-ethers' -import '@nomiclabs/hardhat-waffle' -import '@nomiclabs/hardhat-etherscan' - -export default { - networks: { - hardhat: { - allowUnlimitedContractSize: false, - }, - mainnet: { - url: `https://mainnet.infura.io/v3/${process.env.INFURA_API_KEY}`, - }, - ropsten: { - url: `https://ropsten.infura.io/v3/${process.env.INFURA_API_KEY}`, - }, - rinkeby: { - url: `https://rinkeby.infura.io/v3/${process.env.INFURA_API_KEY}`, - }, - goerli: { - url: `https://goerli.infura.io/v3/${process.env.INFURA_API_KEY}`, - }, - kovan: { - url: `https://kovan.infura.io/v3/${process.env.INFURA_API_KEY}`, - }, - arbitrumRinkeby: { - url: `https://arbitrum-rinkeby.infura.io/v3/${process.env.INFURA_API_KEY}`, - }, - arbitrum: { - url: `https://arbitrum-mainnet.infura.io/v3/${process.env.INFURA_API_KEY}`, - }, - optimismKovan: { - url: `https://optimism-kovan.infura.io/v3/${process.env.INFURA_API_KEY}`, - }, - optimism: { - url: `https://optimism-mainnet.infura.io/v3/${process.env.INFURA_API_KEY}`, - }, - mumbai: { - url: `https://polygon-mumbai.infura.io/v3/${process.env.INFURA_API_KEY}`, - }, - polygon: { - url: `https://polygon-mainnet.infura.io/v3/${process.env.INFURA_API_KEY}`, - }, - bnb: { - url: `https://bsc-dataseed.binance.org/`, - }, - }, - etherscan: { - // Your API key for Etherscan - // Obtain one at https://etherscan.io/ - apiKey: process.env.ETHERSCAN_API_KEY, - }, - solidity: { - version: '0.7.6', - settings: { - optimizer: { - enabled: true, - runs: 800, - }, - metadata: { - // do not include the metadata hash, since this is machine dependent - // and we want all generated code to be deterministic - // https://docs.soliditylang.org/en/v0.7.6/metadata.html - bytecodeHash: 'none', - }, - }, - }, -} diff --git a/lib/v3-core/package.json b/lib/v3-core/package.json deleted file mode 100644 index 188721b..0000000 --- a/lib/v3-core/package.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "name": "@uniswap/v3-core", - "description": "🦄 Core smart contracts of Uniswap V3", - "license": "BUSL-1.1", - "publishConfig": { - "access": "public" - }, - "version": "1.0.1", - "homepage": "https://uniswap.org", - "keywords": [ - "uniswap", - "core", - "v3" - ], - "repository": { - "type": "git", - "url": "https://github.com/Uniswap/uniswap-v3-core" - }, - "files": [ - "contracts/interfaces", - "contracts/libraries", - "artifacts/contracts/UniswapV3Factory.sol/UniswapV3Factory.json", - "artifacts/contracts/UniswapV3Pool.sol/UniswapV3Pool.json", - "artifacts/contracts/interfaces/**/*.json", - "!artifacts/contracts/interfaces/**/*.dbg.json" - ], - "engines": { - "node": ">=10" - }, - "dependencies": {}, - "devDependencies": { - "@nomiclabs/hardhat-ethers": "^2.0.2", - "@nomiclabs/hardhat-etherscan": "^2.1.8", - "@nomiclabs/hardhat-waffle": "^2.0.1", - "@typechain/ethers-v5": "^4.0.0", - "@types/chai": "^4.2.6", - "@types/mocha": "^5.2.7", - "chai": "^4.2.0", - "decimal.js": "^10.2.1", - "ethereum-waffle": "^3.0.2", - "ethers": "^5.0.8", - "hardhat": "^2.2.0", - "hardhat-typechain": "^0.3.5", - "mocha": "^6.2.2", - "mocha-chai-jest-snapshot": "^1.1.0", - "prettier": "^2.0.5", - "prettier-plugin-solidity": "^1.0.0-alpha.59", - "solhint": "^3.2.1", - "solhint-plugin-prettier": "^0.0.5", - "ts-generator": "^0.1.1", - "ts-node": "^8.5.4", - "typechain": "^4.0.0", - "typescript": "^3.7.3" - }, - "scripts": { - "compile": "hardhat compile", - "test": "hardhat test" - } -} diff --git a/lib/v3-core/test/BitMath.spec.ts b/lib/v3-core/test/BitMath.spec.ts deleted file mode 100644 index 00b9285..0000000 --- a/lib/v3-core/test/BitMath.spec.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { expect } from './shared/expect' -import { BitMathTest } from '../typechain/BitMathTest' -import { ethers, waffle } from 'hardhat' -import snapshotGasCost from './shared/snapshotGasCost' - -const { BigNumber } = ethers - -describe('BitMath', () => { - let bitMath: BitMathTest - const fixture = async () => { - const factory = await ethers.getContractFactory('BitMathTest') - return (await factory.deploy()) as BitMathTest - } - beforeEach('deploy BitMathTest', async () => { - bitMath = await waffle.loadFixture(fixture) - }) - - describe('#mostSignificantBit', () => { - it('0', async () => { - await expect(bitMath.mostSignificantBit(0)).to.be.reverted - }) - it('1', async () => { - expect(await bitMath.mostSignificantBit(1)).to.eq(0) - }) - it('2', async () => { - expect(await bitMath.mostSignificantBit(2)).to.eq(1) - }) - it('all powers of 2', async () => { - const results = await Promise.all( - [...Array(255)].map((_, i) => bitMath.mostSignificantBit(BigNumber.from(2).pow(i))) - ) - expect(results).to.deep.eq([...Array(255)].map((_, i) => i)) - }) - it('uint256(-1)', async () => { - expect(await bitMath.mostSignificantBit(BigNumber.from(2).pow(256).sub(1))).to.eq(255) - }) - - it('gas cost of smaller number', async () => { - await snapshotGasCost(bitMath.getGasCostOfMostSignificantBit(BigNumber.from(3568))) - }) - it('gas cost of max uint128', async () => { - await snapshotGasCost(bitMath.getGasCostOfMostSignificantBit(BigNumber.from(2).pow(128).sub(1))) - }) - it('gas cost of max uint256', async () => { - await snapshotGasCost(bitMath.getGasCostOfMostSignificantBit(BigNumber.from(2).pow(256).sub(1))) - }) - }) - - describe('#leastSignificantBit', () => { - it('0', async () => { - await expect(bitMath.leastSignificantBit(0)).to.be.reverted - }) - it('1', async () => { - expect(await bitMath.leastSignificantBit(1)).to.eq(0) - }) - it('2', async () => { - expect(await bitMath.leastSignificantBit(2)).to.eq(1) - }) - it('all powers of 2', async () => { - const results = await Promise.all( - [...Array(255)].map((_, i) => bitMath.leastSignificantBit(BigNumber.from(2).pow(i))) - ) - expect(results).to.deep.eq([...Array(255)].map((_, i) => i)) - }) - it('uint256(-1)', async () => { - expect(await bitMath.leastSignificantBit(BigNumber.from(2).pow(256).sub(1))).to.eq(0) - }) - - it('gas cost of smaller number', async () => { - await snapshotGasCost(bitMath.getGasCostOfLeastSignificantBit(BigNumber.from(3568))) - }) - it('gas cost of max uint128', async () => { - await snapshotGasCost(bitMath.getGasCostOfLeastSignificantBit(BigNumber.from(2).pow(128).sub(1))) - }) - it('gas cost of max uint256', async () => { - await snapshotGasCost(bitMath.getGasCostOfLeastSignificantBit(BigNumber.from(2).pow(256).sub(1))) - }) - }) -}) diff --git a/lib/v3-core/test/FullMath.spec.ts b/lib/v3-core/test/FullMath.spec.ts deleted file mode 100644 index a7dfb92..0000000 --- a/lib/v3-core/test/FullMath.spec.ts +++ /dev/null @@ -1,182 +0,0 @@ -import { ethers } from 'hardhat' -import { FullMathTest } from '../typechain/FullMathTest' -import { expect } from './shared/expect' -import { Decimal } from 'decimal.js' - -const { - BigNumber, - constants: { MaxUint256 }, -} = ethers -const Q128 = BigNumber.from(2).pow(128) - -Decimal.config({ toExpNeg: -500, toExpPos: 500 }) - -describe('FullMath', () => { - let fullMath: FullMathTest - before('deploy FullMathTest', async () => { - const factory = await ethers.getContractFactory('FullMathTest') - fullMath = (await factory.deploy()) as FullMathTest - }) - - describe('#mulDiv', () => { - it('reverts if denominator is 0', async () => { - await expect(fullMath.mulDiv(Q128, 5, 0)).to.be.reverted - }) - it('reverts if denominator is 0 and numerator overflows', async () => { - await expect(fullMath.mulDiv(Q128, Q128, 0)).to.be.reverted - }) - it('reverts if output overflows uint256', async () => { - await expect(fullMath.mulDiv(Q128, Q128, 1)).to.be.reverted - }) - it('reverts if output overflows uint256', async () => { - await expect(fullMath.mulDiv(Q128, Q128, 1)).to.be.reverted - }) - it('reverts on overflow with all max inputs', async () => { - await expect(fullMath.mulDiv(MaxUint256, MaxUint256, MaxUint256.sub(1))).to.be.reverted - }) - - it('all max inputs', async () => { - expect(await fullMath.mulDiv(MaxUint256, MaxUint256, MaxUint256)).to.eq(MaxUint256) - }) - - it('accurate without phantom overflow', async () => { - const result = Q128.div(3) - expect( - await fullMath.mulDiv( - Q128, - /*0.5=*/ BigNumber.from(50).mul(Q128).div(100), - /*1.5=*/ BigNumber.from(150).mul(Q128).div(100) - ) - ).to.eq(result) - }) - - it('accurate with phantom overflow', async () => { - const result = BigNumber.from(4375).mul(Q128).div(1000) - expect(await fullMath.mulDiv(Q128, BigNumber.from(35).mul(Q128), BigNumber.from(8).mul(Q128))).to.eq(result) - }) - - it('accurate with phantom overflow and repeating decimal', async () => { - const result = BigNumber.from(1).mul(Q128).div(3) - expect(await fullMath.mulDiv(Q128, BigNumber.from(1000).mul(Q128), BigNumber.from(3000).mul(Q128))).to.eq(result) - }) - }) - - describe('#mulDivRoundingUp', () => { - it('reverts if denominator is 0', async () => { - await expect(fullMath.mulDivRoundingUp(Q128, 5, 0)).to.be.reverted - }) - it('reverts if denominator is 0 and numerator overflows', async () => { - await expect(fullMath.mulDivRoundingUp(Q128, Q128, 0)).to.be.reverted - }) - it('reverts if output overflows uint256', async () => { - await expect(fullMath.mulDivRoundingUp(Q128, Q128, 1)).to.be.reverted - }) - it('reverts on overflow with all max inputs', async () => { - await expect(fullMath.mulDivRoundingUp(MaxUint256, MaxUint256, MaxUint256.sub(1))).to.be.reverted - }) - - it('reverts if mulDiv overflows 256 bits after rounding up', async () => { - await expect( - fullMath.mulDivRoundingUp( - '535006138814359', - '432862656469423142931042426214547535783388063929571229938474969', - '2' - ) - ).to.be.reverted - }) - - it('reverts if mulDiv overflows 256 bits after rounding up case 2', async () => { - await expect( - fullMath.mulDivRoundingUp( - '115792089237316195423570985008687907853269984659341747863450311749907997002549', - '115792089237316195423570985008687907853269984659341747863450311749907997002550', - '115792089237316195423570985008687907853269984653042931687443039491902864365164' - ) - ).to.be.reverted - }) - - it('all max inputs', async () => { - expect(await fullMath.mulDivRoundingUp(MaxUint256, MaxUint256, MaxUint256)).to.eq(MaxUint256) - }) - - it('accurate without phantom overflow', async () => { - const result = Q128.div(3).add(1) - expect( - await fullMath.mulDivRoundingUp( - Q128, - /*0.5=*/ BigNumber.from(50).mul(Q128).div(100), - /*1.5=*/ BigNumber.from(150).mul(Q128).div(100) - ) - ).to.eq(result) - }) - - it('accurate with phantom overflow', async () => { - const result = BigNumber.from(4375).mul(Q128).div(1000) - expect(await fullMath.mulDivRoundingUp(Q128, BigNumber.from(35).mul(Q128), BigNumber.from(8).mul(Q128))).to.eq( - result - ) - }) - - it('accurate with phantom overflow and repeating decimal', async () => { - const result = BigNumber.from(1).mul(Q128).div(3).add(1) - expect( - await fullMath.mulDivRoundingUp(Q128, BigNumber.from(1000).mul(Q128), BigNumber.from(3000).mul(Q128)) - ).to.eq(result) - }) - }) - - function pseudoRandomBigNumber() { - return BigNumber.from(new Decimal(MaxUint256.toString()).mul(Math.random().toString()).round().toString()) - } - - // tiny fuzzer. unskip to run - it.skip('check a bunch of random inputs against JS implementation', async () => { - // generates random inputs - const tests = Array(1_000) - .fill(null) - .map(() => { - return { - x: pseudoRandomBigNumber(), - y: pseudoRandomBigNumber(), - d: pseudoRandomBigNumber(), - } - }) - .map(({ x, y, d }) => { - return { - input: { - x, - y, - d, - }, - floored: fullMath.mulDiv(x, y, d), - ceiled: fullMath.mulDivRoundingUp(x, y, d), - } - }) - - await Promise.all( - tests.map(async ({ input: { x, y, d }, floored, ceiled }) => { - if (d.eq(0)) { - await expect(floored).to.be.reverted - await expect(ceiled).to.be.reverted - return - } - - if (x.eq(0) || y.eq(0)) { - await expect(floored).to.eq(0) - await expect(ceiled).to.eq(0) - } else if (x.mul(y).div(d).gt(MaxUint256)) { - await expect(floored).to.be.reverted - await expect(ceiled).to.be.reverted - } else { - expect(await floored).to.eq(x.mul(y).div(d)) - expect(await ceiled).to.eq( - x - .mul(y) - .div(d) - .add(x.mul(y).mod(d).gt(0) ? 1 : 0) - ) - } - }) - ) - }) -}) diff --git a/lib/v3-core/test/LiquidityMath.spec.ts b/lib/v3-core/test/LiquidityMath.spec.ts deleted file mode 100644 index 76f6ac2..0000000 --- a/lib/v3-core/test/LiquidityMath.spec.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { expect } from './shared/expect' -import { LiquidityMathTest } from '../typechain/LiquidityMathTest' -import { ethers, waffle } from 'hardhat' -import snapshotGasCost from './shared/snapshotGasCost' - -const { BigNumber } = ethers - -describe('LiquidityMath', () => { - let liquidityMath: LiquidityMathTest - const fixture = async () => { - const factory = await ethers.getContractFactory('LiquidityMathTest') - return (await factory.deploy()) as LiquidityMathTest - } - beforeEach('deploy LiquidityMathTest', async () => { - liquidityMath = await waffle.loadFixture(fixture) - }) - - describe('#addDelta', () => { - it('1 + 0', async () => { - expect(await liquidityMath.addDelta(1, 0)).to.eq(1) - }) - it('1 + -1', async () => { - expect(await liquidityMath.addDelta(1, -1)).to.eq(0) - }) - it('1 + 1', async () => { - expect(await liquidityMath.addDelta(1, 1)).to.eq(2) - }) - it('2**128-15 + 15 overflows', async () => { - await expect(liquidityMath.addDelta(BigNumber.from(2).pow(128).sub(15), 15)).to.be.revertedWith('LA') - }) - it('0 + -1 underflows', async () => { - await expect(liquidityMath.addDelta(0, -1)).to.be.revertedWith('LS') - }) - it('3 + -4 underflows', async () => { - await expect(liquidityMath.addDelta(3, -4)).to.be.revertedWith('LS') - }) - it('gas add', async () => { - await snapshotGasCost(liquidityMath.getGasCostOfAddDelta(15, 4)) - }) - it('gas sub', async () => { - await snapshotGasCost(liquidityMath.getGasCostOfAddDelta(15, -4)) - }) - }) -}) diff --git a/lib/v3-core/test/NoDelegateCall.spec.ts b/lib/v3-core/test/NoDelegateCall.spec.ts deleted file mode 100644 index c46af93..0000000 --- a/lib/v3-core/test/NoDelegateCall.spec.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { Wallet } from 'ethers' -import { ethers, waffle } from 'hardhat' -import { NoDelegateCallTest } from '../typechain/NoDelegateCallTest' -import { expect } from './shared/expect' -import snapshotGasCost from './shared/snapshotGasCost' - -describe('NoDelegateCall', () => { - let wallet: Wallet, other: Wallet - - let loadFixture: ReturnType - before('create fixture loader', async () => { - ;[wallet, other] = await (ethers as any).getSigners() - loadFixture = waffle.createFixtureLoader([wallet, other]) - }) - - const noDelegateCallFixture = async () => { - const noDelegateCallTestFactory = await ethers.getContractFactory('NoDelegateCallTest') - const noDelegateCallTest = (await noDelegateCallTestFactory.deploy()) as NoDelegateCallTest - const minimalProxyFactory = new ethers.ContractFactory( - noDelegateCallTestFactory.interface, - `3d602d80600a3d3981f3363d3d373d3d3d363d73${noDelegateCallTest.address.slice(2)}5af43d82803e903d91602b57fd5bf3`, - wallet - ) - const proxy = (await minimalProxyFactory.deploy()) as NoDelegateCallTest - return { noDelegateCallTest, proxy } - } - - let base: NoDelegateCallTest - let proxy: NoDelegateCallTest - - beforeEach('deploy test contracts', async () => { - ;({ noDelegateCallTest: base, proxy } = await loadFixture(noDelegateCallFixture)) - }) - - it('runtime overhead', async () => { - await snapshotGasCost( - (await base.getGasCostOfCannotBeDelegateCalled()).sub(await base.getGasCostOfCanBeDelegateCalled()) - ) - }) - - it('proxy can call the method without the modifier', async () => { - await proxy.canBeDelegateCalled() - }) - it('proxy cannot call the method with the modifier', async () => { - await expect(proxy.cannotBeDelegateCalled()).to.be.reverted - }) - - it('can call the method that calls into a private method with the modifier', async () => { - await base.callsIntoNoDelegateCallFunction() - }) - it('proxy cannot call the method that calls a private method with the modifier', async () => { - await expect(proxy.callsIntoNoDelegateCallFunction()).to.be.reverted - }) -}) diff --git a/lib/v3-core/test/Oracle.spec.ts b/lib/v3-core/test/Oracle.spec.ts deleted file mode 100644 index 1a31d6f..0000000 --- a/lib/v3-core/test/Oracle.spec.ts +++ /dev/null @@ -1,798 +0,0 @@ -import { BigNumber, BigNumberish, Wallet } from 'ethers' -import { ethers, waffle } from 'hardhat' -import { OracleTest } from '../typechain/OracleTest' -import checkObservationEquals from './shared/checkObservationEquals' -import { expect } from './shared/expect' -import { TEST_POOL_START_TIME } from './shared/fixtures' -import snapshotGasCost from './shared/snapshotGasCost' -import { MaxUint128 } from './shared/utilities' - -describe('Oracle', () => { - let wallet: Wallet, other: Wallet - - let loadFixture: ReturnType - before('create fixture loader', async () => { - ;[wallet, other] = await (ethers as any).getSigners() - loadFixture = waffle.createFixtureLoader([wallet, other]) - }) - - const oracleFixture = async () => { - const oracleTestFactory = await ethers.getContractFactory('OracleTest') - return (await oracleTestFactory.deploy()) as OracleTest - } - - const initializedOracleFixture = async () => { - const oracle = await oracleFixture() - await oracle.initialize({ - time: 0, - tick: 0, - liquidity: 0, - }) - return oracle - } - - describe('#initialize', () => { - let oracle: OracleTest - beforeEach('deploy test oracle', async () => { - oracle = await loadFixture(oracleFixture) - }) - it('index is 0', async () => { - await oracle.initialize({ liquidity: 1, tick: 1, time: 1 }) - expect(await oracle.index()).to.eq(0) - }) - it('cardinality is 1', async () => { - await oracle.initialize({ liquidity: 1, tick: 1, time: 1 }) - expect(await oracle.cardinality()).to.eq(1) - }) - it('cardinality next is 1', async () => { - await oracle.initialize({ liquidity: 1, tick: 1, time: 1 }) - expect(await oracle.cardinalityNext()).to.eq(1) - }) - it('sets first slot timestamp only', async () => { - await oracle.initialize({ liquidity: 1, tick: 1, time: 1 }) - checkObservationEquals(await oracle.observations(0), { - initialized: true, - blockTimestamp: 1, - tickCumulative: 0, - secondsPerLiquidityCumulativeX128: 0, - }) - }) - it('gas', async () => { - await snapshotGasCost(oracle.initialize({ liquidity: 1, tick: 1, time: 1 })) - }) - }) - - describe('#grow', () => { - let oracle: OracleTest - beforeEach('deploy initialized test oracle', async () => { - oracle = await loadFixture(initializedOracleFixture) - }) - - it('increases the cardinality next for the first call', async () => { - await oracle.grow(5) - expect(await oracle.index()).to.eq(0) - expect(await oracle.cardinality()).to.eq(1) - expect(await oracle.cardinalityNext()).to.eq(5) - }) - - it('does not touch the first slot', async () => { - await oracle.grow(5) - checkObservationEquals(await oracle.observations(0), { - secondsPerLiquidityCumulativeX128: 0, - tickCumulative: 0, - blockTimestamp: 0, - initialized: true, - }) - }) - - it('is no op if oracle is already gte that size', async () => { - await oracle.grow(5) - await oracle.grow(3) - expect(await oracle.index()).to.eq(0) - expect(await oracle.cardinality()).to.eq(1) - expect(await oracle.cardinalityNext()).to.eq(5) - }) - - it('adds data to all the slots', async () => { - await oracle.grow(5) - for (let i = 1; i < 5; i++) { - checkObservationEquals(await oracle.observations(i), { - secondsPerLiquidityCumulativeX128: 0, - tickCumulative: 0, - blockTimestamp: 1, - initialized: false, - }) - } - }) - - it('grow after wrap', async () => { - await oracle.grow(2) - await oracle.update({ advanceTimeBy: 2, liquidity: 1, tick: 1 }) // index is now 1 - await oracle.update({ advanceTimeBy: 2, liquidity: 1, tick: 1 }) // index is now 0 again - expect(await oracle.index()).to.eq(0) - await oracle.grow(3) - expect(await oracle.index()).to.eq(0) - expect(await oracle.cardinality()).to.eq(2) - expect(await oracle.cardinalityNext()).to.eq(3) - }) - - it('gas for growing by 1 slot when index == cardinality - 1', async () => { - await snapshotGasCost(oracle.grow(2)) - }) - - it('gas for growing by 10 slots when index == cardinality - 1', async () => { - await snapshotGasCost(oracle.grow(11)) - }) - - it('gas for growing by 1 slot when index != cardinality - 1', async () => { - await oracle.grow(2) - await snapshotGasCost(oracle.grow(3)) - }) - - it('gas for growing by 10 slots when index != cardinality - 1', async () => { - await oracle.grow(2) - await snapshotGasCost(oracle.grow(12)) - }) - }) - - describe('#write', () => { - let oracle: OracleTest - - beforeEach('deploy initialized test oracle', async () => { - oracle = await loadFixture(initializedOracleFixture) - }) - - it('single element array gets overwritten', async () => { - await oracle.update({ advanceTimeBy: 1, tick: 2, liquidity: 5 }) - expect(await oracle.index()).to.eq(0) - checkObservationEquals(await oracle.observations(0), { - initialized: true, - secondsPerLiquidityCumulativeX128: '340282366920938463463374607431768211456', - tickCumulative: 0, - blockTimestamp: 1, - }) - await oracle.update({ advanceTimeBy: 5, tick: -1, liquidity: 8 }) - expect(await oracle.index()).to.eq(0) - checkObservationEquals(await oracle.observations(0), { - initialized: true, - secondsPerLiquidityCumulativeX128: '680564733841876926926749214863536422912', - tickCumulative: 10, - blockTimestamp: 6, - }) - await oracle.update({ advanceTimeBy: 3, tick: 2, liquidity: 3 }) - expect(await oracle.index()).to.eq(0) - checkObservationEquals(await oracle.observations(0), { - initialized: true, - secondsPerLiquidityCumulativeX128: '808170621437228850725514692650449502208', - tickCumulative: 7, - blockTimestamp: 9, - }) - }) - - it('does nothing if time has not changed', async () => { - await oracle.grow(2) - await oracle.update({ advanceTimeBy: 1, tick: 3, liquidity: 2 }) - expect(await oracle.index()).to.eq(1) - await oracle.update({ advanceTimeBy: 0, tick: -5, liquidity: 9 }) - expect(await oracle.index()).to.eq(1) - }) - - it('writes an index if time has changed', async () => { - await oracle.grow(3) - await oracle.update({ advanceTimeBy: 6, tick: 3, liquidity: 2 }) - expect(await oracle.index()).to.eq(1) - await oracle.update({ advanceTimeBy: 4, tick: -5, liquidity: 9 }) - - expect(await oracle.index()).to.eq(2) - checkObservationEquals(await oracle.observations(1), { - tickCumulative: 0, - secondsPerLiquidityCumulativeX128: '2041694201525630780780247644590609268736', - initialized: true, - blockTimestamp: 6, - }) - }) - - it('grows cardinality when writing past', async () => { - await oracle.grow(2) - await oracle.grow(4) - expect(await oracle.cardinality()).to.eq(1) - await oracle.update({ advanceTimeBy: 3, tick: 5, liquidity: 6 }) - expect(await oracle.cardinality()).to.eq(4) - await oracle.update({ advanceTimeBy: 4, tick: 6, liquidity: 4 }) - expect(await oracle.cardinality()).to.eq(4) - expect(await oracle.index()).to.eq(2) - checkObservationEquals(await oracle.observations(2), { - secondsPerLiquidityCumulativeX128: '1247702012043441032699040227249816775338', - tickCumulative: 20, - initialized: true, - blockTimestamp: 7, - }) - }) - - it('wraps around', async () => { - await oracle.grow(3) - await oracle.update({ advanceTimeBy: 3, tick: 1, liquidity: 2 }) - await oracle.update({ advanceTimeBy: 4, tick: 2, liquidity: 3 }) - await oracle.update({ advanceTimeBy: 5, tick: 3, liquidity: 4 }) - - expect(await oracle.index()).to.eq(0) - - checkObservationEquals(await oracle.observations(0), { - secondsPerLiquidityCumulativeX128: '2268549112806256423089164049545121409706', - tickCumulative: 14, - initialized: true, - blockTimestamp: 12, - }) - }) - - it('accumulates liquidity', async () => { - await oracle.grow(4) - - await oracle.update({ advanceTimeBy: 3, tick: 3, liquidity: 2 }) - await oracle.update({ advanceTimeBy: 4, tick: -7, liquidity: 6 }) - await oracle.update({ advanceTimeBy: 5, tick: -2, liquidity: 4 }) - - expect(await oracle.index()).to.eq(3) - - checkObservationEquals(await oracle.observations(1), { - initialized: true, - tickCumulative: 0, - secondsPerLiquidityCumulativeX128: '1020847100762815390390123822295304634368', - blockTimestamp: 3, - }) - checkObservationEquals(await oracle.observations(2), { - initialized: true, - tickCumulative: 12, - secondsPerLiquidityCumulativeX128: '1701411834604692317316873037158841057280', - blockTimestamp: 7, - }) - checkObservationEquals(await oracle.observations(3), { - initialized: true, - tickCumulative: -23, - secondsPerLiquidityCumulativeX128: '1984980473705474370203018543351981233493', - blockTimestamp: 12, - }) - checkObservationEquals(await oracle.observations(4), { - initialized: false, - tickCumulative: 0, - secondsPerLiquidityCumulativeX128: 0, - blockTimestamp: 0, - }) - }) - }) - - describe('#observe', () => { - describe('before initialization', async () => { - let oracle: OracleTest - beforeEach('deploy test oracle', async () => { - oracle = await loadFixture(oracleFixture) - }) - - const observeSingle = async (secondsAgo: number) => { - const { - tickCumulatives: [tickCumulative], - secondsPerLiquidityCumulativeX128s: [secondsPerLiquidityCumulativeX128], - } = await oracle.observe([secondsAgo]) - return { secondsPerLiquidityCumulativeX128, tickCumulative } - } - - it('fails before initialize', async () => { - await expect(observeSingle(0)).to.be.revertedWith('I') - }) - - it('fails if an older observation does not exist', async () => { - await oracle.initialize({ liquidity: 4, tick: 2, time: 5 }) - await expect(observeSingle(1)).to.be.revertedWith('OLD') - }) - - it('does not fail across overflow boundary', async () => { - await oracle.initialize({ liquidity: 4, tick: 2, time: 2 ** 32 - 1 }) - await oracle.advanceTime(2) - const { tickCumulative, secondsPerLiquidityCumulativeX128 } = await observeSingle(1) - expect(tickCumulative).to.be.eq(2) - expect(secondsPerLiquidityCumulativeX128).to.be.eq('85070591730234615865843651857942052864') - }) - - it('interpolates correctly at max liquidity', async () => { - await oracle.initialize({ liquidity: MaxUint128, tick: 0, time: 0 }) - await oracle.grow(2) - await oracle.update({ advanceTimeBy: 13, tick: 0, liquidity: 0 }) - let { secondsPerLiquidityCumulativeX128 } = await observeSingle(0) - expect(secondsPerLiquidityCumulativeX128).to.eq(13) - ;({ secondsPerLiquidityCumulativeX128 } = await observeSingle(6)) - expect(secondsPerLiquidityCumulativeX128).to.eq(7) - ;({ secondsPerLiquidityCumulativeX128 } = await observeSingle(12)) - expect(secondsPerLiquidityCumulativeX128).to.eq(1) - ;({ secondsPerLiquidityCumulativeX128 } = await observeSingle(13)) - expect(secondsPerLiquidityCumulativeX128).to.eq(0) - }) - - it('interpolates correctly at min liquidity', async () => { - await oracle.initialize({ liquidity: 0, tick: 0, time: 0 }) - await oracle.grow(2) - await oracle.update({ advanceTimeBy: 13, tick: 0, liquidity: MaxUint128 }) - let { secondsPerLiquidityCumulativeX128 } = await observeSingle(0) - expect(secondsPerLiquidityCumulativeX128).to.eq(BigNumber.from(13).shl(128)) - ;({ secondsPerLiquidityCumulativeX128 } = await observeSingle(6)) - expect(secondsPerLiquidityCumulativeX128).to.eq(BigNumber.from(7).shl(128)) - ;({ secondsPerLiquidityCumulativeX128 } = await observeSingle(12)) - expect(secondsPerLiquidityCumulativeX128).to.eq(BigNumber.from(1).shl(128)) - ;({ secondsPerLiquidityCumulativeX128 } = await observeSingle(13)) - expect(secondsPerLiquidityCumulativeX128).to.eq(0) - }) - - it('interpolates the same as 0 liquidity for 1 liquidity', async () => { - await oracle.initialize({ liquidity: 1, tick: 0, time: 0 }) - await oracle.grow(2) - await oracle.update({ advanceTimeBy: 13, tick: 0, liquidity: MaxUint128 }) - let { secondsPerLiquidityCumulativeX128 } = await observeSingle(0) - expect(secondsPerLiquidityCumulativeX128).to.eq(BigNumber.from(13).shl(128)) - ;({ secondsPerLiquidityCumulativeX128 } = await observeSingle(6)) - expect(secondsPerLiquidityCumulativeX128).to.eq(BigNumber.from(7).shl(128)) - ;({ secondsPerLiquidityCumulativeX128 } = await observeSingle(12)) - expect(secondsPerLiquidityCumulativeX128).to.eq(BigNumber.from(1).shl(128)) - ;({ secondsPerLiquidityCumulativeX128 } = await observeSingle(13)) - expect(secondsPerLiquidityCumulativeX128).to.eq(0) - }) - - it('interpolates correctly across uint32 seconds boundaries', async () => { - // setup - await oracle.initialize({ liquidity: 0, tick: 0, time: 0 }) - await oracle.grow(2) - await oracle.update({ advanceTimeBy: 2 ** 32 - 6, tick: 0, liquidity: 0 }) - let { secondsPerLiquidityCumulativeX128 } = await observeSingle(0) - expect(secondsPerLiquidityCumulativeX128).to.eq(BigNumber.from(2 ** 32 - 6).shl(128)) - await oracle.update({ advanceTimeBy: 13, tick: 0, liquidity: 0 }) - ;({ secondsPerLiquidityCumulativeX128 } = await observeSingle(0)) - expect(secondsPerLiquidityCumulativeX128).to.eq(BigNumber.from(7).shl(128)) - - // interpolation checks - ;({ secondsPerLiquidityCumulativeX128 } = await observeSingle(3)) - expect(secondsPerLiquidityCumulativeX128).to.eq(BigNumber.from(4).shl(128)) - ;({ secondsPerLiquidityCumulativeX128 } = await observeSingle(8)) - expect(secondsPerLiquidityCumulativeX128).to.eq(BigNumber.from(2 ** 32 - 1).shl(128)) - }) - - it('single observation at current time', async () => { - await oracle.initialize({ liquidity: 4, tick: 2, time: 5 }) - const { tickCumulative, secondsPerLiquidityCumulativeX128 } = await observeSingle(0) - expect(tickCumulative).to.eq(0) - expect(secondsPerLiquidityCumulativeX128).to.eq(0) - }) - - it('single observation in past but not earlier than secondsAgo', async () => { - await oracle.initialize({ liquidity: 4, tick: 2, time: 5 }) - await oracle.advanceTime(3) - await expect(observeSingle(4)).to.be.revertedWith('OLD') - }) - - it('single observation in past at exactly seconds ago', async () => { - await oracle.initialize({ liquidity: 4, tick: 2, time: 5 }) - await oracle.advanceTime(3) - const { tickCumulative, secondsPerLiquidityCumulativeX128 } = await observeSingle(3) - expect(tickCumulative).to.eq(0) - expect(secondsPerLiquidityCumulativeX128).to.eq(0) - }) - - it('single observation in past counterfactual in past', async () => { - await oracle.initialize({ liquidity: 4, tick: 2, time: 5 }) - await oracle.advanceTime(3) - const { tickCumulative, secondsPerLiquidityCumulativeX128 } = await observeSingle(1) - expect(tickCumulative).to.eq(4) - expect(secondsPerLiquidityCumulativeX128).to.eq('170141183460469231731687303715884105728') - }) - - it('single observation in past counterfactual now', async () => { - await oracle.initialize({ liquidity: 4, tick: 2, time: 5 }) - await oracle.advanceTime(3) - const { tickCumulative, secondsPerLiquidityCumulativeX128 } = await observeSingle(0) - expect(tickCumulative).to.eq(6) - expect(secondsPerLiquidityCumulativeX128).to.eq('255211775190703847597530955573826158592') - }) - - it('two observations in chronological order 0 seconds ago exact', async () => { - await oracle.initialize({ liquidity: 5, tick: -5, time: 5 }) - await oracle.grow(2) - await oracle.update({ advanceTimeBy: 4, tick: 1, liquidity: 2 }) - const { tickCumulative, secondsPerLiquidityCumulativeX128 } = await observeSingle(0) - expect(tickCumulative).to.eq(-20) - expect(secondsPerLiquidityCumulativeX128).to.eq('272225893536750770770699685945414569164') - }) - - it('two observations in chronological order 0 seconds ago counterfactual', async () => { - await oracle.initialize({ liquidity: 5, tick: -5, time: 5 }) - await oracle.grow(2) - await oracle.update({ advanceTimeBy: 4, tick: 1, liquidity: 2 }) - await oracle.advanceTime(7) - const { tickCumulative, secondsPerLiquidityCumulativeX128 } = await observeSingle(0) - expect(tickCumulative).to.eq(-13) - expect(secondsPerLiquidityCumulativeX128).to.eq('1463214177760035392892510811956603309260') - }) - - it('two observations in chronological order seconds ago is exactly on first observation', async () => { - await oracle.initialize({ liquidity: 5, tick: -5, time: 5 }) - await oracle.grow(2) - await oracle.update({ advanceTimeBy: 4, tick: 1, liquidity: 2 }) - await oracle.advanceTime(7) - const { tickCumulative, secondsPerLiquidityCumulativeX128 } = await observeSingle(11) - expect(tickCumulative).to.eq(0) - expect(secondsPerLiquidityCumulativeX128).to.eq(0) - }) - - it('two observations in chronological order seconds ago is between first and second', async () => { - await oracle.initialize({ liquidity: 5, tick: -5, time: 5 }) - await oracle.grow(2) - await oracle.update({ advanceTimeBy: 4, tick: 1, liquidity: 2 }) - await oracle.advanceTime(7) - const { tickCumulative, secondsPerLiquidityCumulativeX128 } = await observeSingle(9) - expect(tickCumulative).to.eq(-10) - expect(secondsPerLiquidityCumulativeX128).to.eq('136112946768375385385349842972707284582') - }) - - it('two observations in reverse order 0 seconds ago exact', async () => { - await oracle.initialize({ liquidity: 5, tick: -5, time: 5 }) - await oracle.grow(2) - await oracle.update({ advanceTimeBy: 4, tick: 1, liquidity: 2 }) - await oracle.update({ advanceTimeBy: 3, tick: -5, liquidity: 4 }) - const { tickCumulative, secondsPerLiquidityCumulativeX128 } = await observeSingle(0) - expect(tickCumulative).to.eq(-17) - expect(secondsPerLiquidityCumulativeX128).to.eq('782649443918158465965761597093066886348') - }) - - it('two observations in reverse order 0 seconds ago counterfactual', async () => { - await oracle.initialize({ liquidity: 5, tick: -5, time: 5 }) - await oracle.grow(2) - await oracle.update({ advanceTimeBy: 4, tick: 1, liquidity: 2 }) - await oracle.update({ advanceTimeBy: 3, tick: -5, liquidity: 4 }) - await oracle.advanceTime(7) - const { tickCumulative, secondsPerLiquidityCumulativeX128 } = await observeSingle(0) - expect(tickCumulative).to.eq(-52) - expect(secondsPerLiquidityCumulativeX128).to.eq('1378143586029800777026667160098661256396') - }) - - it('two observations in reverse order seconds ago is exactly on first observation', async () => { - await oracle.initialize({ liquidity: 5, tick: -5, time: 5 }) - await oracle.grow(2) - await oracle.update({ advanceTimeBy: 4, tick: 1, liquidity: 2 }) - await oracle.update({ advanceTimeBy: 3, tick: -5, liquidity: 4 }) - await oracle.advanceTime(7) - const { tickCumulative, secondsPerLiquidityCumulativeX128 } = await observeSingle(10) - expect(tickCumulative).to.eq(-20) - expect(secondsPerLiquidityCumulativeX128).to.eq('272225893536750770770699685945414569164') - }) - - it('two observations in reverse order seconds ago is between first and second', async () => { - await oracle.initialize({ liquidity: 5, tick: -5, time: 5 }) - await oracle.grow(2) - await oracle.update({ advanceTimeBy: 4, tick: 1, liquidity: 2 }) - await oracle.update({ advanceTimeBy: 3, tick: -5, liquidity: 4 }) - await oracle.advanceTime(7) - const { tickCumulative, secondsPerLiquidityCumulativeX128 } = await observeSingle(9) - expect(tickCumulative).to.eq(-19) - expect(secondsPerLiquidityCumulativeX128).to.eq('442367076997220002502386989661298674892') - }) - - it('can fetch multiple observations', async () => { - await oracle.initialize({ time: 5, tick: 2, liquidity: BigNumber.from(2).pow(15) }) - await oracle.grow(4) - await oracle.update({ advanceTimeBy: 13, tick: 6, liquidity: BigNumber.from(2).pow(12) }) - await oracle.advanceTime(5) - - const { tickCumulatives, secondsPerLiquidityCumulativeX128s } = await oracle.observe([0, 3, 8, 13, 15, 18]) - expect(tickCumulatives).to.have.lengthOf(6) - expect(tickCumulatives[0]).to.eq(56) - expect(tickCumulatives[1]).to.eq(38) - expect(tickCumulatives[2]).to.eq(20) - expect(tickCumulatives[3]).to.eq(10) - expect(tickCumulatives[4]).to.eq(6) - expect(tickCumulatives[5]).to.eq(0) - expect(secondsPerLiquidityCumulativeX128s).to.have.lengthOf(6) - expect(secondsPerLiquidityCumulativeX128s[0]).to.eq('550383467004691728624232610897330176') - expect(secondsPerLiquidityCumulativeX128s[1]).to.eq('301153217795020002454768787094765568') - expect(secondsPerLiquidityCumulativeX128s[2]).to.eq('103845937170696552570609926584401920') - expect(secondsPerLiquidityCumulativeX128s[3]).to.eq('51922968585348276285304963292200960') - expect(secondsPerLiquidityCumulativeX128s[4]).to.eq('31153781151208965771182977975320576') - expect(secondsPerLiquidityCumulativeX128s[5]).to.eq(0) - }) - - it('gas for observe since most recent', async () => { - await oracle.initialize({ liquidity: 5, tick: -5, time: 5 }) - await oracle.advanceTime(2) - await snapshotGasCost(oracle.getGasCostOfObserve([1])) - }) - - it('gas for single observation at current time', async () => { - await oracle.initialize({ liquidity: 5, tick: -5, time: 5 }) - await snapshotGasCost(oracle.getGasCostOfObserve([0])) - }) - - it('gas for single observation at current time counterfactually computed', async () => { - await oracle.initialize({ liquidity: 5, tick: -5, time: 5 }) - await oracle.advanceTime(5) - await snapshotGasCost(oracle.getGasCostOfObserve([0])) - }) - }) - - for (const startingTime of [5, 2 ** 32 - 5]) { - describe(`initialized with 5 observations with starting time of ${startingTime}`, () => { - const oracleFixture5Observations = async () => { - const oracle = await oracleFixture() - await oracle.initialize({ liquidity: 5, tick: -5, time: startingTime }) - await oracle.grow(5) - await oracle.update({ advanceTimeBy: 3, tick: 1, liquidity: 2 }) - await oracle.update({ advanceTimeBy: 2, tick: -6, liquidity: 4 }) - await oracle.update({ advanceTimeBy: 4, tick: -2, liquidity: 4 }) - await oracle.update({ advanceTimeBy: 1, tick: -2, liquidity: 9 }) - await oracle.update({ advanceTimeBy: 3, tick: 4, liquidity: 2 }) - await oracle.update({ advanceTimeBy: 6, tick: 6, liquidity: 7 }) - return oracle - } - let oracle: OracleTest - beforeEach('set up observations', async () => { - oracle = await loadFixture(oracleFixture5Observations) - }) - - const observeSingle = async (secondsAgo: number) => { - const { - tickCumulatives: [tickCumulative], - secondsPerLiquidityCumulativeX128s: [secondsPerLiquidityCumulativeX128], - } = await oracle.observe([secondsAgo]) - return { secondsPerLiquidityCumulativeX128, tickCumulative } - } - - it('index, cardinality, cardinality next', async () => { - expect(await oracle.index()).to.eq(1) - expect(await oracle.cardinality()).to.eq(5) - expect(await oracle.cardinalityNext()).to.eq(5) - }) - it('latest observation same time as latest', async () => { - const { tickCumulative, secondsPerLiquidityCumulativeX128 } = await observeSingle(0) - expect(tickCumulative).to.eq(-21) - expect(secondsPerLiquidityCumulativeX128).to.eq('2104079302127802832415199655953100107502') - }) - it('latest observation 5 seconds after latest', async () => { - await oracle.advanceTime(5) - const { tickCumulative, secondsPerLiquidityCumulativeX128 } = await observeSingle(5) - expect(tickCumulative).to.eq(-21) - expect(secondsPerLiquidityCumulativeX128).to.eq('2104079302127802832415199655953100107502') - }) - it('current observation 5 seconds after latest', async () => { - await oracle.advanceTime(5) - const { tickCumulative, secondsPerLiquidityCumulativeX128 } = await observeSingle(0) - expect(tickCumulative).to.eq(9) - expect(secondsPerLiquidityCumulativeX128).to.eq('2347138135642758877746181518404363115684') - }) - it('between latest observation and just before latest observation at same time as latest', async () => { - const { tickCumulative, secondsPerLiquidityCumulativeX128 } = await observeSingle(3) - expect(tickCumulative).to.eq(-33) - expect(secondsPerLiquidityCumulativeX128).to.eq('1593655751746395137220137744805447790318') - }) - it('between latest observation and just before latest observation after the latest observation', async () => { - await oracle.advanceTime(5) - const { tickCumulative, secondsPerLiquidityCumulativeX128 } = await observeSingle(8) - expect(tickCumulative).to.eq(-33) - expect(secondsPerLiquidityCumulativeX128).to.eq('1593655751746395137220137744805447790318') - }) - it('older than oldest reverts', async () => { - await expect(observeSingle(15)).to.be.revertedWith('OLD') - await oracle.advanceTime(5) - await expect(observeSingle(20)).to.be.revertedWith('OLD') - }) - it('oldest observation', async () => { - const { tickCumulative, secondsPerLiquidityCumulativeX128 } = await observeSingle(14) - expect(tickCumulative).to.eq(-13) - expect(secondsPerLiquidityCumulativeX128).to.eq('544451787073501541541399371890829138329') - }) - it('oldest observation after some time', async () => { - await oracle.advanceTime(6) - const { tickCumulative, secondsPerLiquidityCumulativeX128 } = await observeSingle(20) - expect(tickCumulative).to.eq(-13) - expect(secondsPerLiquidityCumulativeX128).to.eq('544451787073501541541399371890829138329') - }) - - it('fetch many values', async () => { - await oracle.advanceTime(6) - const { tickCumulatives, secondsPerLiquidityCumulativeX128s } = await oracle.observe([ - 20, - 17, - 13, - 10, - 5, - 1, - 0, - ]) - expect({ - tickCumulatives: tickCumulatives.map((tc) => tc.toNumber()), - secondsPerLiquidityCumulativeX128s: secondsPerLiquidityCumulativeX128s.map((lc) => lc.toString()), - }).to.matchSnapshot() - }) - - it('gas all of last 20 seconds', async () => { - await oracle.advanceTime(6) - await snapshotGasCost( - oracle.getGasCostOfObserve([20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]) - ) - }) - - it('gas latest equal', async () => { - await snapshotGasCost(oracle.getGasCostOfObserve([0])) - }) - it('gas latest transform', async () => { - await oracle.advanceTime(5) - await snapshotGasCost(oracle.getGasCostOfObserve([0])) - }) - it('gas oldest', async () => { - await snapshotGasCost(oracle.getGasCostOfObserve([14])) - }) - it('gas between oldest and oldest + 1', async () => { - await snapshotGasCost(oracle.getGasCostOfObserve([13])) - }) - it('gas middle', async () => { - await snapshotGasCost(oracle.getGasCostOfObserve([5])) - }) - }) - } - }) - - describe.skip('full oracle', function () { - this.timeout(1_200_000) - - let oracle: OracleTest - - const BATCH_SIZE = 300 - - const STARTING_TIME = TEST_POOL_START_TIME - - const maxedOutOracleFixture = async () => { - const oracle = await oracleFixture() - await oracle.initialize({ liquidity: 0, tick: 0, time: STARTING_TIME }) - let cardinalityNext = await oracle.cardinalityNext() - while (cardinalityNext < 65535) { - const growTo = Math.min(65535, cardinalityNext + BATCH_SIZE) - console.log('growing from', cardinalityNext, 'to', growTo) - await oracle.grow(growTo) - cardinalityNext = growTo - } - - for (let i = 0; i < 65535; i += BATCH_SIZE) { - console.log('batch update starting at', i) - const batch = Array(BATCH_SIZE) - .fill(null) - .map((_, j) => ({ - advanceTimeBy: 13, - tick: -i - j, - liquidity: i + j, - })) - await oracle.batchUpdate(batch) - } - - return oracle - } - - beforeEach('create a full oracle', async () => { - oracle = await loadFixture(maxedOutOracleFixture) - }) - - it('has max cardinality next', async () => { - expect(await oracle.cardinalityNext()).to.eq(65535) - }) - - it('has max cardinality', async () => { - expect(await oracle.cardinality()).to.eq(65535) - }) - - it('index wrapped around', async () => { - expect(await oracle.index()).to.eq(165) - }) - - async function checkObserve( - secondsAgo: number, - expected?: { tickCumulative: BigNumberish; secondsPerLiquidityCumulativeX128: BigNumberish } - ) { - const { tickCumulatives, secondsPerLiquidityCumulativeX128s } = await oracle.observe([secondsAgo]) - const check = { - tickCumulative: tickCumulatives[0].toString(), - secondsPerLiquidityCumulativeX128: secondsPerLiquidityCumulativeX128s[0].toString(), - } - if (typeof expected === 'undefined') { - expect(check).to.matchSnapshot() - } else { - expect(check).to.deep.eq({ - tickCumulative: expected.tickCumulative.toString(), - secondsPerLiquidityCumulativeX128: expected.secondsPerLiquidityCumulativeX128.toString(), - }) - } - } - - it('can observe into the ordered portion with exact seconds ago', async () => { - await checkObserve(100 * 13, { - secondsPerLiquidityCumulativeX128: '60465049086512033878831623038233202591033', - tickCumulative: '-27970560813', - }) - }) - - it('can observe into the ordered portion with unexact seconds ago', async () => { - await checkObserve(100 * 13 + 5, { - secondsPerLiquidityCumulativeX128: '60465023149565257990964350912969670793706', - tickCumulative: '-27970232823', - }) - }) - - it('can observe at exactly the latest observation', async () => { - await checkObserve(0, { - secondsPerLiquidityCumulativeX128: '60471787506468701386237800669810720099776', - tickCumulative: '-28055903863', - }) - }) - - it('can observe at exactly the latest observation after some time passes', async () => { - await oracle.advanceTime(5) - await checkObserve(5, { - secondsPerLiquidityCumulativeX128: '60471787506468701386237800669810720099776', - tickCumulative: '-28055903863', - }) - }) - - it('can observe after the latest observation counterfactual', async () => { - await oracle.advanceTime(5) - await checkObserve(3, { - secondsPerLiquidityCumulativeX128: '60471797865298117996489508104462919730461', - tickCumulative: '-28056035261', - }) - }) - - it('can observe into the unordered portion of array at exact seconds ago of observation', async () => { - await checkObserve(200 * 13, { - secondsPerLiquidityCumulativeX128: '60458300386499273141628780395875293027404', - tickCumulative: '-27885347763', - }) - }) - - it('can observe into the unordered portion of array at seconds ago between observations', async () => { - await checkObserve(200 * 13 + 5, { - secondsPerLiquidityCumulativeX128: '60458274409952896081377821330361274907140', - tickCumulative: '-27885020273', - }) - }) - - it('can observe the oldest observation 13*65534 seconds ago', async () => { - await checkObserve(13 * 65534, { - secondsPerLiquidityCumulativeX128: '33974356747348039873972993881117400879779', - tickCumulative: '-175890', - }) - }) - - it('can observe the oldest observation 13*65534 + 5 seconds ago if time has elapsed', async () => { - await oracle.advanceTime(5) - await checkObserve(13 * 65534 + 5, { - secondsPerLiquidityCumulativeX128: '33974356747348039873972993881117400879779', - tickCumulative: '-175890', - }) - }) - - it('gas cost of observe(0)', async () => { - await snapshotGasCost(oracle.getGasCostOfObserve([0])) - }) - it('gas cost of observe(200 * 13)', async () => { - await snapshotGasCost(oracle.getGasCostOfObserve([200 + 13])) - }) - it('gas cost of observe(200 * 13 + 5)', async () => { - await snapshotGasCost(oracle.getGasCostOfObserve([200 + 13 + 5])) - }) - it('gas cost of observe(0) after 5 seconds', async () => { - await oracle.advanceTime(5) - await snapshotGasCost(oracle.getGasCostOfObserve([0])) - }) - it('gas cost of observe(5) after 5 seconds', async () => { - await oracle.advanceTime(5) - await snapshotGasCost(oracle.getGasCostOfObserve([5])) - }) - it('gas cost of observe(oldest)', async () => { - await snapshotGasCost(oracle.getGasCostOfObserve([65534 * 13])) - }) - it('gas cost of observe(oldest) after 5 seconds', async () => { - await oracle.advanceTime(5) - await snapshotGasCost(oracle.getGasCostOfObserve([65534 * 13 + 5])) - }) - }) -}) diff --git a/lib/v3-core/test/SqrtPriceMath.spec.ts b/lib/v3-core/test/SqrtPriceMath.spec.ts deleted file mode 100644 index ef01245..0000000 --- a/lib/v3-core/test/SqrtPriceMath.spec.ts +++ /dev/null @@ -1,379 +0,0 @@ -import { BigNumber, constants } from 'ethers' -import { ethers } from 'hardhat' -import { SqrtPriceMathTest } from '../typechain/SqrtPriceMathTest' - -import { expect } from './shared/expect' -import snapshotGasCost from './shared/snapshotGasCost' -import { encodePriceSqrt, expandTo18Decimals, MaxUint128 } from './shared/utilities' - -const { - constants: { MaxUint256 }, -} = ethers - -describe('SqrtPriceMath', () => { - let sqrtPriceMath: SqrtPriceMathTest - before(async () => { - const sqrtPriceMathTestFactory = await ethers.getContractFactory('SqrtPriceMathTest') - sqrtPriceMath = (await sqrtPriceMathTestFactory.deploy()) as SqrtPriceMathTest - }) - - describe('#getNextSqrtPriceFromInput', () => { - it('fails if price is zero', async () => { - await expect(sqrtPriceMath.getNextSqrtPriceFromInput(0, 0, expandTo18Decimals(1).div(10), false)).to.be.reverted - }) - - it('fails if liquidity is zero', async () => { - await expect(sqrtPriceMath.getNextSqrtPriceFromInput(1, 0, expandTo18Decimals(1).div(10), true)).to.be.reverted - }) - - it('fails if input amount overflows the price', async () => { - const price = BigNumber.from(2).pow(160).sub(1) - const liquidity = 1024 - const amountIn = 1024 - await expect(sqrtPriceMath.getNextSqrtPriceFromInput(price, liquidity, amountIn, false)).to.be.reverted - }) - - it('any input amount cannot underflow the price', async () => { - const price = 1 - const liquidity = 1 - const amountIn = BigNumber.from(2).pow(255) - expect(await sqrtPriceMath.getNextSqrtPriceFromInput(price, liquidity, amountIn, true)).to.eq(1) - }) - - it('returns input price if amount in is zero and zeroForOne = true', async () => { - const price = encodePriceSqrt(1, 1) - expect(await sqrtPriceMath.getNextSqrtPriceFromInput(price, expandTo18Decimals(1).div(10), 0, true)).to.eq(price) - }) - - it('returns input price if amount in is zero and zeroForOne = false', async () => { - const price = encodePriceSqrt(1, 1) - expect(await sqrtPriceMath.getNextSqrtPriceFromInput(price, expandTo18Decimals(1).div(10), 0, false)).to.eq(price) - }) - - it('returns the minimum price for max inputs', async () => { - const sqrtP = BigNumber.from(2).pow(160).sub(1) - const liquidity = MaxUint128 - const maxAmountNoOverflow = MaxUint256.sub(liquidity.shl(96).div(sqrtP)) - expect(await sqrtPriceMath.getNextSqrtPriceFromInput(sqrtP, liquidity, maxAmountNoOverflow, true)).to.eq('1') - }) - - it('input amount of 0.1 token1', async () => { - const sqrtQ = await sqrtPriceMath.getNextSqrtPriceFromInput( - encodePriceSqrt(1, 1), - expandTo18Decimals(1), - expandTo18Decimals(1).div(10), - false - ) - expect(sqrtQ).to.eq('87150978765690771352898345369') - }) - - it('input amount of 0.1 token0', async () => { - const sqrtQ = await sqrtPriceMath.getNextSqrtPriceFromInput( - encodePriceSqrt(1, 1), - expandTo18Decimals(1), - expandTo18Decimals(1).div(10), - true - ) - expect(sqrtQ).to.eq('72025602285694852357767227579') - }) - - it('amountIn > type(uint96).max and zeroForOne = true', async () => { - expect( - await sqrtPriceMath.getNextSqrtPriceFromInput( - encodePriceSqrt(1, 1), - expandTo18Decimals(10), - BigNumber.from(2).pow(100), - true - ) - // perfect answer: - // https://www.wolframalpha.com/input/?i=624999999995069620+-+%28%281e19+*+1+%2F+%281e19+%2B+2%5E100+*+1%29%29+*+2%5E96%29 - ).to.eq('624999999995069620') - }) - - it('can return 1 with enough amountIn and zeroForOne = true', async () => { - expect( - await sqrtPriceMath.getNextSqrtPriceFromInput(encodePriceSqrt(1, 1), 1, constants.MaxUint256.div(2), true) - ).to.eq(1) - }) - - it('zeroForOne = true gas', async () => { - await snapshotGasCost( - sqrtPriceMath.getGasCostOfGetNextSqrtPriceFromInput( - encodePriceSqrt(1, 1), - expandTo18Decimals(1), - expandTo18Decimals(1).div(10), - true - ) - ) - }) - - it('zeroForOne = false gas', async () => { - await snapshotGasCost( - sqrtPriceMath.getGasCostOfGetNextSqrtPriceFromInput( - encodePriceSqrt(1, 1), - expandTo18Decimals(1), - expandTo18Decimals(1).div(10), - false - ) - ) - }) - }) - - describe('#getNextSqrtPriceFromOutput', () => { - it('fails if price is zero', async () => { - await expect(sqrtPriceMath.getNextSqrtPriceFromOutput(0, 0, expandTo18Decimals(1).div(10), false)).to.be.reverted - }) - - it('fails if liquidity is zero', async () => { - await expect(sqrtPriceMath.getNextSqrtPriceFromOutput(1, 0, expandTo18Decimals(1).div(10), true)).to.be.reverted - }) - - it('fails if output amount is exactly the virtual reserves of token0', async () => { - const price = '20282409603651670423947251286016' - const liquidity = 1024 - const amountOut = 4 - await expect(sqrtPriceMath.getNextSqrtPriceFromOutput(price, liquidity, amountOut, false)).to.be.reverted - }) - - it('fails if output amount is greater than virtual reserves of token0', async () => { - const price = '20282409603651670423947251286016' - const liquidity = 1024 - const amountOut = 5 - await expect(sqrtPriceMath.getNextSqrtPriceFromOutput(price, liquidity, amountOut, false)).to.be.reverted - }) - - it('fails if output amount is greater than virtual reserves of token1', async () => { - const price = '20282409603651670423947251286016' - const liquidity = 1024 - const amountOut = 262145 - await expect(sqrtPriceMath.getNextSqrtPriceFromOutput(price, liquidity, amountOut, true)).to.be.reverted - }) - - it('fails if output amount is exactly the virtual reserves of token1', async () => { - const price = '20282409603651670423947251286016' - const liquidity = 1024 - const amountOut = 262144 - await expect(sqrtPriceMath.getNextSqrtPriceFromOutput(price, liquidity, amountOut, true)).to.be.reverted - }) - - it('succeeds if output amount is just less than the virtual reserves of token1', async () => { - const price = '20282409603651670423947251286016' - const liquidity = 1024 - const amountOut = 262143 - const sqrtQ = await sqrtPriceMath.getNextSqrtPriceFromOutput(price, liquidity, amountOut, true) - expect(sqrtQ).to.eq('77371252455336267181195264') - }) - - it('puzzling echidna test', async () => { - const price = '20282409603651670423947251286016' - const liquidity = 1024 - const amountOut = 4 - - await expect(sqrtPriceMath.getNextSqrtPriceFromOutput(price, liquidity, amountOut, false)).to.be.reverted - }) - - it('returns input price if amount in is zero and zeroForOne = true', async () => { - const price = encodePriceSqrt(1, 1) - expect(await sqrtPriceMath.getNextSqrtPriceFromOutput(price, expandTo18Decimals(1).div(10), 0, true)).to.eq(price) - }) - - it('returns input price if amount in is zero and zeroForOne = false', async () => { - const price = encodePriceSqrt(1, 1) - expect(await sqrtPriceMath.getNextSqrtPriceFromOutput(price, expandTo18Decimals(1).div(10), 0, false)).to.eq( - price - ) - }) - - it('output amount of 0.1 token1', async () => { - const sqrtQ = await sqrtPriceMath.getNextSqrtPriceFromOutput( - encodePriceSqrt(1, 1), - expandTo18Decimals(1), - expandTo18Decimals(1).div(10), - false - ) - expect(sqrtQ).to.eq('88031291682515930659493278152') - }) - - it('output amount of 0.1 token1', async () => { - const sqrtQ = await sqrtPriceMath.getNextSqrtPriceFromOutput( - encodePriceSqrt(1, 1), - expandTo18Decimals(1), - expandTo18Decimals(1).div(10), - true - ) - expect(sqrtQ).to.eq('71305346262837903834189555302') - }) - - it('reverts if amountOut is impossible in zero for one direction', async () => { - await expect(sqrtPriceMath.getNextSqrtPriceFromOutput(encodePriceSqrt(1, 1), 1, constants.MaxUint256, true)).to.be - .reverted - }) - - it('reverts if amountOut is impossible in one for zero direction', async () => { - await expect(sqrtPriceMath.getNextSqrtPriceFromOutput(encodePriceSqrt(1, 1), 1, constants.MaxUint256, false)).to - .be.reverted - }) - - it('zeroForOne = true gas', async () => { - await snapshotGasCost( - sqrtPriceMath.getGasCostOfGetNextSqrtPriceFromOutput( - encodePriceSqrt(1, 1), - expandTo18Decimals(1), - expandTo18Decimals(1).div(10), - true - ) - ) - }) - - it('zeroForOne = false gas', async () => { - await snapshotGasCost( - sqrtPriceMath.getGasCostOfGetNextSqrtPriceFromOutput( - encodePriceSqrt(1, 1), - expandTo18Decimals(1), - expandTo18Decimals(1).div(10), - false - ) - ) - }) - }) - - describe('#getAmount0Delta', () => { - it('returns 0 if liquidity is 0', async () => { - const amount0 = await sqrtPriceMath.getAmount0Delta(encodePriceSqrt(1, 1), encodePriceSqrt(2, 1), 0, true) - - expect(amount0).to.eq(0) - }) - it('returns 0 if prices are equal', async () => { - const amount0 = await sqrtPriceMath.getAmount0Delta(encodePriceSqrt(1, 1), encodePriceSqrt(1, 1), 0, true) - - expect(amount0).to.eq(0) - }) - - it('returns 0.1 amount1 for price of 1 to 1.21', async () => { - const amount0 = await sqrtPriceMath.getAmount0Delta( - encodePriceSqrt(1, 1), - encodePriceSqrt(121, 100), - expandTo18Decimals(1), - true - ) - expect(amount0).to.eq('90909090909090910') - - const amount0RoundedDown = await sqrtPriceMath.getAmount0Delta( - encodePriceSqrt(1, 1), - encodePriceSqrt(121, 100), - expandTo18Decimals(1), - false - ) - - expect(amount0RoundedDown).to.eq(amount0.sub(1)) - }) - - it('works for prices that overflow', async () => { - const amount0Up = await sqrtPriceMath.getAmount0Delta( - encodePriceSqrt(BigNumber.from(2).pow(90), 1), - encodePriceSqrt(BigNumber.from(2).pow(96), 1), - expandTo18Decimals(1), - true - ) - const amount0Down = await sqrtPriceMath.getAmount0Delta( - encodePriceSqrt(BigNumber.from(2).pow(90), 1), - encodePriceSqrt(BigNumber.from(2).pow(96), 1), - expandTo18Decimals(1), - false - ) - expect(amount0Up).to.eq(amount0Down.add(1)) - }) - - it(`gas cost for amount0 where roundUp = true`, async () => { - await snapshotGasCost( - sqrtPriceMath.getGasCostOfGetAmount0Delta( - encodePriceSqrt(100, 121), - encodePriceSqrt(1, 1), - expandTo18Decimals(1), - true - ) - ) - }) - - it(`gas cost for amount0 where roundUp = true`, async () => { - await snapshotGasCost( - sqrtPriceMath.getGasCostOfGetAmount0Delta( - encodePriceSqrt(100, 121), - encodePriceSqrt(1, 1), - expandTo18Decimals(1), - false - ) - ) - }) - }) - - describe('#getAmount1Delta', () => { - it('returns 0 if liquidity is 0', async () => { - const amount1 = await sqrtPriceMath.getAmount1Delta(encodePriceSqrt(1, 1), encodePriceSqrt(2, 1), 0, true) - - expect(amount1).to.eq(0) - }) - it('returns 0 if prices are equal', async () => { - const amount1 = await sqrtPriceMath.getAmount0Delta(encodePriceSqrt(1, 1), encodePriceSqrt(1, 1), 0, true) - - expect(amount1).to.eq(0) - }) - - it('returns 0.1 amount1 for price of 1 to 1.21', async () => { - const amount1 = await sqrtPriceMath.getAmount1Delta( - encodePriceSqrt(1, 1), - encodePriceSqrt(121, 100), - expandTo18Decimals(1), - true - ) - - expect(amount1).to.eq('100000000000000000') - const amount1RoundedDown = await sqrtPriceMath.getAmount1Delta( - encodePriceSqrt(1, 1), - encodePriceSqrt(121, 100), - expandTo18Decimals(1), - false - ) - - expect(amount1RoundedDown).to.eq(amount1.sub(1)) - }) - - it(`gas cost for amount0 where roundUp = true`, async () => { - await snapshotGasCost( - sqrtPriceMath.getGasCostOfGetAmount0Delta( - encodePriceSqrt(100, 121), - encodePriceSqrt(1, 1), - expandTo18Decimals(1), - true - ) - ) - }) - - it(`gas cost for amount0 where roundUp = false`, async () => { - await snapshotGasCost( - sqrtPriceMath.getGasCostOfGetAmount0Delta( - encodePriceSqrt(100, 121), - encodePriceSqrt(1, 1), - expandTo18Decimals(1), - false - ) - ) - }) - }) - - describe('swap computation', () => { - it('sqrtP * sqrtQ overflows', async () => { - // getNextSqrtPriceInvariants(1025574284609383690408304870162715216695788925244,50015962439936049619261659728067971248,406,true) - const sqrtP = '1025574284609383690408304870162715216695788925244' - const liquidity = '50015962439936049619261659728067971248' - const zeroForOne = true - const amountIn = '406' - - const sqrtQ = await sqrtPriceMath.getNextSqrtPriceFromInput(sqrtP, liquidity, amountIn, zeroForOne) - expect(sqrtQ).to.eq('1025574284609383582644711336373707553698163132913') - - const amount0Delta = await sqrtPriceMath.getAmount0Delta(sqrtQ, sqrtP, liquidity, true) - expect(amount0Delta).to.eq('406') - }) - }) -}) diff --git a/lib/v3-core/test/SwapMath.spec.ts b/lib/v3-core/test/SwapMath.spec.ts deleted file mode 100644 index 2dbd920..0000000 --- a/lib/v3-core/test/SwapMath.spec.ts +++ /dev/null @@ -1,324 +0,0 @@ -import { BigNumber } from 'ethers' -import { ethers } from 'hardhat' -import { SwapMathTest } from '../typechain/SwapMathTest' - -import { expect } from './shared/expect' -import snapshotGasCost from './shared/snapshotGasCost' -import { encodePriceSqrt, expandTo18Decimals } from './shared/utilities' -import { SqrtPriceMathTest } from '../typechain/SqrtPriceMathTest' - -describe('SwapMath', () => { - let swapMath: SwapMathTest - let sqrtPriceMath: SqrtPriceMathTest - before(async () => { - const swapMathTestFactory = await ethers.getContractFactory('SwapMathTest') - const sqrtPriceMathTestFactory = await ethers.getContractFactory('SqrtPriceMathTest') - swapMath = (await swapMathTestFactory.deploy()) as SwapMathTest - sqrtPriceMath = (await sqrtPriceMathTestFactory.deploy()) as SqrtPriceMathTest - }) - - describe('#computeSwapStep', () => { - it('exact amount in that gets capped at price target in one for zero', async () => { - const price = encodePriceSqrt(1, 1) - const priceTarget = encodePriceSqrt(101, 100) - const liquidity = expandTo18Decimals(2) - const amount = expandTo18Decimals(1) - const fee = 600 - const zeroForOne = false - - const { amountIn, amountOut, sqrtQ, feeAmount } = await swapMath.computeSwapStep( - price, - priceTarget, - liquidity, - amount, - fee - ) - - expect(amountIn).to.eq('9975124224178055') - expect(feeAmount).to.eq('5988667735148') - expect(amountOut).to.eq('9925619580021728') - expect(amountIn.add(feeAmount), 'entire amount is not used').to.lt(amount) - - const priceAfterWholeInputAmount = await sqrtPriceMath.getNextSqrtPriceFromInput( - price, - liquidity, - amount, - zeroForOne - ) - - expect(sqrtQ, 'price is capped at price target').to.eq(priceTarget) - expect(sqrtQ, 'price is less than price after whole input amount').to.lt(priceAfterWholeInputAmount) - }) - - it('exact amount out that gets capped at price target in one for zero', async () => { - const price = encodePriceSqrt(1, 1) - const priceTarget = encodePriceSqrt(101, 100) - const liquidity = expandTo18Decimals(2) - const amount = expandTo18Decimals(1).mul(-1) - const fee = 600 - const zeroForOne = false - - const { amountIn, amountOut, sqrtQ, feeAmount } = await swapMath.computeSwapStep( - price, - priceTarget, - liquidity, - amount, - fee - ) - - expect(amountIn).to.eq('9975124224178055') - expect(feeAmount).to.eq('5988667735148') - expect(amountOut).to.eq('9925619580021728') - expect(amountOut, 'entire amount out is not returned').to.lt(amount.mul(-1)) - - const priceAfterWholeOutputAmount = await sqrtPriceMath.getNextSqrtPriceFromOutput( - price, - liquidity, - amount.mul(-1), - zeroForOne - ) - - expect(sqrtQ, 'price is capped at price target').to.eq(priceTarget) - expect(sqrtQ, 'price is less than price after whole output amount').to.lt(priceAfterWholeOutputAmount) - }) - - it('exact amount in that is fully spent in one for zero', async () => { - const price = encodePriceSqrt(1, 1) - const priceTarget = encodePriceSqrt(1000, 100) - const liquidity = expandTo18Decimals(2) - const amount = expandTo18Decimals(1) - const fee = 600 - const zeroForOne = false - - const { amountIn, amountOut, sqrtQ, feeAmount } = await swapMath.computeSwapStep( - price, - priceTarget, - liquidity, - amount, - fee - ) - - expect(amountIn).to.eq('999400000000000000') - expect(feeAmount).to.eq('600000000000000') - expect(amountOut).to.eq('666399946655997866') - expect(amountIn.add(feeAmount), 'entire amount is used').to.eq(amount) - - const priceAfterWholeInputAmountLessFee = await sqrtPriceMath.getNextSqrtPriceFromInput( - price, - liquidity, - amount.sub(feeAmount), - zeroForOne - ) - - expect(sqrtQ, 'price does not reach price target').to.be.lt(priceTarget) - expect(sqrtQ, 'price is equal to price after whole input amount').to.eq(priceAfterWholeInputAmountLessFee) - }) - - it('exact amount out that is fully received in one for zero', async () => { - const price = encodePriceSqrt(1, 1) - const priceTarget = encodePriceSqrt(10000, 100) - const liquidity = expandTo18Decimals(2) - const amount = expandTo18Decimals(1).mul(-1) - const fee = 600 - const zeroForOne = false - - const { amountIn, amountOut, sqrtQ, feeAmount } = await swapMath.computeSwapStep( - price, - priceTarget, - liquidity, - amount, - fee - ) - - expect(amountIn).to.eq('2000000000000000000') - expect(feeAmount).to.eq('1200720432259356') - expect(amountOut).to.eq(amount.mul(-1)) - - const priceAfterWholeOutputAmount = await sqrtPriceMath.getNextSqrtPriceFromOutput( - price, - liquidity, - amount.mul(-1), - zeroForOne - ) - - expect(sqrtQ, 'price does not reach price target').to.be.lt(priceTarget) - expect(sqrtQ, 'price is less than price after whole output amount').to.eq(priceAfterWholeOutputAmount) - }) - - it('amount out is capped at the desired amount out', async () => { - const { amountIn, amountOut, sqrtQ, feeAmount } = await swapMath.computeSwapStep( - BigNumber.from('417332158212080721273783715441582'), - BigNumber.from('1452870262520218020823638996'), - '159344665391607089467575320103', - '-1', - 1 - ) - expect(amountIn).to.eq('1') - expect(feeAmount).to.eq('1') - expect(amountOut).to.eq('1') // would be 2 if not capped - expect(sqrtQ).to.eq('417332158212080721273783715441581') - }) - - it('target price of 1 uses partial input amount', async () => { - const { amountIn, amountOut, sqrtQ, feeAmount } = await swapMath.computeSwapStep( - BigNumber.from('2'), - BigNumber.from('1'), - '1', - '3915081100057732413702495386755767', - 1 - ) - expect(amountIn).to.eq('39614081257132168796771975168') - expect(feeAmount).to.eq('39614120871253040049813') - expect(amountIn.add(feeAmount)).to.be.lte('3915081100057732413702495386755767') - expect(amountOut).to.eq('0') - expect(sqrtQ).to.eq('1') - }) - - it('entire input amount taken as fee', async () => { - const { amountIn, amountOut, sqrtQ, feeAmount } = await swapMath.computeSwapStep( - '2413', - '79887613182836312', - '1985041575832132834610021537970', - '10', - 1872 - ) - expect(amountIn).to.eq('0') - expect(feeAmount).to.eq('10') - expect(amountOut).to.eq('0') - expect(sqrtQ).to.eq('2413') - }) - - it('handles intermediate insufficient liquidity in zero for one exact output case', async () => { - const sqrtP = BigNumber.from('20282409603651670423947251286016') - const sqrtPTarget = sqrtP.mul(11).div(10) - const liquidity = 1024 - // virtual reserves of one are only 4 - // https://www.wolframalpha.com/input/?i=1024+%2F+%2820282409603651670423947251286016+%2F+2**96%29 - const amountRemaining = -4 - const feePips = 3000 - const { amountIn, amountOut, sqrtQ, feeAmount } = await swapMath.computeSwapStep( - sqrtP, - sqrtPTarget, - liquidity, - amountRemaining, - feePips - ) - expect(amountOut).to.eq(0) - expect(sqrtQ).to.eq(sqrtPTarget) - expect(amountIn).to.eq(26215) - expect(feeAmount).to.eq(79) - }) - - it('handles intermediate insufficient liquidity in one for zero exact output case', async () => { - const sqrtP = BigNumber.from('20282409603651670423947251286016') - const sqrtPTarget = sqrtP.mul(9).div(10) - const liquidity = 1024 - // virtual reserves of zero are only 262144 - // https://www.wolframalpha.com/input/?i=1024+*+%2820282409603651670423947251286016+%2F+2**96%29 - const amountRemaining = -263000 - const feePips = 3000 - const { amountIn, amountOut, sqrtQ, feeAmount } = await swapMath.computeSwapStep( - sqrtP, - sqrtPTarget, - liquidity, - amountRemaining, - feePips - ) - expect(amountOut).to.eq(26214) - expect(sqrtQ).to.eq(sqrtPTarget) - expect(amountIn).to.eq(1) - expect(feeAmount).to.eq(1) - }) - - describe('gas', () => { - it('swap one for zero exact in capped', async () => { - await snapshotGasCost( - swapMath.getGasCostOfComputeSwapStep( - encodePriceSqrt(1, 1), - encodePriceSqrt(101, 100), - expandTo18Decimals(2), - expandTo18Decimals(1), - 600 - ) - ) - }) - it('swap zero for one exact in capped', async () => { - await snapshotGasCost( - swapMath.getGasCostOfComputeSwapStep( - encodePriceSqrt(1, 1), - encodePriceSqrt(99, 100), - expandTo18Decimals(2), - expandTo18Decimals(1), - 600 - ) - ) - }) - it('swap one for zero exact out capped', async () => { - await snapshotGasCost( - swapMath.getGasCostOfComputeSwapStep( - encodePriceSqrt(1, 1), - encodePriceSqrt(101, 100), - expandTo18Decimals(2), - expandTo18Decimals(1).mul(-1), - 600 - ) - ) - }) - it('swap zero for one exact out capped', async () => { - await snapshotGasCost( - swapMath.getGasCostOfComputeSwapStep( - encodePriceSqrt(1, 1), - encodePriceSqrt(99, 100), - expandTo18Decimals(2), - expandTo18Decimals(1).mul(-1), - 600 - ) - ) - }) - it('swap one for zero exact in partial', async () => { - await snapshotGasCost( - swapMath.getGasCostOfComputeSwapStep( - encodePriceSqrt(1, 1), - encodePriceSqrt(1010, 100), - expandTo18Decimals(2), - 1000, - 600 - ) - ) - }) - it('swap zero for one exact in partial', async () => { - await snapshotGasCost( - swapMath.getGasCostOfComputeSwapStep( - encodePriceSqrt(1, 1), - encodePriceSqrt(99, 1000), - expandTo18Decimals(2), - 1000, - 600 - ) - ) - }) - it('swap one for zero exact out partial', async () => { - await snapshotGasCost( - swapMath.getGasCostOfComputeSwapStep( - encodePriceSqrt(1, 1), - encodePriceSqrt(1010, 100), - expandTo18Decimals(2), - 1000, - 600 - ) - ) - }) - it('swap zero for one exact out partial', async () => { - await snapshotGasCost( - swapMath.getGasCostOfComputeSwapStep( - encodePriceSqrt(1, 1), - encodePriceSqrt(99, 1000), - expandTo18Decimals(2), - 1000, - 600 - ) - ) - }) - }) - }) -}) diff --git a/lib/v3-core/test/Tick.spec.ts b/lib/v3-core/test/Tick.spec.ts deleted file mode 100644 index f4b04dc..0000000 --- a/lib/v3-core/test/Tick.spec.ts +++ /dev/null @@ -1,329 +0,0 @@ -import { ethers } from 'hardhat' -import { BigNumber } from 'ethers' -import { TickTest } from '../typechain/TickTest' -import { expect } from './shared/expect' -import { FeeAmount, getMaxLiquidityPerTick, TICK_SPACINGS } from './shared/utilities' - -const MaxUint128 = BigNumber.from(2).pow(128).sub(1) - -const { constants } = ethers - -describe('Tick', () => { - let tickTest: TickTest - - beforeEach('deploy TickTest', async () => { - const tickTestFactory = await ethers.getContractFactory('TickTest') - tickTest = (await tickTestFactory.deploy()) as TickTest - }) - - describe('#tickSpacingToMaxLiquidityPerTick', () => { - it('returns the correct value for low fee', async () => { - const maxLiquidityPerTick = await tickTest.tickSpacingToMaxLiquidityPerTick(TICK_SPACINGS[FeeAmount.LOW]) - expect(maxLiquidityPerTick).to.eq('1917569901783203986719870431555990') // 110.8 bits - expect(maxLiquidityPerTick).to.eq(getMaxLiquidityPerTick(TICK_SPACINGS[FeeAmount.LOW])) - }) - it('returns the correct value for medium fee', async () => { - const maxLiquidityPerTick = await tickTest.tickSpacingToMaxLiquidityPerTick(TICK_SPACINGS[FeeAmount.MEDIUM]) - expect(maxLiquidityPerTick).to.eq('11505743598341114571880798222544994') // 113.1 bits - expect(maxLiquidityPerTick).to.eq(getMaxLiquidityPerTick(TICK_SPACINGS[FeeAmount.MEDIUM])) - }) - it('returns the correct value for high fee', async () => { - const maxLiquidityPerTick = await tickTest.tickSpacingToMaxLiquidityPerTick(TICK_SPACINGS[FeeAmount.HIGH]) - expect(maxLiquidityPerTick).to.eq('38350317471085141830651933667504588') // 114.7 bits - expect(maxLiquidityPerTick).to.eq(getMaxLiquidityPerTick(TICK_SPACINGS[FeeAmount.HIGH])) - }) - it('returns the correct value for entire range', async () => { - const maxLiquidityPerTick = await tickTest.tickSpacingToMaxLiquidityPerTick(887272) - expect(maxLiquidityPerTick).to.eq(MaxUint128.div(3)) // 126 bits - expect(maxLiquidityPerTick).to.eq(getMaxLiquidityPerTick(887272)) - }) - it('returns the correct value for 2302', async () => { - const maxLiquidityPerTick = await tickTest.tickSpacingToMaxLiquidityPerTick(2302) - expect(maxLiquidityPerTick).to.eq('441351967472034323558203122479595605') // 118 bits - expect(maxLiquidityPerTick).to.eq(getMaxLiquidityPerTick(2302)) - }) - }) - - describe('#getFeeGrowthInside', () => { - it('returns all for two uninitialized ticks if tick is inside', async () => { - const { feeGrowthInside0X128, feeGrowthInside1X128 } = await tickTest.getFeeGrowthInside(-2, 2, 0, 15, 15) - expect(feeGrowthInside0X128).to.eq(15) - expect(feeGrowthInside1X128).to.eq(15) - }) - it('returns 0 for two uninitialized ticks if tick is above', async () => { - const { feeGrowthInside0X128, feeGrowthInside1X128 } = await tickTest.getFeeGrowthInside(-2, 2, 4, 15, 15) - expect(feeGrowthInside0X128).to.eq(0) - expect(feeGrowthInside1X128).to.eq(0) - }) - it('returns 0 for two uninitialized ticks if tick is below', async () => { - const { feeGrowthInside0X128, feeGrowthInside1X128 } = await tickTest.getFeeGrowthInside(-2, 2, -4, 15, 15) - expect(feeGrowthInside0X128).to.eq(0) - expect(feeGrowthInside1X128).to.eq(0) - }) - - it('subtracts upper tick if below', async () => { - await tickTest.setTick(2, { - feeGrowthOutside0X128: 2, - feeGrowthOutside1X128: 3, - liquidityGross: 0, - liquidityNet: 0, - secondsPerLiquidityOutsideX128: 0, - tickCumulativeOutside: 0, - secondsOutside: 0, - initialized: true, - }) - const { feeGrowthInside0X128, feeGrowthInside1X128 } = await tickTest.getFeeGrowthInside(-2, 2, 0, 15, 15) - expect(feeGrowthInside0X128).to.eq(13) - expect(feeGrowthInside1X128).to.eq(12) - }) - - it('subtracts lower tick if above', async () => { - await tickTest.setTick(-2, { - feeGrowthOutside0X128: 2, - feeGrowthOutside1X128: 3, - liquidityGross: 0, - liquidityNet: 0, - secondsPerLiquidityOutsideX128: 0, - tickCumulativeOutside: 0, - secondsOutside: 0, - initialized: true, - }) - const { feeGrowthInside0X128, feeGrowthInside1X128 } = await tickTest.getFeeGrowthInside(-2, 2, 0, 15, 15) - expect(feeGrowthInside0X128).to.eq(13) - expect(feeGrowthInside1X128).to.eq(12) - }) - - it('subtracts upper and lower tick if inside', async () => { - await tickTest.setTick(-2, { - feeGrowthOutside0X128: 2, - feeGrowthOutside1X128: 3, - liquidityGross: 0, - liquidityNet: 0, - secondsPerLiquidityOutsideX128: 0, - tickCumulativeOutside: 0, - secondsOutside: 0, - initialized: true, - }) - await tickTest.setTick(2, { - feeGrowthOutside0X128: 4, - feeGrowthOutside1X128: 1, - liquidityGross: 0, - liquidityNet: 0, - secondsPerLiquidityOutsideX128: 0, - tickCumulativeOutside: 0, - secondsOutside: 0, - initialized: true, - }) - const { feeGrowthInside0X128, feeGrowthInside1X128 } = await tickTest.getFeeGrowthInside(-2, 2, 0, 15, 15) - expect(feeGrowthInside0X128).to.eq(9) - expect(feeGrowthInside1X128).to.eq(11) - }) - - it('works correctly with overflow on inside tick', async () => { - await tickTest.setTick(-2, { - feeGrowthOutside0X128: constants.MaxUint256.sub(3), - feeGrowthOutside1X128: constants.MaxUint256.sub(2), - liquidityGross: 0, - liquidityNet: 0, - secondsPerLiquidityOutsideX128: 0, - tickCumulativeOutside: 0, - secondsOutside: 0, - initialized: true, - }) - await tickTest.setTick(2, { - feeGrowthOutside0X128: 3, - feeGrowthOutside1X128: 5, - liquidityGross: 0, - liquidityNet: 0, - secondsPerLiquidityOutsideX128: 0, - tickCumulativeOutside: 0, - secondsOutside: 0, - initialized: true, - }) - const { feeGrowthInside0X128, feeGrowthInside1X128 } = await tickTest.getFeeGrowthInside(-2, 2, 0, 15, 15) - expect(feeGrowthInside0X128).to.eq(16) - expect(feeGrowthInside1X128).to.eq(13) - }) - }) - - describe('#update', async () => { - it('flips from zero to nonzero', async () => { - expect(await tickTest.callStatic.update(0, 0, 1, 0, 0, 0, 0, 0, false, 3)).to.eq(true) - }) - it('does not flip from nonzero to greater nonzero', async () => { - await tickTest.update(0, 0, 1, 0, 0, 0, 0, 0, false, 3) - expect(await tickTest.callStatic.update(0, 0, 1, 0, 0, 0, 0, 0, false, 3)).to.eq(false) - }) - it('flips from nonzero to zero', async () => { - await tickTest.update(0, 0, 1, 0, 0, 0, 0, 0, false, 3) - expect(await tickTest.callStatic.update(0, 0, -1, 0, 0, 0, 0, 0, false, 3)).to.eq(true) - }) - it('does not flip from nonzero to lesser nonzero', async () => { - await tickTest.update(0, 0, 2, 0, 0, 0, 0, 0, false, 3) - expect(await tickTest.callStatic.update(0, 0, -1, 0, 0, 0, 0, 0, false, 3)).to.eq(false) - }) - it('does not flip from nonzero to lesser nonzero', async () => { - await tickTest.update(0, 0, 2, 0, 0, 0, 0, 0, false, 3) - expect(await tickTest.callStatic.update(0, 0, -1, 0, 0, 0, 0, 0, false, 3)).to.eq(false) - }) - it('reverts if total liquidity gross is greater than max', async () => { - await tickTest.update(0, 0, 2, 0, 0, 0, 0, 0, false, 3) - await tickTest.update(0, 0, 1, 0, 0, 0, 0, 0, true, 3) - await expect(tickTest.update(0, 0, 1, 0, 0, 0, 0, 0, false, 3)).to.be.revertedWith('LO') - }) - it('nets the liquidity based on upper flag', async () => { - await tickTest.update(0, 0, 2, 0, 0, 0, 0, 0, false, 10) - await tickTest.update(0, 0, 1, 0, 0, 0, 0, 0, true, 10) - await tickTest.update(0, 0, 3, 0, 0, 0, 0, 0, true, 10) - await tickTest.update(0, 0, 1, 0, 0, 0, 0, 0, false, 10) - const { liquidityGross, liquidityNet } = await tickTest.ticks(0) - expect(liquidityGross).to.eq(2 + 1 + 3 + 1) - expect(liquidityNet).to.eq(2 - 1 - 3 + 1) - }) - it('reverts on overflow liquidity gross', async () => { - await tickTest.update(0, 0, MaxUint128.div(2).sub(1), 0, 0, 0, 0, 0, false, MaxUint128) - await expect(tickTest.update(0, 0, MaxUint128.div(2).sub(1), 0, 0, 0, 0, 0, false, MaxUint128)).to.be.reverted - }) - it('assumes all growth happens below ticks lte current tick', async () => { - await tickTest.update(1, 1, 1, 1, 2, 3, 4, 5, false, MaxUint128) - const { - feeGrowthOutside0X128, - feeGrowthOutside1X128, - secondsOutside, - secondsPerLiquidityOutsideX128, - tickCumulativeOutside, - initialized, - } = await tickTest.ticks(1) - expect(feeGrowthOutside0X128).to.eq(1) - expect(feeGrowthOutside1X128).to.eq(2) - expect(secondsPerLiquidityOutsideX128).to.eq(3) - expect(tickCumulativeOutside).to.eq(4) - expect(secondsOutside).to.eq(5) - expect(initialized).to.eq(true) - }) - it('does not set any growth fields if tick is already initialized', async () => { - await tickTest.update(1, 1, 1, 1, 2, 3, 4, 5, false, MaxUint128) - await tickTest.update(1, 1, 1, 6, 7, 8, 9, 10, false, MaxUint128) - const { - feeGrowthOutside0X128, - feeGrowthOutside1X128, - secondsOutside, - secondsPerLiquidityOutsideX128, - tickCumulativeOutside, - initialized, - } = await tickTest.ticks(1) - expect(feeGrowthOutside0X128).to.eq(1) - expect(feeGrowthOutside1X128).to.eq(2) - expect(secondsPerLiquidityOutsideX128).to.eq(3) - expect(tickCumulativeOutside).to.eq(4) - expect(secondsOutside).to.eq(5) - expect(initialized).to.eq(true) - }) - it('does not set any growth fields for ticks gt current tick', async () => { - await tickTest.update(2, 1, 1, 1, 2, 3, 4, 5, false, MaxUint128) - const { - feeGrowthOutside0X128, - feeGrowthOutside1X128, - secondsOutside, - secondsPerLiquidityOutsideX128, - tickCumulativeOutside, - initialized, - } = await tickTest.ticks(2) - expect(feeGrowthOutside0X128).to.eq(0) - expect(feeGrowthOutside1X128).to.eq(0) - expect(secondsPerLiquidityOutsideX128).to.eq(0) - expect(tickCumulativeOutside).to.eq(0) - expect(secondsOutside).to.eq(0) - expect(initialized).to.eq(true) - }) - }) - - // this is skipped because the presence of the method causes slither to fail - describe('#clear', async () => { - it('deletes all the data in the tick', async () => { - await tickTest.setTick(2, { - feeGrowthOutside0X128: 1, - feeGrowthOutside1X128: 2, - liquidityGross: 3, - liquidityNet: 4, - secondsPerLiquidityOutsideX128: 5, - tickCumulativeOutside: 6, - secondsOutside: 7, - initialized: true, - }) - await tickTest.clear(2) - const { - feeGrowthOutside0X128, - feeGrowthOutside1X128, - secondsOutside, - secondsPerLiquidityOutsideX128, - liquidityGross, - tickCumulativeOutside, - liquidityNet, - initialized, - } = await tickTest.ticks(2) - expect(feeGrowthOutside0X128).to.eq(0) - expect(feeGrowthOutside1X128).to.eq(0) - expect(secondsOutside).to.eq(0) - expect(secondsPerLiquidityOutsideX128).to.eq(0) - expect(tickCumulativeOutside).to.eq(0) - expect(liquidityGross).to.eq(0) - expect(liquidityNet).to.eq(0) - expect(initialized).to.eq(false) - }) - }) - - describe('#cross', () => { - it('flips the growth variables', async () => { - await tickTest.setTick(2, { - feeGrowthOutside0X128: 1, - feeGrowthOutside1X128: 2, - liquidityGross: 3, - liquidityNet: 4, - secondsPerLiquidityOutsideX128: 5, - tickCumulativeOutside: 6, - secondsOutside: 7, - initialized: true, - }) - await tickTest.cross(2, 7, 9, 8, 15, 10) - const { - feeGrowthOutside0X128, - feeGrowthOutside1X128, - secondsOutside, - tickCumulativeOutside, - secondsPerLiquidityOutsideX128, - } = await tickTest.ticks(2) - expect(feeGrowthOutside0X128).to.eq(6) - expect(feeGrowthOutside1X128).to.eq(7) - expect(secondsPerLiquidityOutsideX128).to.eq(3) - expect(tickCumulativeOutside).to.eq(9) - expect(secondsOutside).to.eq(3) - }) - it('two flips are no op', async () => { - await tickTest.setTick(2, { - feeGrowthOutside0X128: 1, - feeGrowthOutside1X128: 2, - liquidityGross: 3, - liquidityNet: 4, - secondsPerLiquidityOutsideX128: 5, - tickCumulativeOutside: 6, - secondsOutside: 7, - initialized: true, - }) - await tickTest.cross(2, 7, 9, 8, 15, 10) - await tickTest.cross(2, 7, 9, 8, 15, 10) - const { - feeGrowthOutside0X128, - feeGrowthOutside1X128, - secondsOutside, - tickCumulativeOutside, - secondsPerLiquidityOutsideX128, - } = await tickTest.ticks(2) - expect(feeGrowthOutside0X128).to.eq(1) - expect(feeGrowthOutside1X128).to.eq(2) - expect(secondsPerLiquidityOutsideX128).to.eq(5) - expect(tickCumulativeOutside).to.eq(6) - expect(secondsOutside).to.eq(7) - }) - }) -}) diff --git a/lib/v3-core/test/TickBitmap.spec.ts b/lib/v3-core/test/TickBitmap.spec.ts deleted file mode 100644 index 6c50779..0000000 --- a/lib/v3-core/test/TickBitmap.spec.ts +++ /dev/null @@ -1,227 +0,0 @@ -import { ethers } from 'hardhat' -import { TickBitmapTest } from '../typechain/TickBitmapTest' -import { expect } from './shared/expect' -import snapshotGasCost from './shared/snapshotGasCost' - -describe('TickBitmap', () => { - let tickBitmap: TickBitmapTest - - beforeEach('deploy TickBitmapTest', async () => { - const tickBitmapTestFactory = await ethers.getContractFactory('TickBitmapTest') - tickBitmap = (await tickBitmapTestFactory.deploy()) as TickBitmapTest - }) - - async function initTicks(ticks: number[]): Promise { - for (const tick of ticks) { - await tickBitmap.flipTick(tick) - } - } - - describe('#isInitialized', () => { - it('is false at first', async () => { - expect(await tickBitmap.isInitialized(1)).to.eq(false) - }) - it('is flipped by #flipTick', async () => { - await tickBitmap.flipTick(1) - expect(await tickBitmap.isInitialized(1)).to.eq(true) - }) - it('is flipped back by #flipTick', async () => { - await tickBitmap.flipTick(1) - await tickBitmap.flipTick(1) - expect(await tickBitmap.isInitialized(1)).to.eq(false) - }) - it('is not changed by another flip to a different tick', async () => { - await tickBitmap.flipTick(2) - expect(await tickBitmap.isInitialized(1)).to.eq(false) - }) - it('is not changed by another flip to a different tick on another word', async () => { - await tickBitmap.flipTick(1 + 256) - expect(await tickBitmap.isInitialized(257)).to.eq(true) - expect(await tickBitmap.isInitialized(1)).to.eq(false) - }) - }) - - describe('#flipTick', () => { - it('flips only the specified tick', async () => { - await tickBitmap.flipTick(-230) - expect(await tickBitmap.isInitialized(-230)).to.eq(true) - expect(await tickBitmap.isInitialized(-231)).to.eq(false) - expect(await tickBitmap.isInitialized(-229)).to.eq(false) - expect(await tickBitmap.isInitialized(-230 + 256)).to.eq(false) - expect(await tickBitmap.isInitialized(-230 - 256)).to.eq(false) - await tickBitmap.flipTick(-230) - expect(await tickBitmap.isInitialized(-230)).to.eq(false) - expect(await tickBitmap.isInitialized(-231)).to.eq(false) - expect(await tickBitmap.isInitialized(-229)).to.eq(false) - expect(await tickBitmap.isInitialized(-230 + 256)).to.eq(false) - expect(await tickBitmap.isInitialized(-230 - 256)).to.eq(false) - }) - - it('reverts only itself', async () => { - await tickBitmap.flipTick(-230) - await tickBitmap.flipTick(-259) - await tickBitmap.flipTick(-229) - await tickBitmap.flipTick(500) - await tickBitmap.flipTick(-259) - await tickBitmap.flipTick(-229) - await tickBitmap.flipTick(-259) - - expect(await tickBitmap.isInitialized(-259)).to.eq(true) - expect(await tickBitmap.isInitialized(-229)).to.eq(false) - }) - - it('gas cost of flipping first tick in word to initialized', async () => { - await snapshotGasCost(await tickBitmap.getGasCostOfFlipTick(1)) - }) - it('gas cost of flipping second tick in word to initialized', async () => { - await tickBitmap.flipTick(0) - await snapshotGasCost(await tickBitmap.getGasCostOfFlipTick(1)) - }) - it('gas cost of flipping a tick that results in deleting a word', async () => { - await tickBitmap.flipTick(0) - await snapshotGasCost(await tickBitmap.getGasCostOfFlipTick(0)) - }) - }) - - describe('#nextInitializedTickWithinOneWord', () => { - beforeEach('set up some ticks', async () => { - // word boundaries are at multiples of 256 - await initTicks([-200, -55, -4, 70, 78, 84, 139, 240, 535]) - }) - - describe('lte = false', async () => { - it('returns tick to right if at initialized tick', async () => { - const { next, initialized } = await tickBitmap.nextInitializedTickWithinOneWord(78, false) - expect(next).to.eq(84) - expect(initialized).to.eq(true) - }) - it('returns tick to right if at initialized tick', async () => { - const { next, initialized } = await tickBitmap.nextInitializedTickWithinOneWord(-55, false) - expect(next).to.eq(-4) - expect(initialized).to.eq(true) - }) - - it('returns the tick directly to the right', async () => { - const { next, initialized } = await tickBitmap.nextInitializedTickWithinOneWord(77, false) - expect(next).to.eq(78) - expect(initialized).to.eq(true) - }) - it('returns the tick directly to the right', async () => { - const { next, initialized } = await tickBitmap.nextInitializedTickWithinOneWord(-56, false) - expect(next).to.eq(-55) - expect(initialized).to.eq(true) - }) - - it('returns the next words initialized tick if on the right boundary', async () => { - const { next, initialized } = await tickBitmap.nextInitializedTickWithinOneWord(255, false) - expect(next).to.eq(511) - expect(initialized).to.eq(false) - }) - it('returns the next words initialized tick if on the right boundary', async () => { - const { next, initialized } = await tickBitmap.nextInitializedTickWithinOneWord(-257, false) - expect(next).to.eq(-200) - expect(initialized).to.eq(true) - }) - - it('returns the next initialized tick from the next word', async () => { - await tickBitmap.flipTick(340) - const { next, initialized } = await tickBitmap.nextInitializedTickWithinOneWord(328, false) - expect(next).to.eq(340) - expect(initialized).to.eq(true) - }) - it('does not exceed boundary', async () => { - const { next, initialized } = await tickBitmap.nextInitializedTickWithinOneWord(508, false) - expect(next).to.eq(511) - expect(initialized).to.eq(false) - }) - it('skips entire word', async () => { - const { next, initialized } = await tickBitmap.nextInitializedTickWithinOneWord(255, false) - expect(next).to.eq(511) - expect(initialized).to.eq(false) - }) - it('skips half word', async () => { - const { next, initialized } = await tickBitmap.nextInitializedTickWithinOneWord(383, false) - expect(next).to.eq(511) - expect(initialized).to.eq(false) - }) - - it('gas cost on boundary', async () => { - await snapshotGasCost(await tickBitmap.getGasCostOfNextInitializedTickWithinOneWord(255, false)) - }) - it('gas cost just below boundary', async () => { - await snapshotGasCost(await tickBitmap.getGasCostOfNextInitializedTickWithinOneWord(254, false)) - }) - it('gas cost for entire word', async () => { - await snapshotGasCost(await tickBitmap.getGasCostOfNextInitializedTickWithinOneWord(768, false)) - }) - }) - - describe('lte = true', () => { - it('returns same tick if initialized', async () => { - const { next, initialized } = await tickBitmap.nextInitializedTickWithinOneWord(78, true) - - expect(next).to.eq(78) - expect(initialized).to.eq(true) - }) - it('returns tick directly to the left of input tick if not initialized', async () => { - const { next, initialized } = await tickBitmap.nextInitializedTickWithinOneWord(79, true) - - expect(next).to.eq(78) - expect(initialized).to.eq(true) - }) - it('will not exceed the word boundary', async () => { - const { next, initialized } = await tickBitmap.nextInitializedTickWithinOneWord(258, true) - - expect(next).to.eq(256) - expect(initialized).to.eq(false) - }) - it('at the word boundary', async () => { - const { next, initialized } = await tickBitmap.nextInitializedTickWithinOneWord(256, true) - - expect(next).to.eq(256) - expect(initialized).to.eq(false) - }) - it('word boundary less 1 (next initialized tick in next word)', async () => { - const { next, initialized } = await tickBitmap.nextInitializedTickWithinOneWord(72, true) - - expect(next).to.eq(70) - expect(initialized).to.eq(true) - }) - it('word boundary', async () => { - const { next, initialized } = await tickBitmap.nextInitializedTickWithinOneWord(-257, true) - - expect(next).to.eq(-512) - expect(initialized).to.eq(false) - }) - it('entire empty word', async () => { - const { next, initialized } = await tickBitmap.nextInitializedTickWithinOneWord(1023, true) - - expect(next).to.eq(768) - expect(initialized).to.eq(false) - }) - it('halfway through empty word', async () => { - const { next, initialized } = await tickBitmap.nextInitializedTickWithinOneWord(900, true) - - expect(next).to.eq(768) - expect(initialized).to.eq(false) - }) - it('boundary is initialized', async () => { - await tickBitmap.flipTick(329) - const { next, initialized } = await tickBitmap.nextInitializedTickWithinOneWord(456, true) - - expect(next).to.eq(329) - expect(initialized).to.eq(true) - }) - - it('gas cost on boundary', async () => { - await snapshotGasCost(await tickBitmap.getGasCostOfNextInitializedTickWithinOneWord(256, true)) - }) - it('gas cost just below boundary', async () => { - await snapshotGasCost(await tickBitmap.getGasCostOfNextInitializedTickWithinOneWord(255, true)) - }) - it('gas cost for entire word', async () => { - await snapshotGasCost(await tickBitmap.getGasCostOfNextInitializedTickWithinOneWord(1024, true)) - }) - }) - }) -}) diff --git a/lib/v3-core/test/TickMath.spec.ts b/lib/v3-core/test/TickMath.spec.ts deleted file mode 100644 index 8e03a60..0000000 --- a/lib/v3-core/test/TickMath.spec.ts +++ /dev/null @@ -1,166 +0,0 @@ -import { BigNumber } from 'ethers' -import { ethers } from 'hardhat' -import { TickMathTest } from '../typechain/TickMathTest' -import { expect } from './shared/expect' -import snapshotGasCost from './shared/snapshotGasCost' -import { encodePriceSqrt, MIN_SQRT_RATIO, MAX_SQRT_RATIO } from './shared/utilities' -import Decimal from 'decimal.js' - -const MIN_TICK = -887272 -const MAX_TICK = 887272 - -Decimal.config({ toExpNeg: -500, toExpPos: 500 }) - -describe('TickMath', () => { - let tickMath: TickMathTest - - before('deploy TickMathTest', async () => { - const factory = await ethers.getContractFactory('TickMathTest') - tickMath = (await factory.deploy()) as TickMathTest - }) - - describe('#getSqrtRatioAtTick', () => { - it('throws for too low', async () => { - await expect(tickMath.getSqrtRatioAtTick(MIN_TICK - 1)).to.be.revertedWith('T') - }) - - it('throws for too low', async () => { - await expect(tickMath.getSqrtRatioAtTick(MAX_TICK + 1)).to.be.revertedWith('T') - }) - - it('min tick', async () => { - expect(await tickMath.getSqrtRatioAtTick(MIN_TICK)).to.eq('4295128739') - }) - - it('min tick +1', async () => { - expect(await tickMath.getSqrtRatioAtTick(MIN_TICK + 1)).to.eq('4295343490') - }) - - it('max tick - 1', async () => { - expect(await tickMath.getSqrtRatioAtTick(MAX_TICK - 1)).to.eq('1461373636630004318706518188784493106690254656249') - }) - - it('min tick ratio is less than js implementation', async () => { - expect(await tickMath.getSqrtRatioAtTick(MIN_TICK)).to.be.lt(encodePriceSqrt(1, BigNumber.from(2).pow(127))) - }) - - it('max tick ratio is greater than js implementation', async () => { - expect(await tickMath.getSqrtRatioAtTick(MAX_TICK)).to.be.gt(encodePriceSqrt(BigNumber.from(2).pow(127), 1)) - }) - - it('max tick', async () => { - expect(await tickMath.getSqrtRatioAtTick(MAX_TICK)).to.eq('1461446703485210103287273052203988822378723970342') - }) - - for (const absTick of [ - 50, - 100, - 250, - 500, - 1_000, - 2_500, - 3_000, - 4_000, - 5_000, - 50_000, - 150_000, - 250_000, - 500_000, - 738_203, - ]) { - for (const tick of [-absTick, absTick]) { - describe(`tick ${tick}`, () => { - it('is at most off by 1/100th of a bips', async () => { - const jsResult = new Decimal(1.0001).pow(tick).sqrt().mul(new Decimal(2).pow(96)) - const result = await tickMath.getSqrtRatioAtTick(tick) - const absDiff = new Decimal(result.toString()).sub(jsResult).abs() - expect(absDiff.div(jsResult).toNumber()).to.be.lt(0.000001) - }) - it('result', async () => { - expect((await tickMath.getSqrtRatioAtTick(tick)).toString()).to.matchSnapshot() - }) - it('gas', async () => { - await snapshotGasCost(tickMath.getGasCostOfGetSqrtRatioAtTick(tick)) - }) - }) - } - } - }) - - describe('#MIN_SQRT_RATIO', async () => { - it('equals #getSqrtRatioAtTick(MIN_TICK)', async () => { - const min = await tickMath.getSqrtRatioAtTick(MIN_TICK) - expect(min).to.eq(await tickMath.MIN_SQRT_RATIO()) - expect(min).to.eq(MIN_SQRT_RATIO) - }) - }) - - describe('#MAX_SQRT_RATIO', async () => { - it('equals #getSqrtRatioAtTick(MAX_TICK)', async () => { - const max = await tickMath.getSqrtRatioAtTick(MAX_TICK) - expect(max).to.eq(await tickMath.MAX_SQRT_RATIO()) - expect(max).to.eq(MAX_SQRT_RATIO) - }) - }) - - describe('#getTickAtSqrtRatio', () => { - it('throws for too low', async () => { - await expect(tickMath.getTickAtSqrtRatio(MIN_SQRT_RATIO.sub(1))).to.be.revertedWith('R') - }) - - it('throws for too high', async () => { - await expect(tickMath.getTickAtSqrtRatio(BigNumber.from(MAX_SQRT_RATIO))).to.be.revertedWith('R') - }) - - it('ratio of min tick', async () => { - expect(await tickMath.getTickAtSqrtRatio(MIN_SQRT_RATIO)).to.eq(MIN_TICK) - }) - it('ratio of min tick + 1', async () => { - expect(await tickMath.getTickAtSqrtRatio('4295343490')).to.eq(MIN_TICK + 1) - }) - it('ratio of max tick - 1', async () => { - expect(await tickMath.getTickAtSqrtRatio('1461373636630004318706518188784493106690254656249')).to.eq(MAX_TICK - 1) - }) - it('ratio closest to max tick', async () => { - expect(await tickMath.getTickAtSqrtRatio(MAX_SQRT_RATIO.sub(1))).to.eq(MAX_TICK - 1) - }) - - for (const ratio of [ - MIN_SQRT_RATIO, - encodePriceSqrt(BigNumber.from(10).pow(12), 1), - encodePriceSqrt(BigNumber.from(10).pow(6), 1), - encodePriceSqrt(1, 64), - encodePriceSqrt(1, 8), - encodePriceSqrt(1, 2), - encodePriceSqrt(1, 1), - encodePriceSqrt(2, 1), - encodePriceSqrt(8, 1), - encodePriceSqrt(64, 1), - encodePriceSqrt(1, BigNumber.from(10).pow(6)), - encodePriceSqrt(1, BigNumber.from(10).pow(12)), - MAX_SQRT_RATIO.sub(1), - ]) { - describe(`ratio ${ratio}`, () => { - it('is at most off by 1', async () => { - const jsResult = new Decimal(ratio.toString()).div(new Decimal(2).pow(96)).pow(2).log(1.0001).floor() - const result = await tickMath.getTickAtSqrtRatio(ratio) - const absDiff = new Decimal(result.toString()).sub(jsResult).abs() - expect(absDiff.toNumber()).to.be.lte(1) - }) - it('ratio is between the tick and tick+1', async () => { - const tick = await tickMath.getTickAtSqrtRatio(ratio) - const ratioOfTick = await tickMath.getSqrtRatioAtTick(tick) - const ratioOfTickPlusOne = await tickMath.getSqrtRatioAtTick(tick + 1) - expect(ratio).to.be.gte(ratioOfTick) - expect(ratio).to.be.lt(ratioOfTickPlusOne) - }) - it('result', async () => { - expect(await tickMath.getTickAtSqrtRatio(ratio)).to.matchSnapshot() - }) - it('gas', async () => { - await snapshotGasCost(tickMath.getGasCostOfGetTickAtSqrtRatio(ratio)) - }) - }) - } - }) -}) diff --git a/lib/v3-core/test/UniswapV3Factory.spec.ts b/lib/v3-core/test/UniswapV3Factory.spec.ts deleted file mode 100644 index afdc922..0000000 --- a/lib/v3-core/test/UniswapV3Factory.spec.ts +++ /dev/null @@ -1,177 +0,0 @@ -import { Wallet } from 'ethers' -import { ethers, waffle } from 'hardhat' -import { UniswapV3Factory } from '../typechain/UniswapV3Factory' -import { expect } from './shared/expect' -import snapshotGasCost from './shared/snapshotGasCost' - -import { FeeAmount, getCreate2Address, TICK_SPACINGS } from './shared/utilities' - -const { constants } = ethers - -const TEST_ADDRESSES: [string, string] = [ - '0x1000000000000000000000000000000000000000', - '0x2000000000000000000000000000000000000000', -] - -const createFixtureLoader = waffle.createFixtureLoader - -describe('UniswapV3Factory', () => { - let wallet: Wallet, other: Wallet - - let factory: UniswapV3Factory - let poolBytecode: string - const fixture = async () => { - const factoryFactory = await ethers.getContractFactory('UniswapV3Factory') - return (await factoryFactory.deploy()) as UniswapV3Factory - } - - let loadFixture: ReturnType - before('create fixture loader', async () => { - ;[wallet, other] = await (ethers as any).getSigners() - - loadFixture = createFixtureLoader([wallet, other]) - }) - - before('load pool bytecode', async () => { - poolBytecode = (await ethers.getContractFactory('UniswapV3Pool')).bytecode - }) - - beforeEach('deploy factory', async () => { - factory = await loadFixture(fixture) - }) - - it('owner is deployer', async () => { - expect(await factory.owner()).to.eq(wallet.address) - }) - - it('factory bytecode size', async () => { - expect(((await waffle.provider.getCode(factory.address)).length - 2) / 2).to.matchSnapshot() - }) - - it('pool bytecode size', async () => { - await factory.createPool(TEST_ADDRESSES[0], TEST_ADDRESSES[1], FeeAmount.MEDIUM) - const poolAddress = getCreate2Address(factory.address, TEST_ADDRESSES, FeeAmount.MEDIUM, poolBytecode) - expect(((await waffle.provider.getCode(poolAddress)).length - 2) / 2).to.matchSnapshot() - }) - - it('initial enabled fee amounts', async () => { - expect(await factory.feeAmountTickSpacing(FeeAmount.LOW)).to.eq(TICK_SPACINGS[FeeAmount.LOW]) - expect(await factory.feeAmountTickSpacing(FeeAmount.MEDIUM)).to.eq(TICK_SPACINGS[FeeAmount.MEDIUM]) - expect(await factory.feeAmountTickSpacing(FeeAmount.HIGH)).to.eq(TICK_SPACINGS[FeeAmount.HIGH]) - }) - - async function createAndCheckPool( - tokens: [string, string], - feeAmount: FeeAmount, - tickSpacing: number = TICK_SPACINGS[feeAmount] - ) { - const create2Address = getCreate2Address(factory.address, tokens, feeAmount, poolBytecode) - const create = factory.createPool(tokens[0], tokens[1], feeAmount) - - await expect(create) - .to.emit(factory, 'PoolCreated') - .withArgs(TEST_ADDRESSES[0], TEST_ADDRESSES[1], feeAmount, tickSpacing, create2Address) - - await expect(factory.createPool(tokens[0], tokens[1], feeAmount)).to.be.reverted - await expect(factory.createPool(tokens[1], tokens[0], feeAmount)).to.be.reverted - expect(await factory.getPool(tokens[0], tokens[1], feeAmount), 'getPool in order').to.eq(create2Address) - expect(await factory.getPool(tokens[1], tokens[0], feeAmount), 'getPool in reverse').to.eq(create2Address) - - const poolContractFactory = await ethers.getContractFactory('UniswapV3Pool') - const pool = poolContractFactory.attach(create2Address) - expect(await pool.factory(), 'pool factory address').to.eq(factory.address) - expect(await pool.token0(), 'pool token0').to.eq(TEST_ADDRESSES[0]) - expect(await pool.token1(), 'pool token1').to.eq(TEST_ADDRESSES[1]) - expect(await pool.fee(), 'pool fee').to.eq(feeAmount) - expect(await pool.tickSpacing(), 'pool tick spacing').to.eq(tickSpacing) - } - - describe('#createPool', () => { - it('succeeds for low fee pool', async () => { - await createAndCheckPool(TEST_ADDRESSES, FeeAmount.LOW) - }) - - it('succeeds for medium fee pool', async () => { - await createAndCheckPool(TEST_ADDRESSES, FeeAmount.MEDIUM) - }) - it('succeeds for high fee pool', async () => { - await createAndCheckPool(TEST_ADDRESSES, FeeAmount.HIGH) - }) - - it('succeeds if tokens are passed in reverse', async () => { - await createAndCheckPool([TEST_ADDRESSES[1], TEST_ADDRESSES[0]], FeeAmount.MEDIUM) - }) - - it('fails if token a == token b', async () => { - await expect(factory.createPool(TEST_ADDRESSES[0], TEST_ADDRESSES[0], FeeAmount.LOW)).to.be.reverted - }) - - it('fails if token a is 0 or token b is 0', async () => { - await expect(factory.createPool(TEST_ADDRESSES[0], constants.AddressZero, FeeAmount.LOW)).to.be.reverted - await expect(factory.createPool(constants.AddressZero, TEST_ADDRESSES[0], FeeAmount.LOW)).to.be.reverted - await expect(factory.createPool(constants.AddressZero, constants.AddressZero, FeeAmount.LOW)).to.be.revertedWith( - '' - ) - }) - - it('fails if fee amount is not enabled', async () => { - await expect(factory.createPool(TEST_ADDRESSES[0], TEST_ADDRESSES[1], 250)).to.be.reverted - }) - - it('gas', async () => { - await snapshotGasCost(factory.createPool(TEST_ADDRESSES[0], TEST_ADDRESSES[1], FeeAmount.MEDIUM)) - }) - }) - - describe('#setOwner', () => { - it('fails if caller is not owner', async () => { - await expect(factory.connect(other).setOwner(wallet.address)).to.be.reverted - }) - - it('updates owner', async () => { - await factory.setOwner(other.address) - expect(await factory.owner()).to.eq(other.address) - }) - - it('emits event', async () => { - await expect(factory.setOwner(other.address)) - .to.emit(factory, 'OwnerChanged') - .withArgs(wallet.address, other.address) - }) - - it('cannot be called by original owner', async () => { - await factory.setOwner(other.address) - await expect(factory.setOwner(wallet.address)).to.be.reverted - }) - }) - - describe('#enableFeeAmount', () => { - it('fails if caller is not owner', async () => { - await expect(factory.connect(other).enableFeeAmount(100, 2)).to.be.reverted - }) - it('fails if fee is too great', async () => { - await expect(factory.enableFeeAmount(1000000, 10)).to.be.reverted - }) - it('fails if tick spacing is too small', async () => { - await expect(factory.enableFeeAmount(500, 0)).to.be.reverted - }) - it('fails if tick spacing is too large', async () => { - await expect(factory.enableFeeAmount(500, 16834)).to.be.reverted - }) - it('fails if already initialized', async () => { - await factory.enableFeeAmount(100, 5) - await expect(factory.enableFeeAmount(100, 10)).to.be.reverted - }) - it('sets the fee amount in the mapping', async () => { - await factory.enableFeeAmount(100, 5) - expect(await factory.feeAmountTickSpacing(100)).to.eq(5) - }) - it('emits an event', async () => { - await expect(factory.enableFeeAmount(100, 5)).to.emit(factory, 'FeeAmountEnabled').withArgs(100, 5) - }) - it('enables pool creation', async () => { - await factory.enableFeeAmount(250, 15) - await createAndCheckPool([TEST_ADDRESSES[0], TEST_ADDRESSES[1]], 250, 15) - }) - }) -}) diff --git a/lib/v3-core/test/UniswapV3Pool.arbitrage.spec.ts b/lib/v3-core/test/UniswapV3Pool.arbitrage.spec.ts deleted file mode 100644 index 3c3de00..0000000 --- a/lib/v3-core/test/UniswapV3Pool.arbitrage.spec.ts +++ /dev/null @@ -1,373 +0,0 @@ -import Decimal from 'decimal.js' -import { BigNumber, BigNumberish, Wallet } from 'ethers' -import { ethers, waffle } from 'hardhat' -import { MockTimeUniswapV3Pool } from '../typechain/MockTimeUniswapV3Pool' -import { TickMathTest } from '../typechain/TickMathTest' -import { UniswapV3PoolSwapTest } from '../typechain/UniswapV3PoolSwapTest' -import { expect } from './shared/expect' - -import { poolFixture } from './shared/fixtures' -import { formatPrice, formatTokenAmount } from './shared/format' - -import { - createPoolFunctions, - encodePriceSqrt, - expandTo18Decimals, - FeeAmount, - getMaxLiquidityPerTick, - getMaxTick, - getMinTick, - MAX_SQRT_RATIO, - MaxUint128, - MIN_SQRT_RATIO, - MintFunction, - SwapFunction, - TICK_SPACINGS, -} from './shared/utilities' - -const { - constants: { MaxUint256 }, -} = ethers - -const createFixtureLoader = waffle.createFixtureLoader - -Decimal.config({ toExpNeg: -500, toExpPos: 500 }) - -function applySqrtRatioBipsHundredthsDelta(sqrtRatio: BigNumber, bipsHundredths: number): BigNumber { - return BigNumber.from( - new Decimal( - sqrtRatio - .mul(sqrtRatio) - .mul(1e6 + bipsHundredths) - .div(1e6) - .toString() - ) - .sqrt() - .floor() - .toString() - ) -} - -describe('UniswapV3Pool arbitrage tests', () => { - let wallet: Wallet, arbitrageur: Wallet - - let loadFixture: ReturnType - - before('create fixture loader', async () => { - ;[wallet, arbitrageur] = await (ethers as any).getSigners() - loadFixture = createFixtureLoader([wallet, arbitrageur]) - }) - - for (const feeProtocol of [0, 6]) { - describe(`protocol fee = ${feeProtocol};`, () => { - const startingPrice = encodePriceSqrt(1, 1) - const startingTick = 0 - const feeAmount = FeeAmount.MEDIUM - const tickSpacing = TICK_SPACINGS[feeAmount] - const minTick = getMinTick(tickSpacing) - const maxTick = getMaxTick(tickSpacing) - - for (const passiveLiquidity of [ - expandTo18Decimals(1).div(100), - expandTo18Decimals(1), - expandTo18Decimals(10), - expandTo18Decimals(100), - ]) { - describe(`passive liquidity of ${formatTokenAmount(passiveLiquidity)}`, () => { - const arbTestFixture = async ([wallet, arbitrageur]: Wallet[]) => { - const fix = await poolFixture([wallet], waffle.provider) - - const pool = await fix.createPool(feeAmount, tickSpacing) - - await fix.token0.transfer(arbitrageur.address, BigNumber.from(2).pow(254)) - await fix.token1.transfer(arbitrageur.address, BigNumber.from(2).pow(254)) - - const { - swapExact0For1, - swapToHigherPrice, - swapToLowerPrice, - swapExact1For0, - mint, - } = await createPoolFunctions({ - swapTarget: fix.swapTargetCallee, - token0: fix.token0, - token1: fix.token1, - pool, - }) - - const testerFactory = await ethers.getContractFactory('UniswapV3PoolSwapTest') - const tester = (await testerFactory.deploy()) as UniswapV3PoolSwapTest - - const tickMathFactory = await ethers.getContractFactory('TickMathTest') - const tickMath = (await tickMathFactory.deploy()) as TickMathTest - - await fix.token0.approve(tester.address, MaxUint256) - await fix.token1.approve(tester.address, MaxUint256) - - await pool.initialize(startingPrice) - if (feeProtocol != 0) await pool.setFeeProtocol(feeProtocol, feeProtocol) - await mint(wallet.address, minTick, maxTick, passiveLiquidity) - - expect((await pool.slot0()).tick).to.eq(startingTick) - expect((await pool.slot0()).sqrtPriceX96).to.eq(startingPrice) - - return { pool, swapExact0For1, mint, swapToHigherPrice, swapToLowerPrice, swapExact1For0, tester, tickMath } - } - - let swapExact0For1: SwapFunction - let swapToHigherPrice: SwapFunction - let swapToLowerPrice: SwapFunction - let swapExact1For0: SwapFunction - let pool: MockTimeUniswapV3Pool - let mint: MintFunction - let tester: UniswapV3PoolSwapTest - let tickMath: TickMathTest - - beforeEach('load the fixture', async () => { - ;({ - swapExact0For1, - pool, - mint, - swapToHigherPrice, - swapToLowerPrice, - swapExact1For0, - tester, - tickMath, - } = await loadFixture(arbTestFixture)) - }) - - async function simulateSwap( - zeroForOne: boolean, - amountSpecified: BigNumberish, - sqrtPriceLimitX96?: BigNumber - ): Promise<{ - executionPrice: BigNumber - nextSqrtRatio: BigNumber - amount0Delta: BigNumber - amount1Delta: BigNumber - }> { - const { amount0Delta, amount1Delta, nextSqrtRatio } = await tester.callStatic.getSwapResult( - pool.address, - zeroForOne, - amountSpecified, - sqrtPriceLimitX96 ?? (zeroForOne ? MIN_SQRT_RATIO.add(1) : MAX_SQRT_RATIO.sub(1)) - ) - - const executionPrice = zeroForOne - ? encodePriceSqrt(amount1Delta, amount0Delta.mul(-1)) - : encodePriceSqrt(amount1Delta.mul(-1), amount0Delta) - - return { executionPrice, nextSqrtRatio, amount0Delta, amount1Delta } - } - - for (const { zeroForOne, assumedTruePriceAfterSwap, inputAmount, description } of [ - { - description: 'exact input of 10e18 token0 with starting price of 1.0 and true price of 0.98', - zeroForOne: true, - inputAmount: expandTo18Decimals(10), - assumedTruePriceAfterSwap: encodePriceSqrt(98, 100), - }, - { - description: 'exact input of 10e18 token0 with starting price of 1.0 and true price of 1.01', - zeroForOne: true, - inputAmount: expandTo18Decimals(10), - assumedTruePriceAfterSwap: encodePriceSqrt(101, 100), - }, - ]) { - describe(description, () => { - function valueToken1(arbBalance0: BigNumber, arbBalance1: BigNumber) { - return assumedTruePriceAfterSwap - .mul(assumedTruePriceAfterSwap) - .mul(arbBalance0) - .div(BigNumber.from(2).pow(192)) - .add(arbBalance1) - } - - it('not sandwiched', async () => { - const { executionPrice, amount1Delta, amount0Delta } = await simulateSwap(zeroForOne, inputAmount) - zeroForOne - ? await swapExact0For1(inputAmount, wallet.address) - : await swapExact1For0(inputAmount, wallet.address) - - expect({ - executionPrice: formatPrice(executionPrice), - amount0Delta: formatTokenAmount(amount0Delta), - amount1Delta: formatTokenAmount(amount1Delta), - priceAfter: formatPrice((await pool.slot0()).sqrtPriceX96), - }).to.matchSnapshot() - }) - - it('sandwiched with swap to execution price then mint max liquidity/target/burn max liquidity', async () => { - const { executionPrice } = await simulateSwap(zeroForOne, inputAmount) - - const firstTickAboveMarginalPrice = zeroForOne - ? Math.ceil( - (await tickMath.getTickAtSqrtRatio( - applySqrtRatioBipsHundredthsDelta(executionPrice, feeAmount) - )) / tickSpacing - ) * tickSpacing - : Math.floor( - (await tickMath.getTickAtSqrtRatio( - applySqrtRatioBipsHundredthsDelta(executionPrice, -feeAmount) - )) / tickSpacing - ) * tickSpacing - const tickAfterFirstTickAboveMarginPrice = zeroForOne - ? firstTickAboveMarginalPrice - tickSpacing - : firstTickAboveMarginalPrice + tickSpacing - - const priceSwapStart = await tickMath.getSqrtRatioAtTick(firstTickAboveMarginalPrice) - - let arbBalance0 = BigNumber.from(0) - let arbBalance1 = BigNumber.from(0) - - // first frontrun to the first tick before the execution price - const { - amount0Delta: frontrunDelta0, - amount1Delta: frontrunDelta1, - executionPrice: frontrunExecutionPrice, - } = await simulateSwap(zeroForOne, MaxUint256.div(2), priceSwapStart) - arbBalance0 = arbBalance0.sub(frontrunDelta0) - arbBalance1 = arbBalance1.sub(frontrunDelta1) - zeroForOne - ? await swapToLowerPrice(priceSwapStart, arbitrageur.address) - : await swapToHigherPrice(priceSwapStart, arbitrageur.address) - - const profitToken1AfterFrontRun = valueToken1(arbBalance0, arbBalance1) - - const tickLower = zeroForOne ? tickAfterFirstTickAboveMarginPrice : firstTickAboveMarginalPrice - const tickUpper = zeroForOne ? firstTickAboveMarginalPrice : tickAfterFirstTickAboveMarginPrice - - // deposit max liquidity at the tick - const mintReceipt = await ( - await mint(wallet.address, tickLower, tickUpper, getMaxLiquidityPerTick(tickSpacing)) - ).wait() - // sub the mint costs - const { amount0: amount0Mint, amount1: amount1Mint } = pool.interface.decodeEventLog( - pool.interface.events['Mint(address,address,int24,int24,uint128,uint256,uint256)'], - mintReceipt.events?.[2].data! - ) - arbBalance0 = arbBalance0.sub(amount0Mint) - arbBalance1 = arbBalance1.sub(amount1Mint) - - // execute the user's swap - const { executionPrice: executionPriceAfterFrontrun } = await simulateSwap(zeroForOne, inputAmount) - zeroForOne - ? await swapExact0For1(inputAmount, wallet.address) - : await swapExact1For0(inputAmount, wallet.address) - - // burn the arb's liquidity - const { amount0: amount0Burn, amount1: amount1Burn } = await pool.callStatic.burn( - tickLower, - tickUpper, - getMaxLiquidityPerTick(tickSpacing) - ) - await pool.burn(tickLower, tickUpper, getMaxLiquidityPerTick(tickSpacing)) - arbBalance0 = arbBalance0.add(amount0Burn) - arbBalance1 = arbBalance1.add(amount1Burn) - - // add the fees as well - const { - amount0: amount0CollectAndBurn, - amount1: amount1CollectAndBurn, - } = await pool.callStatic.collect(arbitrageur.address, tickLower, tickUpper, MaxUint128, MaxUint128) - const [amount0Collect, amount1Collect] = [ - amount0CollectAndBurn.sub(amount0Burn), - amount1CollectAndBurn.sub(amount1Burn), - ] - arbBalance0 = arbBalance0.add(amount0Collect) - arbBalance1 = arbBalance1.add(amount1Collect) - - const profitToken1AfterSandwich = valueToken1(arbBalance0, arbBalance1) - - // backrun the swap to true price, i.e. swap to the marginal price = true price - const priceToSwapTo = zeroForOne - ? applySqrtRatioBipsHundredthsDelta(assumedTruePriceAfterSwap, -feeAmount) - : applySqrtRatioBipsHundredthsDelta(assumedTruePriceAfterSwap, feeAmount) - const { - amount0Delta: backrunDelta0, - amount1Delta: backrunDelta1, - executionPrice: backrunExecutionPrice, - } = await simulateSwap(!zeroForOne, MaxUint256.div(2), priceToSwapTo) - await swapToHigherPrice(priceToSwapTo, wallet.address) - arbBalance0 = arbBalance0.sub(backrunDelta0) - arbBalance1 = arbBalance1.sub(backrunDelta1) - - expect({ - sandwichedPrice: formatPrice(executionPriceAfterFrontrun), - arbBalanceDelta0: formatTokenAmount(arbBalance0), - arbBalanceDelta1: formatTokenAmount(arbBalance1), - profit: { - final: formatTokenAmount(valueToken1(arbBalance0, arbBalance1)), - afterFrontrun: formatTokenAmount(profitToken1AfterFrontRun), - afterSandwich: formatTokenAmount(profitToken1AfterSandwich), - }, - backrun: { - executionPrice: formatPrice(backrunExecutionPrice), - delta0: formatTokenAmount(backrunDelta0), - delta1: formatTokenAmount(backrunDelta1), - }, - frontrun: { - executionPrice: formatPrice(frontrunExecutionPrice), - delta0: formatTokenAmount(frontrunDelta0), - delta1: formatTokenAmount(frontrunDelta1), - }, - collect: { - amount0: formatTokenAmount(amount0Collect), - amount1: formatTokenAmount(amount1Collect), - }, - burn: { - amount0: formatTokenAmount(amount0Burn), - amount1: formatTokenAmount(amount1Burn), - }, - mint: { - amount0: formatTokenAmount(amount0Mint), - amount1: formatTokenAmount(amount1Mint), - }, - finalPrice: formatPrice((await pool.slot0()).sqrtPriceX96), - }).to.matchSnapshot() - }) - - it('backrun to true price after swap only', async () => { - let arbBalance0 = BigNumber.from(0) - let arbBalance1 = BigNumber.from(0) - - zeroForOne - ? await swapExact0For1(inputAmount, wallet.address) - : await swapExact1For0(inputAmount, wallet.address) - - // swap to the marginal price = true price - const priceToSwapTo = zeroForOne - ? applySqrtRatioBipsHundredthsDelta(assumedTruePriceAfterSwap, -feeAmount) - : applySqrtRatioBipsHundredthsDelta(assumedTruePriceAfterSwap, feeAmount) - const { - amount0Delta: backrunDelta0, - amount1Delta: backrunDelta1, - executionPrice: backrunExecutionPrice, - } = await simulateSwap(!zeroForOne, MaxUint256.div(2), priceToSwapTo) - zeroForOne - ? await swapToHigherPrice(priceToSwapTo, wallet.address) - : await swapToLowerPrice(priceToSwapTo, wallet.address) - arbBalance0 = arbBalance0.sub(backrunDelta0) - arbBalance1 = arbBalance1.sub(backrunDelta1) - - expect({ - arbBalanceDelta0: formatTokenAmount(arbBalance0), - arbBalanceDelta1: formatTokenAmount(arbBalance1), - profit: { - final: formatTokenAmount(valueToken1(arbBalance0, arbBalance1)), - }, - backrun: { - executionPrice: formatPrice(backrunExecutionPrice), - delta0: formatTokenAmount(backrunDelta0), - delta1: formatTokenAmount(backrunDelta1), - }, - finalPrice: formatPrice((await pool.slot0()).sqrtPriceX96), - }).to.matchSnapshot() - }) - }) - } - }) - } - }) - } -}) diff --git a/lib/v3-core/test/UniswapV3Pool.gas.spec.ts b/lib/v3-core/test/UniswapV3Pool.gas.spec.ts deleted file mode 100644 index 877c181..0000000 --- a/lib/v3-core/test/UniswapV3Pool.gas.spec.ts +++ /dev/null @@ -1,315 +0,0 @@ -import { ethers, waffle } from 'hardhat' -import { Wallet } from 'ethers' -import { MockTimeUniswapV3Pool } from '../typechain/MockTimeUniswapV3Pool' -import { expect } from './shared/expect' - -import { poolFixture } from './shared/fixtures' -import snapshotGasCost from './shared/snapshotGasCost' - -import { - expandTo18Decimals, - FeeAmount, - getMinTick, - encodePriceSqrt, - TICK_SPACINGS, - createPoolFunctions, - SwapFunction, - MintFunction, - getMaxTick, - MaxUint128, - SwapToPriceFunction, - MAX_SQRT_RATIO, - MIN_SQRT_RATIO, -} from './shared/utilities' - -const createFixtureLoader = waffle.createFixtureLoader - -describe('UniswapV3Pool gas tests', () => { - let wallet: Wallet, other: Wallet - - let loadFixture: ReturnType - - before('create fixture loader', async () => { - ;[wallet, other] = await (ethers as any).getSigners() - loadFixture = createFixtureLoader([wallet, other]) - }) - - for (const feeProtocol of [0, 6]) { - describe(feeProtocol > 0 ? 'fee is on' : 'fee is off', () => { - const startingPrice = encodePriceSqrt(100001, 100000) - const startingTick = 0 - const feeAmount = FeeAmount.MEDIUM - const tickSpacing = TICK_SPACINGS[feeAmount] - const minTick = getMinTick(tickSpacing) - const maxTick = getMaxTick(tickSpacing) - - const gasTestFixture = async ([wallet]: Wallet[]) => { - const fix = await poolFixture([wallet], waffle.provider) - - const pool = await fix.createPool(feeAmount, tickSpacing) - - const { swapExact0For1, swapToHigherPrice, mint, swapToLowerPrice } = await createPoolFunctions({ - swapTarget: fix.swapTargetCallee, - token0: fix.token0, - token1: fix.token1, - pool, - }) - - await pool.initialize(encodePriceSqrt(1, 1)) - await pool.setFeeProtocol(feeProtocol, feeProtocol) - await pool.increaseObservationCardinalityNext(4) - await pool.advanceTime(1) - await mint(wallet.address, minTick, maxTick, expandTo18Decimals(2)) - - await swapExact0For1(expandTo18Decimals(1), wallet.address) - await pool.advanceTime(1) - await swapToHigherPrice(startingPrice, wallet.address) - await pool.advanceTime(1) - expect((await pool.slot0()).tick).to.eq(startingTick) - expect((await pool.slot0()).sqrtPriceX96).to.eq(startingPrice) - - return { pool, swapExact0For1, mint, swapToHigherPrice, swapToLowerPrice } - } - - let swapExact0For1: SwapFunction - let swapToHigherPrice: SwapToPriceFunction - let swapToLowerPrice: SwapToPriceFunction - let pool: MockTimeUniswapV3Pool - let mint: MintFunction - - beforeEach('load the fixture', async () => { - ;({ swapExact0For1, pool, mint, swapToHigherPrice, swapToLowerPrice } = await loadFixture(gasTestFixture)) - }) - - describe('#swapExact0For1', () => { - it('first swap in block with no tick movement', async () => { - await snapshotGasCost(swapExact0For1(2000, wallet.address)) - expect((await pool.slot0()).sqrtPriceX96).to.not.eq(startingPrice) - expect((await pool.slot0()).tick).to.eq(startingTick) - }) - - it('first swap in block moves tick, no initialized crossings', async () => { - await snapshotGasCost(swapExact0For1(expandTo18Decimals(1).div(10000), wallet.address)) - expect((await pool.slot0()).tick).to.eq(startingTick - 1) - }) - - it('second swap in block with no tick movement', async () => { - await swapExact0For1(expandTo18Decimals(1).div(10000), wallet.address) - expect((await pool.slot0()).tick).to.eq(startingTick - 1) - await snapshotGasCost(swapExact0For1(2000, wallet.address)) - expect((await pool.slot0()).tick).to.eq(startingTick - 1) - }) - - it('second swap in block moves tick, no initialized crossings', async () => { - await swapExact0For1(1000, wallet.address) - expect((await pool.slot0()).tick).to.eq(startingTick) - await snapshotGasCost(swapExact0For1(expandTo18Decimals(1).div(10000), wallet.address)) - expect((await pool.slot0()).tick).to.eq(startingTick - 1) - }) - - it('first swap in block, large swap, no initialized crossings', async () => { - await snapshotGasCost(swapExact0For1(expandTo18Decimals(10), wallet.address)) - expect((await pool.slot0()).tick).to.eq(-35787) - }) - - it('first swap in block, large swap crossing several initialized ticks', async () => { - await mint(wallet.address, startingTick - 3 * tickSpacing, startingTick - tickSpacing, expandTo18Decimals(1)) - await mint( - wallet.address, - startingTick - 4 * tickSpacing, - startingTick - 2 * tickSpacing, - expandTo18Decimals(1) - ) - expect((await pool.slot0()).tick).to.eq(startingTick) - await snapshotGasCost(swapExact0For1(expandTo18Decimals(1), wallet.address)) - expect((await pool.slot0()).tick).to.be.lt(startingTick - 4 * tickSpacing) // we crossed the last tick - }) - - it('first swap in block, large swap crossing a single initialized tick', async () => { - await mint(wallet.address, minTick, startingTick - 2 * tickSpacing, expandTo18Decimals(1)) - await snapshotGasCost(swapExact0For1(expandTo18Decimals(1), wallet.address)) - expect((await pool.slot0()).tick).to.be.lt(startingTick - 2 * tickSpacing) // we crossed the last tick - }) - - it('second swap in block, large swap crossing several initialized ticks', async () => { - await mint(wallet.address, startingTick - 3 * tickSpacing, startingTick - tickSpacing, expandTo18Decimals(1)) - await mint( - wallet.address, - startingTick - 4 * tickSpacing, - startingTick - 2 * tickSpacing, - expandTo18Decimals(1) - ) - await swapExact0For1(expandTo18Decimals(1).div(10000), wallet.address) - await snapshotGasCost(swapExact0For1(expandTo18Decimals(1), wallet.address)) - expect((await pool.slot0()).tick).to.be.lt(startingTick - 4 * tickSpacing) - }) - - it('second swap in block, large swap crossing a single initialized tick', async () => { - await mint(wallet.address, minTick, startingTick - 2 * tickSpacing, expandTo18Decimals(1)) - await swapExact0For1(expandTo18Decimals(1).div(10000), wallet.address) - expect((await pool.slot0()).tick).to.be.gt(startingTick - 2 * tickSpacing) // we didn't cross the initialized tick - await snapshotGasCost(swapExact0For1(expandTo18Decimals(1), wallet.address)) - expect((await pool.slot0()).tick).to.be.lt(startingTick - 2 * tickSpacing) // we crossed the last tick - }) - - it('large swap crossing several initialized ticks after some time passes', async () => { - await mint(wallet.address, startingTick - 3 * tickSpacing, startingTick - tickSpacing, expandTo18Decimals(1)) - await mint( - wallet.address, - startingTick - 4 * tickSpacing, - startingTick - 2 * tickSpacing, - expandTo18Decimals(1) - ) - await swapExact0For1(2, wallet.address) - await pool.advanceTime(1) - await snapshotGasCost(swapExact0For1(expandTo18Decimals(1), wallet.address)) - expect((await pool.slot0()).tick).to.be.lt(startingTick - 4 * tickSpacing) - }) - - it('large swap crossing several initialized ticks second time after some time passes', async () => { - await mint(wallet.address, startingTick - 3 * tickSpacing, startingTick - tickSpacing, expandTo18Decimals(1)) - await mint( - wallet.address, - startingTick - 4 * tickSpacing, - startingTick - 2 * tickSpacing, - expandTo18Decimals(1) - ) - await swapExact0For1(expandTo18Decimals(1), wallet.address) - await swapToHigherPrice(startingPrice, wallet.address) - await pool.advanceTime(1) - await snapshotGasCost(swapExact0For1(expandTo18Decimals(1), wallet.address)) - expect((await pool.slot0()).tick).to.be.lt(tickSpacing * -4) - }) - }) - - describe('#mint', () => { - for (const { description, tickLower, tickUpper } of [ - { - description: 'around current price', - tickLower: startingTick - tickSpacing, - tickUpper: startingTick + tickSpacing, - }, - { - description: 'below current price', - tickLower: startingTick - 2 * tickSpacing, - tickUpper: startingTick - tickSpacing, - }, - { - description: 'above current price', - tickLower: startingTick + tickSpacing, - tickUpper: startingTick + 2 * tickSpacing, - }, - ]) { - describe(description, () => { - it('new position mint first in range', async () => { - await snapshotGasCost(mint(wallet.address, tickLower, tickUpper, expandTo18Decimals(1))) - }) - it('add to position existing', async () => { - await mint(wallet.address, tickLower, tickUpper, expandTo18Decimals(1)) - await snapshotGasCost(mint(wallet.address, tickLower, tickUpper, expandTo18Decimals(1))) - }) - it('second position in same range', async () => { - await mint(wallet.address, tickLower, tickUpper, expandTo18Decimals(1)) - await snapshotGasCost(mint(other.address, tickLower, tickUpper, expandTo18Decimals(1))) - }) - it('add to position after some time passes', async () => { - await mint(wallet.address, tickLower, tickUpper, expandTo18Decimals(1)) - await pool.advanceTime(1) - await snapshotGasCost(mint(wallet.address, tickLower, tickUpper, expandTo18Decimals(1))) - }) - }) - } - }) - - describe('#burn', () => { - for (const { description, tickLower, tickUpper } of [ - { - description: 'around current price', - tickLower: startingTick - tickSpacing, - tickUpper: startingTick + tickSpacing, - }, - { - description: 'below current price', - tickLower: startingTick - 2 * tickSpacing, - tickUpper: startingTick - tickSpacing, - }, - { - description: 'above current price', - tickLower: startingTick + tickSpacing, - tickUpper: startingTick + 2 * tickSpacing, - }, - ]) { - describe(description, () => { - const liquidityAmount = expandTo18Decimals(1) - beforeEach('mint a position', async () => { - await mint(wallet.address, tickLower, tickUpper, liquidityAmount) - }) - - it('burn when only position using ticks', async () => { - await snapshotGasCost(pool.burn(tickLower, tickUpper, expandTo18Decimals(1))) - }) - it('partial position burn', async () => { - await snapshotGasCost(pool.burn(tickLower, tickUpper, expandTo18Decimals(1).div(2))) - }) - it('entire position burn but other positions are using the ticks', async () => { - await mint(other.address, tickLower, tickUpper, expandTo18Decimals(1)) - await snapshotGasCost(pool.burn(tickLower, tickUpper, expandTo18Decimals(1))) - }) - it('burn entire position after some time passes', async () => { - await pool.advanceTime(1) - await snapshotGasCost(pool.burn(tickLower, tickUpper, expandTo18Decimals(1))) - }) - }) - } - }) - - describe('#poke', () => { - const tickLower = startingTick - tickSpacing - const tickUpper = startingTick + tickSpacing - - it('best case', async () => { - await mint(wallet.address, tickLower, tickUpper, expandTo18Decimals(1)) - await swapExact0For1(expandTo18Decimals(1).div(100), wallet.address) - await pool.burn(tickLower, tickUpper, 0) - await swapExact0For1(expandTo18Decimals(1).div(100), wallet.address) - await snapshotGasCost(pool.burn(tickLower, tickUpper, 0)) - }) - }) - - describe('#collect', () => { - const tickLower = startingTick - tickSpacing - const tickUpper = startingTick + tickSpacing - - it('close to worst case', async () => { - await mint(wallet.address, tickLower, tickUpper, expandTo18Decimals(1)) - await swapExact0For1(expandTo18Decimals(1).div(100), wallet.address) - await pool.burn(tickLower, tickUpper, 0) // poke to accumulate fees - await snapshotGasCost(pool.collect(wallet.address, tickLower, tickUpper, MaxUint128, MaxUint128)) - }) - }) - - describe('#increaseObservationCardinalityNext', () => { - it('grow by 1 slot', async () => { - await snapshotGasCost(pool.increaseObservationCardinalityNext(5)) - }) - it('no op', async () => { - await snapshotGasCost(pool.increaseObservationCardinalityNext(3)) - }) - }) - - describe('#snapshotCumulativesInside', () => { - it('tick inside', async () => { - await snapshotGasCost(pool.estimateGas.snapshotCumulativesInside(minTick, maxTick)) - }) - it('tick above', async () => { - await swapToHigherPrice(MAX_SQRT_RATIO.sub(1), wallet.address) - await snapshotGasCost(pool.estimateGas.snapshotCumulativesInside(minTick, maxTick)) - }) - it('tick below', async () => { - await swapToLowerPrice(MIN_SQRT_RATIO.add(1), wallet.address) - await snapshotGasCost(pool.estimateGas.snapshotCumulativesInside(minTick, maxTick)) - }) - }) - }) - } -}) diff --git a/lib/v3-core/test/UniswapV3Pool.spec.ts b/lib/v3-core/test/UniswapV3Pool.spec.ts deleted file mode 100644 index a7eb75e..0000000 --- a/lib/v3-core/test/UniswapV3Pool.spec.ts +++ /dev/null @@ -1,2043 +0,0 @@ -import { ethers, waffle } from 'hardhat' -import { BigNumber, BigNumberish, constants, Wallet } from 'ethers' -import { TestERC20 } from '../typechain/TestERC20' -import { UniswapV3Factory } from '../typechain/UniswapV3Factory' -import { MockTimeUniswapV3Pool } from '../typechain/MockTimeUniswapV3Pool' -import { TestUniswapV3SwapPay } from '../typechain/TestUniswapV3SwapPay' -import checkObservationEquals from './shared/checkObservationEquals' -import { expect } from './shared/expect' - -import { poolFixture, TEST_POOL_START_TIME } from './shared/fixtures' - -import { - expandTo18Decimals, - FeeAmount, - getPositionKey, - getMaxTick, - getMinTick, - encodePriceSqrt, - TICK_SPACINGS, - createPoolFunctions, - SwapFunction, - MintFunction, - getMaxLiquidityPerTick, - FlashFunction, - MaxUint128, - MAX_SQRT_RATIO, - MIN_SQRT_RATIO, - SwapToPriceFunction, -} from './shared/utilities' -import { TestUniswapV3Callee } from '../typechain/TestUniswapV3Callee' -import { TestUniswapV3ReentrantCallee } from '../typechain/TestUniswapV3ReentrantCallee' -import { TickMathTest } from '../typechain/TickMathTest' -import { SwapMathTest } from '../typechain/SwapMathTest' - -const createFixtureLoader = waffle.createFixtureLoader - -type ThenArg = T extends PromiseLike ? U : T - -describe('UniswapV3Pool', () => { - let wallet: Wallet, other: Wallet - - let token0: TestERC20 - let token1: TestERC20 - let token2: TestERC20 - - let factory: UniswapV3Factory - let pool: MockTimeUniswapV3Pool - - let swapTarget: TestUniswapV3Callee - - let swapToLowerPrice: SwapToPriceFunction - let swapToHigherPrice: SwapToPriceFunction - let swapExact0For1: SwapFunction - let swap0ForExact1: SwapFunction - let swapExact1For0: SwapFunction - let swap1ForExact0: SwapFunction - - let feeAmount: number - let tickSpacing: number - - let minTick: number - let maxTick: number - - let mint: MintFunction - let flash: FlashFunction - - let loadFixture: ReturnType - let createPool: ThenArg>['createPool'] - - before('create fixture loader', async () => { - ;[wallet, other] = await (ethers as any).getSigners() - loadFixture = createFixtureLoader([wallet, other]) - }) - - beforeEach('deploy fixture', async () => { - ;({ token0, token1, token2, factory, createPool, swapTargetCallee: swapTarget } = await loadFixture(poolFixture)) - - const oldCreatePool = createPool - createPool = async (_feeAmount, _tickSpacing) => { - const pool = await oldCreatePool(_feeAmount, _tickSpacing) - ;({ - swapToLowerPrice, - swapToHigherPrice, - swapExact0For1, - swap0ForExact1, - swapExact1For0, - swap1ForExact0, - mint, - flash, - } = createPoolFunctions({ - token0, - token1, - swapTarget, - pool, - })) - minTick = getMinTick(_tickSpacing) - maxTick = getMaxTick(_tickSpacing) - feeAmount = _feeAmount - tickSpacing = _tickSpacing - return pool - } - - // default to the 30 bips pool - pool = await createPool(FeeAmount.MEDIUM, TICK_SPACINGS[FeeAmount.MEDIUM]) - }) - - it('constructor initializes immutables', async () => { - expect(await pool.factory()).to.eq(factory.address) - expect(await pool.token0()).to.eq(token0.address) - expect(await pool.token1()).to.eq(token1.address) - expect(await pool.maxLiquidityPerTick()).to.eq(getMaxLiquidityPerTick(tickSpacing)) - }) - - describe('#initialize', () => { - it('fails if already initialized', async () => { - await pool.initialize(encodePriceSqrt(1, 1)) - await expect(pool.initialize(encodePriceSqrt(1, 1))).to.be.reverted - }) - it('fails if starting price is too low', async () => { - await expect(pool.initialize(1)).to.be.revertedWith('R') - await expect(pool.initialize(MIN_SQRT_RATIO.sub(1))).to.be.revertedWith('R') - }) - it('fails if starting price is too high', async () => { - await expect(pool.initialize(MAX_SQRT_RATIO)).to.be.revertedWith('R') - await expect(pool.initialize(BigNumber.from(2).pow(160).sub(1))).to.be.revertedWith('R') - }) - it('can be initialized at MIN_SQRT_RATIO', async () => { - await pool.initialize(MIN_SQRT_RATIO) - expect((await pool.slot0()).tick).to.eq(getMinTick(1)) - }) - it('can be initialized at MAX_SQRT_RATIO - 1', async () => { - await pool.initialize(MAX_SQRT_RATIO.sub(1)) - expect((await pool.slot0()).tick).to.eq(getMaxTick(1) - 1) - }) - it('sets initial variables', async () => { - const price = encodePriceSqrt(1, 2) - await pool.initialize(price) - - const { sqrtPriceX96, observationIndex } = await pool.slot0() - expect(sqrtPriceX96).to.eq(price) - expect(observationIndex).to.eq(0) - expect((await pool.slot0()).tick).to.eq(-6932) - }) - it('initializes the first observations slot', async () => { - await pool.initialize(encodePriceSqrt(1, 1)) - checkObservationEquals(await pool.observations(0), { - secondsPerLiquidityCumulativeX128: 0, - initialized: true, - blockTimestamp: TEST_POOL_START_TIME, - tickCumulative: 0, - }) - }) - it('emits a Initialized event with the input tick', async () => { - const sqrtPriceX96 = encodePriceSqrt(1, 2) - await expect(pool.initialize(sqrtPriceX96)).to.emit(pool, 'Initialize').withArgs(sqrtPriceX96, -6932) - }) - }) - - describe('#increaseObservationCardinalityNext', () => { - it('can only be called after initialize', async () => { - await expect(pool.increaseObservationCardinalityNext(2)).to.be.revertedWith('LOK') - }) - it('emits an event including both old and new', async () => { - await pool.initialize(encodePriceSqrt(1, 1)) - await expect(pool.increaseObservationCardinalityNext(2)) - .to.emit(pool, 'IncreaseObservationCardinalityNext') - .withArgs(1, 2) - }) - it('does not emit an event for no op call', async () => { - await pool.initialize(encodePriceSqrt(1, 1)) - await pool.increaseObservationCardinalityNext(3) - await expect(pool.increaseObservationCardinalityNext(2)).to.not.emit(pool, 'IncreaseObservationCardinalityNext') - }) - it('does not change cardinality next if less than current', async () => { - await pool.initialize(encodePriceSqrt(1, 1)) - await pool.increaseObservationCardinalityNext(3) - await pool.increaseObservationCardinalityNext(2) - expect((await pool.slot0()).observationCardinalityNext).to.eq(3) - }) - it('increases cardinality and cardinality next first time', async () => { - await pool.initialize(encodePriceSqrt(1, 1)) - await pool.increaseObservationCardinalityNext(2) - const { observationCardinality, observationCardinalityNext } = await pool.slot0() - expect(observationCardinality).to.eq(1) - expect(observationCardinalityNext).to.eq(2) - }) - }) - - describe('#mint', () => { - it('fails if not initialized', async () => { - await expect(mint(wallet.address, -tickSpacing, tickSpacing, 1)).to.be.revertedWith('LOK') - }) - describe('after initialization', () => { - beforeEach('initialize the pool at price of 10:1', async () => { - await pool.initialize(encodePriceSqrt(1, 10)) - await mint(wallet.address, minTick, maxTick, 3161) - }) - - describe('failure cases', () => { - it('fails if tickLower greater than tickUpper', async () => { - // should be TLU but...hardhat - await expect(mint(wallet.address, 1, 0, 1)).to.be.reverted - }) - it('fails if tickLower less than min tick', async () => { - // should be TLM but...hardhat - await expect(mint(wallet.address, -887273, 0, 1)).to.be.reverted - }) - it('fails if tickUpper greater than max tick', async () => { - // should be TUM but...hardhat - await expect(mint(wallet.address, 0, 887273, 1)).to.be.reverted - }) - it('fails if amount exceeds the max', async () => { - // these should fail with 'LO' but hardhat is bugged - const maxLiquidityGross = await pool.maxLiquidityPerTick() - await expect(mint(wallet.address, minTick + tickSpacing, maxTick - tickSpacing, maxLiquidityGross.add(1))).to - .be.reverted - await expect(mint(wallet.address, minTick + tickSpacing, maxTick - tickSpacing, maxLiquidityGross)).to.not.be - .reverted - }) - it('fails if total amount at tick exceeds the max', async () => { - // these should fail with 'LO' but hardhat is bugged - await mint(wallet.address, minTick + tickSpacing, maxTick - tickSpacing, 1000) - - const maxLiquidityGross = await pool.maxLiquidityPerTick() - await expect( - mint(wallet.address, minTick + tickSpacing, maxTick - tickSpacing, maxLiquidityGross.sub(1000).add(1)) - ).to.be.reverted - await expect( - mint(wallet.address, minTick + tickSpacing * 2, maxTick - tickSpacing, maxLiquidityGross.sub(1000).add(1)) - ).to.be.reverted - await expect( - mint(wallet.address, minTick + tickSpacing, maxTick - tickSpacing * 2, maxLiquidityGross.sub(1000).add(1)) - ).to.be.reverted - await expect(mint(wallet.address, minTick + tickSpacing, maxTick - tickSpacing, maxLiquidityGross.sub(1000))) - .to.not.be.reverted - }) - it('fails if amount is 0', async () => { - await expect(mint(wallet.address, minTick + tickSpacing, maxTick - tickSpacing, 0)).to.be.reverted - }) - }) - - describe('success cases', () => { - it('initial balances', async () => { - expect(await token0.balanceOf(pool.address)).to.eq(9996) - expect(await token1.balanceOf(pool.address)).to.eq(1000) - }) - - it('initial tick', async () => { - expect((await pool.slot0()).tick).to.eq(-23028) - }) - - describe('above current price', () => { - it('transfers token0 only', async () => { - await expect(mint(wallet.address, -22980, 0, 10000)) - .to.emit(token0, 'Transfer') - .withArgs(wallet.address, pool.address, 21549) - .to.not.emit(token1, 'Transfer') - expect(await token0.balanceOf(pool.address)).to.eq(9996 + 21549) - expect(await token1.balanceOf(pool.address)).to.eq(1000) - }) - - it('max tick with max leverage', async () => { - await mint(wallet.address, maxTick - tickSpacing, maxTick, BigNumber.from(2).pow(102)) - expect(await token0.balanceOf(pool.address)).to.eq(9996 + 828011525) - expect(await token1.balanceOf(pool.address)).to.eq(1000) - }) - - it('works for max tick', async () => { - await expect(mint(wallet.address, -22980, maxTick, 10000)) - .to.emit(token0, 'Transfer') - .withArgs(wallet.address, pool.address, 31549) - expect(await token0.balanceOf(pool.address)).to.eq(9996 + 31549) - expect(await token1.balanceOf(pool.address)).to.eq(1000) - }) - - it('removing works', async () => { - await mint(wallet.address, -240, 0, 10000) - await pool.burn(-240, 0, 10000) - const { amount0, amount1 } = await pool.callStatic.collect(wallet.address, -240, 0, MaxUint128, MaxUint128) - expect(amount0, 'amount0').to.eq(120) - expect(amount1, 'amount1').to.eq(0) - }) - - it('adds liquidity to liquidityGross', async () => { - await mint(wallet.address, -240, 0, 100) - expect((await pool.ticks(-240)).liquidityGross).to.eq(100) - expect((await pool.ticks(0)).liquidityGross).to.eq(100) - expect((await pool.ticks(tickSpacing)).liquidityGross).to.eq(0) - expect((await pool.ticks(tickSpacing * 2)).liquidityGross).to.eq(0) - await mint(wallet.address, -240, tickSpacing, 150) - expect((await pool.ticks(-240)).liquidityGross).to.eq(250) - expect((await pool.ticks(0)).liquidityGross).to.eq(100) - expect((await pool.ticks(tickSpacing)).liquidityGross).to.eq(150) - expect((await pool.ticks(tickSpacing * 2)).liquidityGross).to.eq(0) - await mint(wallet.address, 0, tickSpacing * 2, 60) - expect((await pool.ticks(-240)).liquidityGross).to.eq(250) - expect((await pool.ticks(0)).liquidityGross).to.eq(160) - expect((await pool.ticks(tickSpacing)).liquidityGross).to.eq(150) - expect((await pool.ticks(tickSpacing * 2)).liquidityGross).to.eq(60) - }) - - it('removes liquidity from liquidityGross', async () => { - await mint(wallet.address, -240, 0, 100) - await mint(wallet.address, -240, 0, 40) - await pool.burn(-240, 0, 90) - expect((await pool.ticks(-240)).liquidityGross).to.eq(50) - expect((await pool.ticks(0)).liquidityGross).to.eq(50) - }) - - it('clears tick lower if last position is removed', async () => { - await mint(wallet.address, -240, 0, 100) - await pool.burn(-240, 0, 100) - const { liquidityGross, feeGrowthOutside0X128, feeGrowthOutside1X128 } = await pool.ticks(-240) - expect(liquidityGross).to.eq(0) - expect(feeGrowthOutside0X128).to.eq(0) - expect(feeGrowthOutside1X128).to.eq(0) - }) - - it('clears tick upper if last position is removed', async () => { - await mint(wallet.address, -240, 0, 100) - await pool.burn(-240, 0, 100) - const { liquidityGross, feeGrowthOutside0X128, feeGrowthOutside1X128 } = await pool.ticks(0) - expect(liquidityGross).to.eq(0) - expect(feeGrowthOutside0X128).to.eq(0) - expect(feeGrowthOutside1X128).to.eq(0) - }) - it('only clears the tick that is not used at all', async () => { - await mint(wallet.address, -240, 0, 100) - await mint(wallet.address, -tickSpacing, 0, 250) - await pool.burn(-240, 0, 100) - - let { liquidityGross, feeGrowthOutside0X128, feeGrowthOutside1X128 } = await pool.ticks(-240) - expect(liquidityGross).to.eq(0) - expect(feeGrowthOutside0X128).to.eq(0) - expect(feeGrowthOutside1X128).to.eq(0) - ;({ liquidityGross, feeGrowthOutside0X128, feeGrowthOutside1X128 } = await pool.ticks(-tickSpacing)) - expect(liquidityGross).to.eq(250) - expect(feeGrowthOutside0X128).to.eq(0) - expect(feeGrowthOutside1X128).to.eq(0) - }) - - it('does not write an observation', async () => { - checkObservationEquals(await pool.observations(0), { - tickCumulative: 0, - blockTimestamp: TEST_POOL_START_TIME, - initialized: true, - secondsPerLiquidityCumulativeX128: 0, - }) - await pool.advanceTime(1) - await mint(wallet.address, -240, 0, 100) - checkObservationEquals(await pool.observations(0), { - tickCumulative: 0, - blockTimestamp: TEST_POOL_START_TIME, - initialized: true, - secondsPerLiquidityCumulativeX128: 0, - }) - }) - }) - - describe('including current price', () => { - it('price within range: transfers current price of both tokens', async () => { - await expect(mint(wallet.address, minTick + tickSpacing, maxTick - tickSpacing, 100)) - .to.emit(token0, 'Transfer') - .withArgs(wallet.address, pool.address, 317) - .to.emit(token1, 'Transfer') - .withArgs(wallet.address, pool.address, 32) - expect(await token0.balanceOf(pool.address)).to.eq(9996 + 317) - expect(await token1.balanceOf(pool.address)).to.eq(1000 + 32) - }) - - it('initializes lower tick', async () => { - await mint(wallet.address, minTick + tickSpacing, maxTick - tickSpacing, 100) - const { liquidityGross } = await pool.ticks(minTick + tickSpacing) - expect(liquidityGross).to.eq(100) - }) - - it('initializes upper tick', async () => { - await mint(wallet.address, minTick + tickSpacing, maxTick - tickSpacing, 100) - const { liquidityGross } = await pool.ticks(maxTick - tickSpacing) - expect(liquidityGross).to.eq(100) - }) - - it('works for min/max tick', async () => { - await expect(mint(wallet.address, minTick, maxTick, 10000)) - .to.emit(token0, 'Transfer') - .withArgs(wallet.address, pool.address, 31623) - .to.emit(token1, 'Transfer') - .withArgs(wallet.address, pool.address, 3163) - expect(await token0.balanceOf(pool.address)).to.eq(9996 + 31623) - expect(await token1.balanceOf(pool.address)).to.eq(1000 + 3163) - }) - - it('removing works', async () => { - await mint(wallet.address, minTick + tickSpacing, maxTick - tickSpacing, 100) - await pool.burn(minTick + tickSpacing, maxTick - tickSpacing, 100) - const { amount0, amount1 } = await pool.callStatic.collect( - wallet.address, - minTick + tickSpacing, - maxTick - tickSpacing, - MaxUint128, - MaxUint128 - ) - expect(amount0, 'amount0').to.eq(316) - expect(amount1, 'amount1').to.eq(31) - }) - - it('writes an observation', async () => { - checkObservationEquals(await pool.observations(0), { - tickCumulative: 0, - blockTimestamp: TEST_POOL_START_TIME, - initialized: true, - secondsPerLiquidityCumulativeX128: 0, - }) - await pool.advanceTime(1) - await mint(wallet.address, minTick, maxTick, 100) - checkObservationEquals(await pool.observations(0), { - tickCumulative: -23028, - blockTimestamp: TEST_POOL_START_TIME + 1, - initialized: true, - secondsPerLiquidityCumulativeX128: '107650226801941937191829992860413859', - }) - }) - }) - - describe('below current price', () => { - it('transfers token1 only', async () => { - await expect(mint(wallet.address, -46080, -23040, 10000)) - .to.emit(token1, 'Transfer') - .withArgs(wallet.address, pool.address, 2162) - .to.not.emit(token0, 'Transfer') - expect(await token0.balanceOf(pool.address)).to.eq(9996) - expect(await token1.balanceOf(pool.address)).to.eq(1000 + 2162) - }) - - it('min tick with max leverage', async () => { - await mint(wallet.address, minTick, minTick + tickSpacing, BigNumber.from(2).pow(102)) - expect(await token0.balanceOf(pool.address)).to.eq(9996) - expect(await token1.balanceOf(pool.address)).to.eq(1000 + 828011520) - }) - - it('works for min tick', async () => { - await expect(mint(wallet.address, minTick, -23040, 10000)) - .to.emit(token1, 'Transfer') - .withArgs(wallet.address, pool.address, 3161) - expect(await token0.balanceOf(pool.address)).to.eq(9996) - expect(await token1.balanceOf(pool.address)).to.eq(1000 + 3161) - }) - - it('removing works', async () => { - await mint(wallet.address, -46080, -46020, 10000) - await pool.burn(-46080, -46020, 10000) - const { amount0, amount1 } = await pool.callStatic.collect( - wallet.address, - -46080, - -46020, - MaxUint128, - MaxUint128 - ) - expect(amount0, 'amount0').to.eq(0) - expect(amount1, 'amount1').to.eq(3) - }) - - it('does not write an observation', async () => { - checkObservationEquals(await pool.observations(0), { - tickCumulative: 0, - blockTimestamp: TEST_POOL_START_TIME, - initialized: true, - secondsPerLiquidityCumulativeX128: 0, - }) - await pool.advanceTime(1) - await mint(wallet.address, -46080, -23040, 100) - checkObservationEquals(await pool.observations(0), { - tickCumulative: 0, - blockTimestamp: TEST_POOL_START_TIME, - initialized: true, - secondsPerLiquidityCumulativeX128: 0, - }) - }) - }) - }) - - it('protocol fees accumulate as expected during swap', async () => { - await pool.setFeeProtocol(6, 6) - - await mint(wallet.address, minTick + tickSpacing, maxTick - tickSpacing, expandTo18Decimals(1)) - await swapExact0For1(expandTo18Decimals(1).div(10), wallet.address) - await swapExact1For0(expandTo18Decimals(1).div(100), wallet.address) - - let { token0: token0ProtocolFees, token1: token1ProtocolFees } = await pool.protocolFees() - expect(token0ProtocolFees).to.eq('50000000000000') - expect(token1ProtocolFees).to.eq('5000000000000') - }) - - it('positions are protected before protocol fee is turned on', async () => { - await mint(wallet.address, minTick + tickSpacing, maxTick - tickSpacing, expandTo18Decimals(1)) - await swapExact0For1(expandTo18Decimals(1).div(10), wallet.address) - await swapExact1For0(expandTo18Decimals(1).div(100), wallet.address) - - let { token0: token0ProtocolFees, token1: token1ProtocolFees } = await pool.protocolFees() - expect(token0ProtocolFees).to.eq(0) - expect(token1ProtocolFees).to.eq(0) - - await pool.setFeeProtocol(6, 6) - ;({ token0: token0ProtocolFees, token1: token1ProtocolFees } = await pool.protocolFees()) - expect(token0ProtocolFees).to.eq(0) - expect(token1ProtocolFees).to.eq(0) - }) - - it('poke is not allowed on uninitialized position', async () => { - await mint(other.address, minTick + tickSpacing, maxTick - tickSpacing, expandTo18Decimals(1)) - await swapExact0For1(expandTo18Decimals(1).div(10), wallet.address) - await swapExact1For0(expandTo18Decimals(1).div(100), wallet.address) - - // missing revert reason due to hardhat - await expect(pool.burn(minTick + tickSpacing, maxTick - tickSpacing, 0)).to.be.reverted - - await mint(wallet.address, minTick + tickSpacing, maxTick - tickSpacing, 1) - let { - liquidity, - feeGrowthInside0LastX128, - feeGrowthInside1LastX128, - tokensOwed1, - tokensOwed0, - } = await pool.positions(getPositionKey(wallet.address, minTick + tickSpacing, maxTick - tickSpacing)) - expect(liquidity).to.eq(1) - expect(feeGrowthInside0LastX128).to.eq('102084710076281216349243831104605583') - expect(feeGrowthInside1LastX128).to.eq('10208471007628121634924383110460558') - expect(tokensOwed0, 'tokens owed 0 before').to.eq(0) - expect(tokensOwed1, 'tokens owed 1 before').to.eq(0) - - await pool.burn(minTick + tickSpacing, maxTick - tickSpacing, 1) - ;({ - liquidity, - feeGrowthInside0LastX128, - feeGrowthInside1LastX128, - tokensOwed1, - tokensOwed0, - } = await pool.positions(getPositionKey(wallet.address, minTick + tickSpacing, maxTick - tickSpacing))) - expect(liquidity).to.eq(0) - expect(feeGrowthInside0LastX128).to.eq('102084710076281216349243831104605583') - expect(feeGrowthInside1LastX128).to.eq('10208471007628121634924383110460558') - expect(tokensOwed0, 'tokens owed 0 after').to.eq(3) - expect(tokensOwed1, 'tokens owed 1 after').to.eq(0) - }) - }) - }) - - describe('#burn', () => { - beforeEach('initialize at zero tick', () => initializeAtZeroTick(pool)) - - async function checkTickIsClear(tick: number) { - const { liquidityGross, feeGrowthOutside0X128, feeGrowthOutside1X128, liquidityNet } = await pool.ticks(tick) - expect(liquidityGross).to.eq(0) - expect(feeGrowthOutside0X128).to.eq(0) - expect(feeGrowthOutside1X128).to.eq(0) - expect(liquidityNet).to.eq(0) - } - - async function checkTickIsNotClear(tick: number) { - const { liquidityGross } = await pool.ticks(tick) - expect(liquidityGross).to.not.eq(0) - } - - it('does not clear the position fee growth snapshot if no more liquidity', async () => { - // some activity that would make the ticks non-zero - await pool.advanceTime(10) - await mint(other.address, minTick, maxTick, expandTo18Decimals(1)) - await swapExact0For1(expandTo18Decimals(1), wallet.address) - await swapExact1For0(expandTo18Decimals(1), wallet.address) - await pool.connect(other).burn(minTick, maxTick, expandTo18Decimals(1)) - const { - liquidity, - tokensOwed0, - tokensOwed1, - feeGrowthInside0LastX128, - feeGrowthInside1LastX128, - } = await pool.positions(getPositionKey(other.address, minTick, maxTick)) - expect(liquidity).to.eq(0) - expect(tokensOwed0).to.not.eq(0) - expect(tokensOwed1).to.not.eq(0) - expect(feeGrowthInside0LastX128).to.eq('340282366920938463463374607431768211') - expect(feeGrowthInside1LastX128).to.eq('340282366920938576890830247744589365') - }) - - it('clears the tick if its the last position using it', async () => { - const tickLower = minTick + tickSpacing - const tickUpper = maxTick - tickSpacing - // some activity that would make the ticks non-zero - await pool.advanceTime(10) - await mint(wallet.address, tickLower, tickUpper, 1) - await swapExact0For1(expandTo18Decimals(1), wallet.address) - await pool.burn(tickLower, tickUpper, 1) - await checkTickIsClear(tickLower) - await checkTickIsClear(tickUpper) - }) - - it('clears only the lower tick if upper is still used', async () => { - const tickLower = minTick + tickSpacing - const tickUpper = maxTick - tickSpacing - // some activity that would make the ticks non-zero - await pool.advanceTime(10) - await mint(wallet.address, tickLower, tickUpper, 1) - await mint(wallet.address, tickLower + tickSpacing, tickUpper, 1) - await swapExact0For1(expandTo18Decimals(1), wallet.address) - await pool.burn(tickLower, tickUpper, 1) - await checkTickIsClear(tickLower) - await checkTickIsNotClear(tickUpper) - }) - - it('clears only the upper tick if lower is still used', async () => { - const tickLower = minTick + tickSpacing - const tickUpper = maxTick - tickSpacing - // some activity that would make the ticks non-zero - await pool.advanceTime(10) - await mint(wallet.address, tickLower, tickUpper, 1) - await mint(wallet.address, tickLower, tickUpper - tickSpacing, 1) - await swapExact0For1(expandTo18Decimals(1), wallet.address) - await pool.burn(tickLower, tickUpper, 1) - await checkTickIsNotClear(tickLower) - await checkTickIsClear(tickUpper) - }) - }) - - // the combined amount of liquidity that the pool is initialized with (including the 1 minimum liquidity that is burned) - const initializeLiquidityAmount = expandTo18Decimals(2) - async function initializeAtZeroTick(pool: MockTimeUniswapV3Pool): Promise { - await pool.initialize(encodePriceSqrt(1, 1)) - const tickSpacing = await pool.tickSpacing() - const [min, max] = [getMinTick(tickSpacing), getMaxTick(tickSpacing)] - await mint(wallet.address, min, max, initializeLiquidityAmount) - } - - describe('#observe', () => { - beforeEach(() => initializeAtZeroTick(pool)) - - // zero tick - it('current tick accumulator increases by tick over time', async () => { - let { - tickCumulatives: [tickCumulative], - } = await pool.observe([0]) - expect(tickCumulative).to.eq(0) - await pool.advanceTime(10) - ;({ - tickCumulatives: [tickCumulative], - } = await pool.observe([0])) - expect(tickCumulative).to.eq(0) - }) - - it('current tick accumulator after single swap', async () => { - // moves to tick -1 - await swapExact0For1(1000, wallet.address) - await pool.advanceTime(4) - let { - tickCumulatives: [tickCumulative], - } = await pool.observe([0]) - expect(tickCumulative).to.eq(-4) - }) - - it('current tick accumulator after two swaps', async () => { - await swapExact0For1(expandTo18Decimals(1).div(2), wallet.address) - expect((await pool.slot0()).tick).to.eq(-4452) - await pool.advanceTime(4) - await swapExact1For0(expandTo18Decimals(1).div(4), wallet.address) - expect((await pool.slot0()).tick).to.eq(-1558) - await pool.advanceTime(6) - let { - tickCumulatives: [tickCumulative], - } = await pool.observe([0]) - // -4452*4 + -1558*6 - expect(tickCumulative).to.eq(-27156) - }) - }) - - describe('miscellaneous mint tests', () => { - beforeEach('initialize at zero tick', async () => { - pool = await createPool(FeeAmount.LOW, TICK_SPACINGS[FeeAmount.LOW]) - await initializeAtZeroTick(pool) - }) - - it('mint to the right of the current price', async () => { - const liquidityDelta = 1000 - const lowerTick = tickSpacing - const upperTick = tickSpacing * 2 - - const liquidityBefore = await pool.liquidity() - - const b0 = await token0.balanceOf(pool.address) - const b1 = await token1.balanceOf(pool.address) - - await mint(wallet.address, lowerTick, upperTick, liquidityDelta) - - const liquidityAfter = await pool.liquidity() - expect(liquidityAfter).to.be.gte(liquidityBefore) - - expect((await token0.balanceOf(pool.address)).sub(b0)).to.eq(1) - expect((await token1.balanceOf(pool.address)).sub(b1)).to.eq(0) - }) - - it('mint to the left of the current price', async () => { - const liquidityDelta = 1000 - const lowerTick = -tickSpacing * 2 - const upperTick = -tickSpacing - - const liquidityBefore = await pool.liquidity() - - const b0 = await token0.balanceOf(pool.address) - const b1 = await token1.balanceOf(pool.address) - - await mint(wallet.address, lowerTick, upperTick, liquidityDelta) - - const liquidityAfter = await pool.liquidity() - expect(liquidityAfter).to.be.gte(liquidityBefore) - - expect((await token0.balanceOf(pool.address)).sub(b0)).to.eq(0) - expect((await token1.balanceOf(pool.address)).sub(b1)).to.eq(1) - }) - - it('mint within the current price', async () => { - const liquidityDelta = 1000 - const lowerTick = -tickSpacing - const upperTick = tickSpacing - - const liquidityBefore = await pool.liquidity() - - const b0 = await token0.balanceOf(pool.address) - const b1 = await token1.balanceOf(pool.address) - - await mint(wallet.address, lowerTick, upperTick, liquidityDelta) - - const liquidityAfter = await pool.liquidity() - expect(liquidityAfter).to.be.gte(liquidityBefore) - - expect((await token0.balanceOf(pool.address)).sub(b0)).to.eq(1) - expect((await token1.balanceOf(pool.address)).sub(b1)).to.eq(1) - }) - - it('cannot remove more than the entire position', async () => { - const lowerTick = -tickSpacing - const upperTick = tickSpacing - await mint(wallet.address, lowerTick, upperTick, expandTo18Decimals(1000)) - // should be 'LS', hardhat is bugged - await expect(pool.burn(lowerTick, upperTick, expandTo18Decimals(1001))).to.be.reverted - }) - - it('collect fees within the current price after swap', async () => { - const liquidityDelta = expandTo18Decimals(100) - const lowerTick = -tickSpacing * 100 - const upperTick = tickSpacing * 100 - - await mint(wallet.address, lowerTick, upperTick, liquidityDelta) - - const liquidityBefore = await pool.liquidity() - - const amount0In = expandTo18Decimals(1) - await swapExact0For1(amount0In, wallet.address) - - const liquidityAfter = await pool.liquidity() - expect(liquidityAfter, 'k increases').to.be.gte(liquidityBefore) - - const token0BalanceBeforePool = await token0.balanceOf(pool.address) - const token1BalanceBeforePool = await token1.balanceOf(pool.address) - const token0BalanceBeforeWallet = await token0.balanceOf(wallet.address) - const token1BalanceBeforeWallet = await token1.balanceOf(wallet.address) - - await pool.burn(lowerTick, upperTick, 0) - await pool.collect(wallet.address, lowerTick, upperTick, MaxUint128, MaxUint128) - - await pool.burn(lowerTick, upperTick, 0) - const { amount0: fees0, amount1: fees1 } = await pool.callStatic.collect( - wallet.address, - lowerTick, - upperTick, - MaxUint128, - MaxUint128 - ) - expect(fees0).to.be.eq(0) - expect(fees1).to.be.eq(0) - - const token0BalanceAfterWallet = await token0.balanceOf(wallet.address) - const token1BalanceAfterWallet = await token1.balanceOf(wallet.address) - const token0BalanceAfterPool = await token0.balanceOf(pool.address) - const token1BalanceAfterPool = await token1.balanceOf(pool.address) - - expect(token0BalanceAfterWallet).to.be.gt(token0BalanceBeforeWallet) - expect(token1BalanceAfterWallet).to.be.eq(token1BalanceBeforeWallet) - - expect(token0BalanceAfterPool).to.be.lt(token0BalanceBeforePool) - expect(token1BalanceAfterPool).to.be.eq(token1BalanceBeforePool) - }) - }) - - describe('post-initialize at medium fee', () => { - describe('k (implicit)', () => { - it('returns 0 before initialization', async () => { - expect(await pool.liquidity()).to.eq(0) - }) - describe('post initialized', () => { - beforeEach(() => initializeAtZeroTick(pool)) - - it('returns initial liquidity', async () => { - expect(await pool.liquidity()).to.eq(expandTo18Decimals(2)) - }) - it('returns in supply in range', async () => { - await mint(wallet.address, -tickSpacing, tickSpacing, expandTo18Decimals(3)) - expect(await pool.liquidity()).to.eq(expandTo18Decimals(5)) - }) - it('excludes supply at tick above current tick', async () => { - await mint(wallet.address, tickSpacing, tickSpacing * 2, expandTo18Decimals(3)) - expect(await pool.liquidity()).to.eq(expandTo18Decimals(2)) - }) - it('excludes supply at tick below current tick', async () => { - await mint(wallet.address, -tickSpacing * 2, -tickSpacing, expandTo18Decimals(3)) - expect(await pool.liquidity()).to.eq(expandTo18Decimals(2)) - }) - it('updates correctly when exiting range', async () => { - const kBefore = await pool.liquidity() - expect(kBefore).to.be.eq(expandTo18Decimals(2)) - - // add liquidity at and above current tick - const liquidityDelta = expandTo18Decimals(1) - const lowerTick = 0 - const upperTick = tickSpacing - await mint(wallet.address, lowerTick, upperTick, liquidityDelta) - - // ensure virtual supply has increased appropriately - const kAfter = await pool.liquidity() - expect(kAfter).to.be.eq(expandTo18Decimals(3)) - - // swap toward the left (just enough for the tick transition function to trigger) - await swapExact0For1(1, wallet.address) - const { tick } = await pool.slot0() - expect(tick).to.be.eq(-1) - - const kAfterSwap = await pool.liquidity() - expect(kAfterSwap).to.be.eq(expandTo18Decimals(2)) - }) - it('updates correctly when entering range', async () => { - const kBefore = await pool.liquidity() - expect(kBefore).to.be.eq(expandTo18Decimals(2)) - - // add liquidity below the current tick - const liquidityDelta = expandTo18Decimals(1) - const lowerTick = -tickSpacing - const upperTick = 0 - await mint(wallet.address, lowerTick, upperTick, liquidityDelta) - - // ensure virtual supply hasn't changed - const kAfter = await pool.liquidity() - expect(kAfter).to.be.eq(kBefore) - - // swap toward the left (just enough for the tick transition function to trigger) - await swapExact0For1(1, wallet.address) - const { tick } = await pool.slot0() - expect(tick).to.be.eq(-1) - - const kAfterSwap = await pool.liquidity() - expect(kAfterSwap).to.be.eq(expandTo18Decimals(3)) - }) - }) - }) - }) - - describe('limit orders', () => { - beforeEach('initialize at tick 0', () => initializeAtZeroTick(pool)) - - it('limit selling 0 for 1 at tick 0 thru 1', async () => { - await expect(mint(wallet.address, 0, 120, expandTo18Decimals(1))) - .to.emit(token0, 'Transfer') - .withArgs(wallet.address, pool.address, '5981737760509663') - // somebody takes the limit order - await swapExact1For0(expandTo18Decimals(2), other.address) - await expect(pool.burn(0, 120, expandTo18Decimals(1))) - .to.emit(pool, 'Burn') - .withArgs(wallet.address, 0, 120, expandTo18Decimals(1), 0, '6017734268818165') - .to.not.emit(token0, 'Transfer') - .to.not.emit(token1, 'Transfer') - await expect(pool.collect(wallet.address, 0, 120, MaxUint128, MaxUint128)) - .to.emit(token1, 'Transfer') - .withArgs(pool.address, wallet.address, BigNumber.from('6017734268818165').add('18107525382602')) // roughly 0.3% despite other liquidity - .to.not.emit(token0, 'Transfer') - expect((await pool.slot0()).tick).to.be.gte(120) - }) - it('limit selling 1 for 0 at tick 0 thru -1', async () => { - await expect(mint(wallet.address, -120, 0, expandTo18Decimals(1))) - .to.emit(token1, 'Transfer') - .withArgs(wallet.address, pool.address, '5981737760509663') - // somebody takes the limit order - await swapExact0For1(expandTo18Decimals(2), other.address) - await expect(pool.burn(-120, 0, expandTo18Decimals(1))) - .to.emit(pool, 'Burn') - .withArgs(wallet.address, -120, 0, expandTo18Decimals(1), '6017734268818165', 0) - .to.not.emit(token0, 'Transfer') - .to.not.emit(token1, 'Transfer') - await expect(pool.collect(wallet.address, -120, 0, MaxUint128, MaxUint128)) - .to.emit(token0, 'Transfer') - .withArgs(pool.address, wallet.address, BigNumber.from('6017734268818165').add('18107525382602')) // roughly 0.3% despite other liquidity - expect((await pool.slot0()).tick).to.be.lt(-120) - }) - - describe('fee is on', () => { - beforeEach(() => pool.setFeeProtocol(6, 6)) - it('limit selling 0 for 1 at tick 0 thru 1', async () => { - await expect(mint(wallet.address, 0, 120, expandTo18Decimals(1))) - .to.emit(token0, 'Transfer') - .withArgs(wallet.address, pool.address, '5981737760509663') - // somebody takes the limit order - await swapExact1For0(expandTo18Decimals(2), other.address) - await expect(pool.burn(0, 120, expandTo18Decimals(1))) - .to.emit(pool, 'Burn') - .withArgs(wallet.address, 0, 120, expandTo18Decimals(1), 0, '6017734268818165') - .to.not.emit(token0, 'Transfer') - .to.not.emit(token1, 'Transfer') - await expect(pool.collect(wallet.address, 0, 120, MaxUint128, MaxUint128)) - .to.emit(token1, 'Transfer') - .withArgs(pool.address, wallet.address, BigNumber.from('6017734268818165').add('15089604485501')) // roughly 0.25% despite other liquidity - .to.not.emit(token0, 'Transfer') - expect((await pool.slot0()).tick).to.be.gte(120) - }) - it('limit selling 1 for 0 at tick 0 thru -1', async () => { - await expect(mint(wallet.address, -120, 0, expandTo18Decimals(1))) - .to.emit(token1, 'Transfer') - .withArgs(wallet.address, pool.address, '5981737760509663') - // somebody takes the limit order - await swapExact0For1(expandTo18Decimals(2), other.address) - await expect(pool.burn(-120, 0, expandTo18Decimals(1))) - .to.emit(pool, 'Burn') - .withArgs(wallet.address, -120, 0, expandTo18Decimals(1), '6017734268818165', 0) - .to.not.emit(token0, 'Transfer') - .to.not.emit(token1, 'Transfer') - await expect(pool.collect(wallet.address, -120, 0, MaxUint128, MaxUint128)) - .to.emit(token0, 'Transfer') - .withArgs(pool.address, wallet.address, BigNumber.from('6017734268818165').add('15089604485501')) // roughly 0.25% despite other liquidity - expect((await pool.slot0()).tick).to.be.lt(-120) - }) - }) - }) - - describe('#collect', () => { - beforeEach(async () => { - pool = await createPool(FeeAmount.LOW, TICK_SPACINGS[FeeAmount.LOW]) - await pool.initialize(encodePriceSqrt(1, 1)) - }) - - it('works with multiple LPs', async () => { - await mint(wallet.address, minTick, maxTick, expandTo18Decimals(1)) - await mint(wallet.address, minTick + tickSpacing, maxTick - tickSpacing, expandTo18Decimals(2)) - - await swapExact0For1(expandTo18Decimals(1), wallet.address) - - // poke positions - await pool.burn(minTick, maxTick, 0) - await pool.burn(minTick + tickSpacing, maxTick - tickSpacing, 0) - - const { tokensOwed0: tokensOwed0Position0 } = await pool.positions( - getPositionKey(wallet.address, minTick, maxTick) - ) - const { tokensOwed0: tokensOwed0Position1 } = await pool.positions( - getPositionKey(wallet.address, minTick + tickSpacing, maxTick - tickSpacing) - ) - - expect(tokensOwed0Position0).to.be.eq('166666666666667') - expect(tokensOwed0Position1).to.be.eq('333333333333334') - }) - - describe('works across large increases', () => { - beforeEach(async () => { - await mint(wallet.address, minTick, maxTick, expandTo18Decimals(1)) - }) - - // type(uint128).max * 2**128 / 1e18 - // https://www.wolframalpha.com/input/?i=%282**128+-+1%29+*+2**128+%2F+1e18 - const magicNumber = BigNumber.from('115792089237316195423570985008687907852929702298719625575994') - - it('works just before the cap binds', async () => { - await pool.setFeeGrowthGlobal0X128(magicNumber) - await pool.burn(minTick, maxTick, 0) - - const { tokensOwed0, tokensOwed1 } = await pool.positions(getPositionKey(wallet.address, minTick, maxTick)) - - expect(tokensOwed0).to.be.eq(MaxUint128.sub(1)) - expect(tokensOwed1).to.be.eq(0) - }) - - it('works just after the cap binds', async () => { - await pool.setFeeGrowthGlobal0X128(magicNumber.add(1)) - await pool.burn(minTick, maxTick, 0) - - const { tokensOwed0, tokensOwed1 } = await pool.positions(getPositionKey(wallet.address, minTick, maxTick)) - - expect(tokensOwed0).to.be.eq(MaxUint128) - expect(tokensOwed1).to.be.eq(0) - }) - - it('works well after the cap binds', async () => { - await pool.setFeeGrowthGlobal0X128(constants.MaxUint256) - await pool.burn(minTick, maxTick, 0) - - const { tokensOwed0, tokensOwed1 } = await pool.positions(getPositionKey(wallet.address, minTick, maxTick)) - - expect(tokensOwed0).to.be.eq(MaxUint128) - expect(tokensOwed1).to.be.eq(0) - }) - }) - - describe('works across overflow boundaries', () => { - beforeEach(async () => { - await pool.setFeeGrowthGlobal0X128(constants.MaxUint256) - await pool.setFeeGrowthGlobal1X128(constants.MaxUint256) - await mint(wallet.address, minTick, maxTick, expandTo18Decimals(10)) - }) - - it('token0', async () => { - await swapExact0For1(expandTo18Decimals(1), wallet.address) - await pool.burn(minTick, maxTick, 0) - const { amount0, amount1 } = await pool.callStatic.collect( - wallet.address, - minTick, - maxTick, - MaxUint128, - MaxUint128 - ) - expect(amount0).to.be.eq('499999999999999') - expect(amount1).to.be.eq(0) - }) - it('token1', async () => { - await swapExact1For0(expandTo18Decimals(1), wallet.address) - await pool.burn(minTick, maxTick, 0) - const { amount0, amount1 } = await pool.callStatic.collect( - wallet.address, - minTick, - maxTick, - MaxUint128, - MaxUint128 - ) - expect(amount0).to.be.eq(0) - expect(amount1).to.be.eq('499999999999999') - }) - it('token0 and token1', async () => { - await swapExact0For1(expandTo18Decimals(1), wallet.address) - await swapExact1For0(expandTo18Decimals(1), wallet.address) - await pool.burn(minTick, maxTick, 0) - const { amount0, amount1 } = await pool.callStatic.collect( - wallet.address, - minTick, - maxTick, - MaxUint128, - MaxUint128 - ) - expect(amount0).to.be.eq('499999999999999') - expect(amount1).to.be.eq('500000000000000') - }) - }) - }) - - describe('#feeProtocol', () => { - const liquidityAmount = expandTo18Decimals(1000) - - beforeEach(async () => { - pool = await createPool(FeeAmount.LOW, TICK_SPACINGS[FeeAmount.LOW]) - await pool.initialize(encodePriceSqrt(1, 1)) - await mint(wallet.address, minTick, maxTick, liquidityAmount) - }) - - it('is initially set to 0', async () => { - expect((await pool.slot0()).feeProtocol).to.eq(0) - }) - - it('can be changed by the owner', async () => { - await pool.setFeeProtocol(6, 6) - expect((await pool.slot0()).feeProtocol).to.eq(102) - }) - - it('cannot be changed out of bounds', async () => { - await expect(pool.setFeeProtocol(3, 3)).to.be.reverted - await expect(pool.setFeeProtocol(11, 11)).to.be.reverted - }) - - it('cannot be changed by addresses that are not owner', async () => { - await expect(pool.connect(other).setFeeProtocol(6, 6)).to.be.reverted - }) - - async function swapAndGetFeesOwed({ - amount, - zeroForOne, - poke, - }: { - amount: BigNumberish - zeroForOne: boolean - poke: boolean - }) { - await (zeroForOne ? swapExact0For1(amount, wallet.address) : swapExact1For0(amount, wallet.address)) - - if (poke) await pool.burn(minTick, maxTick, 0) - - const { amount0: fees0, amount1: fees1 } = await pool.callStatic.collect( - wallet.address, - minTick, - maxTick, - MaxUint128, - MaxUint128 - ) - - expect(fees0, 'fees owed in token0 are greater than 0').to.be.gte(0) - expect(fees1, 'fees owed in token1 are greater than 0').to.be.gte(0) - - return { token0Fees: fees0, token1Fees: fees1 } - } - - it('position owner gets full fees when protocol fee is off', async () => { - const { token0Fees, token1Fees } = await swapAndGetFeesOwed({ - amount: expandTo18Decimals(1), - zeroForOne: true, - poke: true, - }) - - // 6 bips * 1e18 - expect(token0Fees).to.eq('499999999999999') - expect(token1Fees).to.eq(0) - }) - - it('swap fees accumulate as expected (0 for 1)', async () => { - let token0Fees - let token1Fees - ;({ token0Fees, token1Fees } = await swapAndGetFeesOwed({ - amount: expandTo18Decimals(1), - zeroForOne: true, - poke: true, - })) - expect(token0Fees).to.eq('499999999999999') - expect(token1Fees).to.eq(0) - ;({ token0Fees, token1Fees } = await swapAndGetFeesOwed({ - amount: expandTo18Decimals(1), - zeroForOne: true, - poke: true, - })) - expect(token0Fees).to.eq('999999999999998') - expect(token1Fees).to.eq(0) - ;({ token0Fees, token1Fees } = await swapAndGetFeesOwed({ - amount: expandTo18Decimals(1), - zeroForOne: true, - poke: true, - })) - expect(token0Fees).to.eq('1499999999999997') - expect(token1Fees).to.eq(0) - }) - - it('swap fees accumulate as expected (1 for 0)', async () => { - let token0Fees - let token1Fees - ;({ token0Fees, token1Fees } = await swapAndGetFeesOwed({ - amount: expandTo18Decimals(1), - zeroForOne: false, - poke: true, - })) - expect(token0Fees).to.eq(0) - expect(token1Fees).to.eq('499999999999999') - ;({ token0Fees, token1Fees } = await swapAndGetFeesOwed({ - amount: expandTo18Decimals(1), - zeroForOne: false, - poke: true, - })) - expect(token0Fees).to.eq(0) - expect(token1Fees).to.eq('999999999999998') - ;({ token0Fees, token1Fees } = await swapAndGetFeesOwed({ - amount: expandTo18Decimals(1), - zeroForOne: false, - poke: true, - })) - expect(token0Fees).to.eq(0) - expect(token1Fees).to.eq('1499999999999997') - }) - - it('position owner gets partial fees when protocol fee is on', async () => { - await pool.setFeeProtocol(6, 6) - - const { token0Fees, token1Fees } = await swapAndGetFeesOwed({ - amount: expandTo18Decimals(1), - zeroForOne: true, - poke: true, - }) - - expect(token0Fees).to.be.eq('416666666666666') - expect(token1Fees).to.be.eq(0) - }) - - describe('#collectProtocol', () => { - it('returns 0 if no fees', async () => { - await pool.setFeeProtocol(6, 6) - const { amount0, amount1 } = await pool.callStatic.collectProtocol(wallet.address, MaxUint128, MaxUint128) - expect(amount0).to.be.eq(0) - expect(amount1).to.be.eq(0) - }) - - it('can collect fees', async () => { - await pool.setFeeProtocol(6, 6) - - await swapAndGetFeesOwed({ - amount: expandTo18Decimals(1), - zeroForOne: true, - poke: true, - }) - - await expect(pool.collectProtocol(other.address, MaxUint128, MaxUint128)) - .to.emit(token0, 'Transfer') - .withArgs(pool.address, other.address, '83333333333332') - }) - - it('fees collected can differ between token0 and token1', async () => { - await pool.setFeeProtocol(8, 5) - - await swapAndGetFeesOwed({ - amount: expandTo18Decimals(1), - zeroForOne: true, - poke: false, - }) - await swapAndGetFeesOwed({ - amount: expandTo18Decimals(1), - zeroForOne: false, - poke: false, - }) - - await expect(pool.collectProtocol(other.address, MaxUint128, MaxUint128)) - .to.emit(token0, 'Transfer') - // more token0 fees because it's 1/5th the swap fees - .withArgs(pool.address, other.address, '62499999999999') - .to.emit(token1, 'Transfer') - // less token1 fees because it's 1/8th the swap fees - .withArgs(pool.address, other.address, '99999999999998') - }) - }) - - it('fees collected by lp after two swaps should be double one swap', async () => { - await swapAndGetFeesOwed({ - amount: expandTo18Decimals(1), - zeroForOne: true, - poke: true, - }) - const { token0Fees, token1Fees } = await swapAndGetFeesOwed({ - amount: expandTo18Decimals(1), - zeroForOne: true, - poke: true, - }) - - // 6 bips * 2e18 - expect(token0Fees).to.eq('999999999999998') - expect(token1Fees).to.eq(0) - }) - - it('fees collected after two swaps with fee turned on in middle are fees from last swap (not confiscatory)', async () => { - await swapAndGetFeesOwed({ - amount: expandTo18Decimals(1), - zeroForOne: true, - poke: false, - }) - - await pool.setFeeProtocol(6, 6) - - const { token0Fees, token1Fees } = await swapAndGetFeesOwed({ - amount: expandTo18Decimals(1), - zeroForOne: true, - poke: true, - }) - - expect(token0Fees).to.eq('916666666666666') - expect(token1Fees).to.eq(0) - }) - - it('fees collected by lp after two swaps with intermediate withdrawal', async () => { - await pool.setFeeProtocol(6, 6) - - const { token0Fees, token1Fees } = await swapAndGetFeesOwed({ - amount: expandTo18Decimals(1), - zeroForOne: true, - poke: true, - }) - - expect(token0Fees).to.eq('416666666666666') - expect(token1Fees).to.eq(0) - - // collect the fees - await pool.collect(wallet.address, minTick, maxTick, MaxUint128, MaxUint128) - - const { token0Fees: token0FeesNext, token1Fees: token1FeesNext } = await swapAndGetFeesOwed({ - amount: expandTo18Decimals(1), - zeroForOne: true, - poke: false, - }) - - expect(token0FeesNext).to.eq(0) - expect(token1FeesNext).to.eq(0) - - let { token0: token0ProtocolFees, token1: token1ProtocolFees } = await pool.protocolFees() - expect(token0ProtocolFees).to.eq('166666666666666') - expect(token1ProtocolFees).to.eq(0) - - await pool.burn(minTick, maxTick, 0) // poke to update fees - await expect(pool.collect(wallet.address, minTick, maxTick, MaxUint128, MaxUint128)) - .to.emit(token0, 'Transfer') - .withArgs(pool.address, wallet.address, '416666666666666') - ;({ token0: token0ProtocolFees, token1: token1ProtocolFees } = await pool.protocolFees()) - expect(token0ProtocolFees).to.eq('166666666666666') - expect(token1ProtocolFees).to.eq(0) - }) - }) - - describe('#tickSpacing', () => { - describe('tickSpacing = 12', () => { - beforeEach('deploy pool', async () => { - pool = await createPool(FeeAmount.MEDIUM, 12) - }) - describe('post initialize', () => { - beforeEach('initialize pool', async () => { - await pool.initialize(encodePriceSqrt(1, 1)) - }) - it('mint can only be called for multiples of 12', async () => { - await expect(mint(wallet.address, -6, 0, 1)).to.be.reverted - await expect(mint(wallet.address, 0, 6, 1)).to.be.reverted - }) - it('mint can be called with multiples of 12', async () => { - await mint(wallet.address, 12, 24, 1) - await mint(wallet.address, -144, -120, 1) - }) - it('swapping across gaps works in 1 for 0 direction', async () => { - const liquidityAmount = expandTo18Decimals(1).div(4) - await mint(wallet.address, 120000, 121200, liquidityAmount) - await swapExact1For0(expandTo18Decimals(1), wallet.address) - await expect(pool.burn(120000, 121200, liquidityAmount)) - .to.emit(pool, 'Burn') - .withArgs(wallet.address, 120000, 121200, liquidityAmount, '30027458295511', '996999999999999999') - .to.not.emit(token0, 'Transfer') - .to.not.emit(token1, 'Transfer') - expect((await pool.slot0()).tick).to.eq(120196) - }) - it('swapping across gaps works in 0 for 1 direction', async () => { - const liquidityAmount = expandTo18Decimals(1).div(4) - await mint(wallet.address, -121200, -120000, liquidityAmount) - await swapExact0For1(expandTo18Decimals(1), wallet.address) - await expect(pool.burn(-121200, -120000, liquidityAmount)) - .to.emit(pool, 'Burn') - .withArgs(wallet.address, -121200, -120000, liquidityAmount, '996999999999999999', '30027458295511') - .to.not.emit(token0, 'Transfer') - .to.not.emit(token1, 'Transfer') - expect((await pool.slot0()).tick).to.eq(-120197) - }) - }) - }) - }) - - // https://github.com/Uniswap/uniswap-v3-core/issues/214 - it('tick transition cannot run twice if zero for one swap ends at fractional price just below tick', async () => { - pool = await createPool(FeeAmount.MEDIUM, 1) - const sqrtTickMath = (await (await ethers.getContractFactory('TickMathTest')).deploy()) as TickMathTest - const swapMath = (await (await ethers.getContractFactory('SwapMathTest')).deploy()) as SwapMathTest - const p0 = (await sqrtTickMath.getSqrtRatioAtTick(-24081)).add(1) - // initialize at a price of ~0.3 token1/token0 - // meaning if you swap in 2 token0, you should end up getting 0 token1 - await pool.initialize(p0) - expect(await pool.liquidity(), 'current pool liquidity is 1').to.eq(0) - expect((await pool.slot0()).tick, 'pool tick is -24081').to.eq(-24081) - - // add a bunch of liquidity around current price - const liquidity = expandTo18Decimals(1000) - await mint(wallet.address, -24082, -24080, liquidity) - expect(await pool.liquidity(), 'current pool liquidity is now liquidity + 1').to.eq(liquidity) - - await mint(wallet.address, -24082, -24081, liquidity) - expect(await pool.liquidity(), 'current pool liquidity is still liquidity + 1').to.eq(liquidity) - - // check the math works out to moving the price down 1, sending no amount out, and having some amount remaining - { - const { feeAmount, amountIn, amountOut, sqrtQ } = await swapMath.computeSwapStep( - p0, - p0.sub(1), - liquidity, - 3, - FeeAmount.MEDIUM - ) - expect(sqrtQ, 'price moves').to.eq(p0.sub(1)) - expect(feeAmount, 'fee amount is 1').to.eq(1) - expect(amountIn, 'amount in is 1').to.eq(1) - expect(amountOut, 'zero amount out').to.eq(0) - } - - // swap 2 amount in, should get 0 amount out - await expect(swapExact0For1(3, wallet.address)) - .to.emit(token0, 'Transfer') - .withArgs(wallet.address, pool.address, 3) - .to.not.emit(token1, 'Transfer') - - const { tick, sqrtPriceX96 } = await pool.slot0() - - expect(tick, 'pool is at the next tick').to.eq(-24082) - expect(sqrtPriceX96, 'pool price is still on the p0 boundary').to.eq(p0.sub(1)) - expect(await pool.liquidity(), 'pool has run tick transition and liquidity changed').to.eq(liquidity.mul(2)) - }) - - describe('#flash', () => { - it('fails if not initialized', async () => { - await expect(flash(100, 200, other.address)).to.be.reverted - await expect(flash(100, 0, other.address)).to.be.reverted - await expect(flash(0, 200, other.address)).to.be.reverted - }) - it('fails if no liquidity', async () => { - await pool.initialize(encodePriceSqrt(1, 1)) - await expect(flash(100, 200, other.address)).to.be.revertedWith('L') - await expect(flash(100, 0, other.address)).to.be.revertedWith('L') - await expect(flash(0, 200, other.address)).to.be.revertedWith('L') - }) - describe('after liquidity added', () => { - let balance0: BigNumber - let balance1: BigNumber - beforeEach('add some tokens', async () => { - await initializeAtZeroTick(pool) - ;[balance0, balance1] = await Promise.all([token0.balanceOf(pool.address), token1.balanceOf(pool.address)]) - }) - - describe('fee off', () => { - it('emits an event', async () => { - await expect(flash(1001, 2001, other.address)) - .to.emit(pool, 'Flash') - .withArgs(swapTarget.address, other.address, 1001, 2001, 4, 7) - }) - - it('transfers the amount0 to the recipient', async () => { - await expect(flash(100, 200, other.address)) - .to.emit(token0, 'Transfer') - .withArgs(pool.address, other.address, 100) - }) - it('transfers the amount1 to the recipient', async () => { - await expect(flash(100, 200, other.address)) - .to.emit(token1, 'Transfer') - .withArgs(pool.address, other.address, 200) - }) - it('can flash only token0', async () => { - await expect(flash(101, 0, other.address)) - .to.emit(token0, 'Transfer') - .withArgs(pool.address, other.address, 101) - .to.not.emit(token1, 'Transfer') - }) - it('can flash only token1', async () => { - await expect(flash(0, 102, other.address)) - .to.emit(token1, 'Transfer') - .withArgs(pool.address, other.address, 102) - .to.not.emit(token0, 'Transfer') - }) - it('can flash entire token balance', async () => { - await expect(flash(balance0, balance1, other.address)) - .to.emit(token0, 'Transfer') - .withArgs(pool.address, other.address, balance0) - .to.emit(token1, 'Transfer') - .withArgs(pool.address, other.address, balance1) - }) - it('no-op if both amounts are 0', async () => { - await expect(flash(0, 0, other.address)).to.not.emit(token0, 'Transfer').to.not.emit(token1, 'Transfer') - }) - it('fails if flash amount is greater than token balance', async () => { - await expect(flash(balance0.add(1), balance1, other.address)).to.be.reverted - await expect(flash(balance0, balance1.add(1), other.address)).to.be.reverted - }) - it('calls the flash callback on the sender with correct fee amounts', async () => { - await expect(flash(1001, 2002, other.address)).to.emit(swapTarget, 'FlashCallback').withArgs(4, 7) - }) - it('increases the fee growth by the expected amount', async () => { - await flash(1001, 2002, other.address) - expect(await pool.feeGrowthGlobal0X128()).to.eq( - BigNumber.from(4).mul(BigNumber.from(2).pow(128)).div(expandTo18Decimals(2)) - ) - expect(await pool.feeGrowthGlobal1X128()).to.eq( - BigNumber.from(7).mul(BigNumber.from(2).pow(128)).div(expandTo18Decimals(2)) - ) - }) - it('fails if original balance not returned in either token', async () => { - await expect(flash(1000, 0, other.address, 999, 0)).to.be.reverted - await expect(flash(0, 1000, other.address, 0, 999)).to.be.reverted - }) - it('fails if underpays either token', async () => { - await expect(flash(1000, 0, other.address, 1002, 0)).to.be.reverted - await expect(flash(0, 1000, other.address, 0, 1002)).to.be.reverted - }) - it('allows donating token0', async () => { - await expect(flash(0, 0, constants.AddressZero, 567, 0)) - .to.emit(token0, 'Transfer') - .withArgs(wallet.address, pool.address, 567) - .to.not.emit(token1, 'Transfer') - expect(await pool.feeGrowthGlobal0X128()).to.eq( - BigNumber.from(567).mul(BigNumber.from(2).pow(128)).div(expandTo18Decimals(2)) - ) - }) - it('allows donating token1', async () => { - await expect(flash(0, 0, constants.AddressZero, 0, 678)) - .to.emit(token1, 'Transfer') - .withArgs(wallet.address, pool.address, 678) - .to.not.emit(token0, 'Transfer') - expect(await pool.feeGrowthGlobal1X128()).to.eq( - BigNumber.from(678).mul(BigNumber.from(2).pow(128)).div(expandTo18Decimals(2)) - ) - }) - it('allows donating token0 and token1 together', async () => { - await expect(flash(0, 0, constants.AddressZero, 789, 1234)) - .to.emit(token0, 'Transfer') - .withArgs(wallet.address, pool.address, 789) - .to.emit(token1, 'Transfer') - .withArgs(wallet.address, pool.address, 1234) - - expect(await pool.feeGrowthGlobal0X128()).to.eq( - BigNumber.from(789).mul(BigNumber.from(2).pow(128)).div(expandTo18Decimals(2)) - ) - expect(await pool.feeGrowthGlobal1X128()).to.eq( - BigNumber.from(1234).mul(BigNumber.from(2).pow(128)).div(expandTo18Decimals(2)) - ) - }) - }) - - describe('fee on', () => { - beforeEach('turn protocol fee on', async () => { - await pool.setFeeProtocol(6, 6) - }) - - it('emits an event', async () => { - await expect(flash(1001, 2001, other.address)) - .to.emit(pool, 'Flash') - .withArgs(swapTarget.address, other.address, 1001, 2001, 4, 7) - }) - - it('increases the fee growth by the expected amount', async () => { - await flash(2002, 4004, other.address) - - const { token0: token0ProtocolFees, token1: token1ProtocolFees } = await pool.protocolFees() - expect(token0ProtocolFees).to.eq(1) - expect(token1ProtocolFees).to.eq(2) - - expect(await pool.feeGrowthGlobal0X128()).to.eq( - BigNumber.from(6).mul(BigNumber.from(2).pow(128)).div(expandTo18Decimals(2)) - ) - expect(await pool.feeGrowthGlobal1X128()).to.eq( - BigNumber.from(11).mul(BigNumber.from(2).pow(128)).div(expandTo18Decimals(2)) - ) - }) - it('allows donating token0', async () => { - await expect(flash(0, 0, constants.AddressZero, 567, 0)) - .to.emit(token0, 'Transfer') - .withArgs(wallet.address, pool.address, 567) - .to.not.emit(token1, 'Transfer') - - const { token0: token0ProtocolFees } = await pool.protocolFees() - expect(token0ProtocolFees).to.eq(94) - - expect(await pool.feeGrowthGlobal0X128()).to.eq( - BigNumber.from(473).mul(BigNumber.from(2).pow(128)).div(expandTo18Decimals(2)) - ) - }) - it('allows donating token1', async () => { - await expect(flash(0, 0, constants.AddressZero, 0, 678)) - .to.emit(token1, 'Transfer') - .withArgs(wallet.address, pool.address, 678) - .to.not.emit(token0, 'Transfer') - - const { token1: token1ProtocolFees } = await pool.protocolFees() - expect(token1ProtocolFees).to.eq(113) - - expect(await pool.feeGrowthGlobal1X128()).to.eq( - BigNumber.from(565).mul(BigNumber.from(2).pow(128)).div(expandTo18Decimals(2)) - ) - }) - it('allows donating token0 and token1 together', async () => { - await expect(flash(0, 0, constants.AddressZero, 789, 1234)) - .to.emit(token0, 'Transfer') - .withArgs(wallet.address, pool.address, 789) - .to.emit(token1, 'Transfer') - .withArgs(wallet.address, pool.address, 1234) - - const { token0: token0ProtocolFees, token1: token1ProtocolFees } = await pool.protocolFees() - expect(token0ProtocolFees).to.eq(131) - expect(token1ProtocolFees).to.eq(205) - - expect(await pool.feeGrowthGlobal0X128()).to.eq( - BigNumber.from(658).mul(BigNumber.from(2).pow(128)).div(expandTo18Decimals(2)) - ) - expect(await pool.feeGrowthGlobal1X128()).to.eq( - BigNumber.from(1029).mul(BigNumber.from(2).pow(128)).div(expandTo18Decimals(2)) - ) - }) - }) - }) - }) - - describe('#increaseObservationCardinalityNext', () => { - it('cannot be called before initialization', async () => { - await expect(pool.increaseObservationCardinalityNext(2)).to.be.reverted - }) - describe('after initialization', () => { - beforeEach('initialize the pool', () => pool.initialize(encodePriceSqrt(1, 1))) - it('oracle starting state after initialization', async () => { - const { observationCardinality, observationIndex, observationCardinalityNext } = await pool.slot0() - expect(observationCardinality).to.eq(1) - expect(observationIndex).to.eq(0) - expect(observationCardinalityNext).to.eq(1) - const { - secondsPerLiquidityCumulativeX128, - tickCumulative, - initialized, - blockTimestamp, - } = await pool.observations(0) - expect(secondsPerLiquidityCumulativeX128).to.eq(0) - expect(tickCumulative).to.eq(0) - expect(initialized).to.eq(true) - expect(blockTimestamp).to.eq(TEST_POOL_START_TIME) - }) - it('increases observation cardinality next', async () => { - await pool.increaseObservationCardinalityNext(2) - const { observationCardinality, observationIndex, observationCardinalityNext } = await pool.slot0() - expect(observationCardinality).to.eq(1) - expect(observationIndex).to.eq(0) - expect(observationCardinalityNext).to.eq(2) - }) - it('is no op if target is already exceeded', async () => { - await pool.increaseObservationCardinalityNext(5) - await pool.increaseObservationCardinalityNext(3) - const { observationCardinality, observationIndex, observationCardinalityNext } = await pool.slot0() - expect(observationCardinality).to.eq(1) - expect(observationIndex).to.eq(0) - expect(observationCardinalityNext).to.eq(5) - }) - }) - }) - - describe('#setFeeProtocol', () => { - beforeEach('initialize the pool', async () => { - await pool.initialize(encodePriceSqrt(1, 1)) - }) - - it('can only be called by factory owner', async () => { - await expect(pool.connect(other).setFeeProtocol(5, 5)).to.be.reverted - }) - it('fails if fee is lt 4 or gt 10', async () => { - await expect(pool.setFeeProtocol(3, 3)).to.be.reverted - await expect(pool.setFeeProtocol(6, 3)).to.be.reverted - await expect(pool.setFeeProtocol(3, 6)).to.be.reverted - await expect(pool.setFeeProtocol(11, 11)).to.be.reverted - await expect(pool.setFeeProtocol(6, 11)).to.be.reverted - await expect(pool.setFeeProtocol(11, 6)).to.be.reverted - }) - it('succeeds for fee of 4', async () => { - await pool.setFeeProtocol(4, 4) - }) - it('succeeds for fee of 10', async () => { - await pool.setFeeProtocol(10, 10) - }) - it('sets protocol fee', async () => { - await pool.setFeeProtocol(7, 7) - expect((await pool.slot0()).feeProtocol).to.eq(119) - }) - it('can change protocol fee', async () => { - await pool.setFeeProtocol(7, 7) - await pool.setFeeProtocol(5, 8) - expect((await pool.slot0()).feeProtocol).to.eq(133) - }) - it('can turn off protocol fee', async () => { - await pool.setFeeProtocol(4, 4) - await pool.setFeeProtocol(0, 0) - expect((await pool.slot0()).feeProtocol).to.eq(0) - }) - it('emits an event when turned on', async () => { - await expect(pool.setFeeProtocol(7, 7)).to.be.emit(pool, 'SetFeeProtocol').withArgs(0, 0, 7, 7) - }) - it('emits an event when turned off', async () => { - await pool.setFeeProtocol(7, 5) - await expect(pool.setFeeProtocol(0, 0)).to.be.emit(pool, 'SetFeeProtocol').withArgs(7, 5, 0, 0) - }) - it('emits an event when changed', async () => { - await pool.setFeeProtocol(4, 10) - await expect(pool.setFeeProtocol(6, 8)).to.be.emit(pool, 'SetFeeProtocol').withArgs(4, 10, 6, 8) - }) - it('emits an event when unchanged', async () => { - await pool.setFeeProtocol(5, 9) - await expect(pool.setFeeProtocol(5, 9)).to.be.emit(pool, 'SetFeeProtocol').withArgs(5, 9, 5, 9) - }) - }) - - describe('#lock', () => { - beforeEach('initialize the pool', async () => { - await pool.initialize(encodePriceSqrt(1, 1)) - await mint(wallet.address, minTick, maxTick, expandTo18Decimals(1)) - }) - - it('cannot reenter from swap callback', async () => { - const reentrant = (await ( - await ethers.getContractFactory('TestUniswapV3ReentrantCallee') - ).deploy()) as TestUniswapV3ReentrantCallee - - // the tests happen in solidity - await expect(reentrant.swapToReenter(pool.address)).to.be.revertedWith('Unable to reenter') - }) - }) - - describe('#snapshotCumulativesInside', () => { - const tickLower = -TICK_SPACINGS[FeeAmount.MEDIUM] - const tickUpper = TICK_SPACINGS[FeeAmount.MEDIUM] - const tickSpacing = TICK_SPACINGS[FeeAmount.MEDIUM] - beforeEach(async () => { - await pool.initialize(encodePriceSqrt(1, 1)) - await mint(wallet.address, tickLower, tickUpper, 10) - }) - it('throws if ticks are in reverse order', async () => { - await expect(pool.snapshotCumulativesInside(tickUpper, tickLower)).to.be.reverted - }) - it('throws if ticks are the same', async () => { - await expect(pool.snapshotCumulativesInside(tickUpper, tickUpper)).to.be.reverted - }) - it('throws if tick lower is too low', async () => { - await expect(pool.snapshotCumulativesInside(getMinTick(tickSpacing) - 1, tickUpper)).be.reverted - }) - it('throws if tick upper is too high', async () => { - await expect(pool.snapshotCumulativesInside(tickLower, getMaxTick(tickSpacing) + 1)).be.reverted - }) - it('throws if tick lower is not initialized', async () => { - await expect(pool.snapshotCumulativesInside(tickLower - tickSpacing, tickUpper)).to.be.reverted - }) - it('throws if tick upper is not initialized', async () => { - await expect(pool.snapshotCumulativesInside(tickLower, tickUpper + tickSpacing)).to.be.reverted - }) - it('is zero immediately after initialize', async () => { - const { - secondsPerLiquidityInsideX128, - tickCumulativeInside, - secondsInside, - } = await pool.snapshotCumulativesInside(tickLower, tickUpper) - expect(secondsPerLiquidityInsideX128).to.eq(0) - expect(tickCumulativeInside).to.eq(0) - expect(secondsInside).to.eq(0) - }) - it('increases by expected amount when time elapses in the range', async () => { - await pool.advanceTime(5) - const { - secondsPerLiquidityInsideX128, - tickCumulativeInside, - secondsInside, - } = await pool.snapshotCumulativesInside(tickLower, tickUpper) - expect(secondsPerLiquidityInsideX128).to.eq(BigNumber.from(5).shl(128).div(10)) - expect(tickCumulativeInside, 'tickCumulativeInside').to.eq(0) - expect(secondsInside).to.eq(5) - }) - it('does not account for time increase above range', async () => { - await pool.advanceTime(5) - await swapToHigherPrice(encodePriceSqrt(2, 1), wallet.address) - await pool.advanceTime(7) - const { - secondsPerLiquidityInsideX128, - tickCumulativeInside, - secondsInside, - } = await pool.snapshotCumulativesInside(tickLower, tickUpper) - expect(secondsPerLiquidityInsideX128).to.eq(BigNumber.from(5).shl(128).div(10)) - expect(tickCumulativeInside, 'tickCumulativeInside').to.eq(0) - expect(secondsInside).to.eq(5) - }) - it('does not account for time increase below range', async () => { - await pool.advanceTime(5) - await swapToLowerPrice(encodePriceSqrt(1, 2), wallet.address) - await pool.advanceTime(7) - const { - secondsPerLiquidityInsideX128, - tickCumulativeInside, - secondsInside, - } = await pool.snapshotCumulativesInside(tickLower, tickUpper) - expect(secondsPerLiquidityInsideX128).to.eq(BigNumber.from(5).shl(128).div(10)) - // tick is 0 for 5 seconds, then not in range - expect(tickCumulativeInside, 'tickCumulativeInside').to.eq(0) - expect(secondsInside).to.eq(5) - }) - it('time increase below range is not counted', async () => { - await swapToLowerPrice(encodePriceSqrt(1, 2), wallet.address) - await pool.advanceTime(5) - await swapToHigherPrice(encodePriceSqrt(1, 1), wallet.address) - await pool.advanceTime(7) - const { - secondsPerLiquidityInsideX128, - tickCumulativeInside, - secondsInside, - } = await pool.snapshotCumulativesInside(tickLower, tickUpper) - expect(secondsPerLiquidityInsideX128).to.eq(BigNumber.from(7).shl(128).div(10)) - // tick is not in range then tick is 0 for 7 seconds - expect(tickCumulativeInside, 'tickCumulativeInside').to.eq(0) - expect(secondsInside).to.eq(7) - }) - it('time increase above range is not counted', async () => { - await swapToHigherPrice(encodePriceSqrt(2, 1), wallet.address) - await pool.advanceTime(5) - await swapToLowerPrice(encodePriceSqrt(1, 1), wallet.address) - await pool.advanceTime(7) - const { - secondsPerLiquidityInsideX128, - tickCumulativeInside, - secondsInside, - } = await pool.snapshotCumulativesInside(tickLower, tickUpper) - expect(secondsPerLiquidityInsideX128).to.eq(BigNumber.from(7).shl(128).div(10)) - expect((await pool.slot0()).tick).to.eq(-1) // justify the -7 tick cumulative inside value - expect(tickCumulativeInside, 'tickCumulativeInside').to.eq(-7) - expect(secondsInside).to.eq(7) - }) - it('positions minted after time spent', async () => { - await pool.advanceTime(5) - await mint(wallet.address, tickUpper, getMaxTick(tickSpacing), 15) - await swapToHigherPrice(encodePriceSqrt(2, 1), wallet.address) - await pool.advanceTime(8) - const { - secondsPerLiquidityInsideX128, - tickCumulativeInside, - secondsInside, - } = await pool.snapshotCumulativesInside(tickUpper, getMaxTick(tickSpacing)) - expect(secondsPerLiquidityInsideX128).to.eq(BigNumber.from(8).shl(128).div(15)) - // the tick of 2/1 is 6931 - // 8 seconds * 6931 = 55448 - expect(tickCumulativeInside, 'tickCumulativeInside').to.eq(55448) - expect(secondsInside).to.eq(8) - }) - it('overlapping liquidity is aggregated', async () => { - await mint(wallet.address, tickLower, getMaxTick(tickSpacing), 15) - await pool.advanceTime(5) - await swapToHigherPrice(encodePriceSqrt(2, 1), wallet.address) - await pool.advanceTime(8) - const { - secondsPerLiquidityInsideX128, - tickCumulativeInside, - secondsInside, - } = await pool.snapshotCumulativesInside(tickLower, tickUpper) - expect(secondsPerLiquidityInsideX128).to.eq(BigNumber.from(5).shl(128).div(25)) - expect(tickCumulativeInside, 'tickCumulativeInside').to.eq(0) - expect(secondsInside).to.eq(5) - }) - it('relative behavior of snapshots', async () => { - await pool.advanceTime(5) - await mint(wallet.address, getMinTick(tickSpacing), tickLower, 15) - const { - secondsPerLiquidityInsideX128: secondsPerLiquidityInsideX128Start, - tickCumulativeInside: tickCumulativeInsideStart, - secondsInside: secondsInsideStart, - } = await pool.snapshotCumulativesInside(getMinTick(tickSpacing), tickLower) - await pool.advanceTime(8) - // 13 seconds in starting range, then 3 seconds in newly minted range - await swapToLowerPrice(encodePriceSqrt(1, 2), wallet.address) - await pool.advanceTime(3) - const { - secondsPerLiquidityInsideX128, - tickCumulativeInside, - secondsInside, - } = await pool.snapshotCumulativesInside(getMinTick(tickSpacing), tickLower) - const expectedDiffSecondsPerLiquidity = BigNumber.from(3).shl(128).div(15) - expect(secondsPerLiquidityInsideX128.sub(secondsPerLiquidityInsideX128Start)).to.eq( - expectedDiffSecondsPerLiquidity - ) - expect(secondsPerLiquidityInsideX128).to.not.eq(expectedDiffSecondsPerLiquidity) - // the tick is the one corresponding to the price of 1/2, or log base 1.0001 of 0.5 - // this is -6932, and 3 seconds have passed, so the cumulative computed from the diff equals 6932 * 3 - expect(tickCumulativeInside.sub(tickCumulativeInsideStart), 'tickCumulativeInside').to.eq(-20796) - expect(secondsInside - secondsInsideStart).to.eq(3) - expect(secondsInside).to.not.eq(3) - }) - }) - - describe('fees overflow scenarios', async () => { - it('up to max uint 128', async () => { - await pool.initialize(encodePriceSqrt(1, 1)) - await mint(wallet.address, minTick, maxTick, 1) - await flash(0, 0, wallet.address, MaxUint128, MaxUint128) - - const [feeGrowthGlobal0X128, feeGrowthGlobal1X128] = await Promise.all([ - pool.feeGrowthGlobal0X128(), - pool.feeGrowthGlobal1X128(), - ]) - // all 1s in first 128 bits - expect(feeGrowthGlobal0X128).to.eq(MaxUint128.shl(128)) - expect(feeGrowthGlobal1X128).to.eq(MaxUint128.shl(128)) - await pool.burn(minTick, maxTick, 0) - const { amount0, amount1 } = await pool.callStatic.collect( - wallet.address, - minTick, - maxTick, - MaxUint128, - MaxUint128 - ) - expect(amount0).to.eq(MaxUint128) - expect(amount1).to.eq(MaxUint128) - }) - - it('overflow max uint 128', async () => { - await pool.initialize(encodePriceSqrt(1, 1)) - await mint(wallet.address, minTick, maxTick, 1) - await flash(0, 0, wallet.address, MaxUint128, MaxUint128) - await flash(0, 0, wallet.address, 1, 1) - - const [feeGrowthGlobal0X128, feeGrowthGlobal1X128] = await Promise.all([ - pool.feeGrowthGlobal0X128(), - pool.feeGrowthGlobal1X128(), - ]) - // all 1s in first 128 bits - expect(feeGrowthGlobal0X128).to.eq(0) - expect(feeGrowthGlobal1X128).to.eq(0) - await pool.burn(minTick, maxTick, 0) - const { amount0, amount1 } = await pool.callStatic.collect( - wallet.address, - minTick, - maxTick, - MaxUint128, - MaxUint128 - ) - // fees burned - expect(amount0).to.eq(0) - expect(amount1).to.eq(0) - }) - - it('overflow max uint 128 after poke burns fees owed to 0', async () => { - await pool.initialize(encodePriceSqrt(1, 1)) - await mint(wallet.address, minTick, maxTick, 1) - await flash(0, 0, wallet.address, MaxUint128, MaxUint128) - await pool.burn(minTick, maxTick, 0) - await flash(0, 0, wallet.address, 1, 1) - await pool.burn(minTick, maxTick, 0) - - const { amount0, amount1 } = await pool.callStatic.collect( - wallet.address, - minTick, - maxTick, - MaxUint128, - MaxUint128 - ) - // fees burned - expect(amount0).to.eq(0) - expect(amount1).to.eq(0) - }) - - it('two positions at the same snapshot', async () => { - await pool.initialize(encodePriceSqrt(1, 1)) - await mint(wallet.address, minTick, maxTick, 1) - await mint(other.address, minTick, maxTick, 1) - await flash(0, 0, wallet.address, MaxUint128, 0) - await flash(0, 0, wallet.address, MaxUint128, 0) - const feeGrowthGlobal0X128 = await pool.feeGrowthGlobal0X128() - expect(feeGrowthGlobal0X128).to.eq(MaxUint128.shl(128)) - await flash(0, 0, wallet.address, 2, 0) - await pool.burn(minTick, maxTick, 0) - await pool.connect(other).burn(minTick, maxTick, 0) - let { amount0 } = await pool.callStatic.collect(wallet.address, minTick, maxTick, MaxUint128, MaxUint128) - expect(amount0, 'amount0 of wallet').to.eq(0) - ;({ amount0 } = await pool - .connect(other) - .callStatic.collect(other.address, minTick, maxTick, MaxUint128, MaxUint128)) - expect(amount0, 'amount0 of other').to.eq(0) - }) - - it('two positions 1 wei of fees apart overflows exactly once', async () => { - await pool.initialize(encodePriceSqrt(1, 1)) - await mint(wallet.address, minTick, maxTick, 1) - await flash(0, 0, wallet.address, 1, 0) - await mint(other.address, minTick, maxTick, 1) - await flash(0, 0, wallet.address, MaxUint128, 0) - await flash(0, 0, wallet.address, MaxUint128, 0) - const feeGrowthGlobal0X128 = await pool.feeGrowthGlobal0X128() - expect(feeGrowthGlobal0X128).to.eq(0) - await flash(0, 0, wallet.address, 2, 0) - await pool.burn(minTick, maxTick, 0) - await pool.connect(other).burn(minTick, maxTick, 0) - let { amount0 } = await pool.callStatic.collect(wallet.address, minTick, maxTick, MaxUint128, MaxUint128) - expect(amount0, 'amount0 of wallet').to.eq(1) - ;({ amount0 } = await pool - .connect(other) - .callStatic.collect(other.address, minTick, maxTick, MaxUint128, MaxUint128)) - expect(amount0, 'amount0 of other').to.eq(0) - }) - }) - - describe('swap underpayment tests', () => { - let underpay: TestUniswapV3SwapPay - beforeEach('deploy swap test', async () => { - const underpayFactory = await ethers.getContractFactory('TestUniswapV3SwapPay') - underpay = (await underpayFactory.deploy()) as TestUniswapV3SwapPay - await token0.approve(underpay.address, constants.MaxUint256) - await token1.approve(underpay.address, constants.MaxUint256) - await pool.initialize(encodePriceSqrt(1, 1)) - await mint(wallet.address, minTick, maxTick, expandTo18Decimals(1)) - }) - - it('underpay zero for one and exact in', async () => { - await expect( - underpay.swap(pool.address, wallet.address, true, MIN_SQRT_RATIO.add(1), 1000, 1, 0) - ).to.be.revertedWith('IIA') - }) - it('pay in the wrong token zero for one and exact in', async () => { - await expect( - underpay.swap(pool.address, wallet.address, true, MIN_SQRT_RATIO.add(1), 1000, 0, 2000) - ).to.be.revertedWith('IIA') - }) - it('overpay zero for one and exact in', async () => { - await expect( - underpay.swap(pool.address, wallet.address, true, MIN_SQRT_RATIO.add(1), 1000, 2000, 0) - ).to.not.be.revertedWith('IIA') - }) - it('underpay zero for one and exact out', async () => { - await expect( - underpay.swap(pool.address, wallet.address, true, MIN_SQRT_RATIO.add(1), -1000, 1, 0) - ).to.be.revertedWith('IIA') - }) - it('pay in the wrong token zero for one and exact out', async () => { - await expect( - underpay.swap(pool.address, wallet.address, true, MIN_SQRT_RATIO.add(1), -1000, 0, 2000) - ).to.be.revertedWith('IIA') - }) - it('overpay zero for one and exact out', async () => { - await expect( - underpay.swap(pool.address, wallet.address, true, MIN_SQRT_RATIO.add(1), -1000, 2000, 0) - ).to.not.be.revertedWith('IIA') - }) - it('underpay one for zero and exact in', async () => { - await expect( - underpay.swap(pool.address, wallet.address, false, MAX_SQRT_RATIO.sub(1), 1000, 0, 1) - ).to.be.revertedWith('IIA') - }) - it('pay in the wrong token one for zero and exact in', async () => { - await expect( - underpay.swap(pool.address, wallet.address, false, MAX_SQRT_RATIO.sub(1), 1000, 2000, 0) - ).to.be.revertedWith('IIA') - }) - it('overpay one for zero and exact in', async () => { - await expect( - underpay.swap(pool.address, wallet.address, false, MAX_SQRT_RATIO.sub(1), 1000, 0, 2000) - ).to.not.be.revertedWith('IIA') - }) - it('underpay one for zero and exact out', async () => { - await expect( - underpay.swap(pool.address, wallet.address, false, MAX_SQRT_RATIO.sub(1), -1000, 0, 1) - ).to.be.revertedWith('IIA') - }) - it('pay in the wrong token one for zero and exact out', async () => { - await expect( - underpay.swap(pool.address, wallet.address, false, MAX_SQRT_RATIO.sub(1), -1000, 2000, 0) - ).to.be.revertedWith('IIA') - }) - it('overpay one for zero and exact out', async () => { - await expect( - underpay.swap(pool.address, wallet.address, false, MAX_SQRT_RATIO.sub(1), -1000, 0, 2000) - ).to.not.be.revertedWith('IIA') - }) - }) -}) diff --git a/lib/v3-core/test/UniswapV3Pool.swaps.spec.ts b/lib/v3-core/test/UniswapV3Pool.swaps.spec.ts deleted file mode 100644 index da4be19..0000000 --- a/lib/v3-core/test/UniswapV3Pool.swaps.spec.ts +++ /dev/null @@ -1,588 +0,0 @@ -import { Decimal } from 'decimal.js' -import { BigNumber, BigNumberish, ContractTransaction, Wallet } from 'ethers' -import { ethers, waffle } from 'hardhat' -import { MockTimeUniswapV3Pool } from '../typechain/MockTimeUniswapV3Pool' -import { TestERC20 } from '../typechain/TestERC20' - -import { TestUniswapV3Callee } from '../typechain/TestUniswapV3Callee' -import { expect } from './shared/expect' -import { poolFixture } from './shared/fixtures' -import { formatPrice, formatTokenAmount } from './shared/format' -import { - createPoolFunctions, - encodePriceSqrt, - expandTo18Decimals, - FeeAmount, - getMaxLiquidityPerTick, - getMaxTick, - getMinTick, - MAX_SQRT_RATIO, - MaxUint128, - MIN_SQRT_RATIO, - TICK_SPACINGS, -} from './shared/utilities' - -Decimal.config({ toExpNeg: -500, toExpPos: 500 }) - -const createFixtureLoader = waffle.createFixtureLoader -const { constants } = ethers - -interface BaseSwapTestCase { - zeroForOne: boolean - sqrtPriceLimit?: BigNumber -} -interface SwapExact0For1TestCase extends BaseSwapTestCase { - zeroForOne: true - exactOut: false - amount0: BigNumberish - sqrtPriceLimit?: BigNumber -} -interface SwapExact1For0TestCase extends BaseSwapTestCase { - zeroForOne: false - exactOut: false - amount1: BigNumberish - sqrtPriceLimit?: BigNumber -} -interface Swap0ForExact1TestCase extends BaseSwapTestCase { - zeroForOne: true - exactOut: true - amount1: BigNumberish - sqrtPriceLimit?: BigNumber -} -interface Swap1ForExact0TestCase extends BaseSwapTestCase { - zeroForOne: false - exactOut: true - amount0: BigNumberish - sqrtPriceLimit?: BigNumber -} -interface SwapToHigherPrice extends BaseSwapTestCase { - zeroForOne: false - sqrtPriceLimit: BigNumber -} -interface SwapToLowerPrice extends BaseSwapTestCase { - zeroForOne: true - sqrtPriceLimit: BigNumber -} -type SwapTestCase = - | SwapExact0For1TestCase - | Swap0ForExact1TestCase - | SwapExact1For0TestCase - | Swap1ForExact0TestCase - | SwapToHigherPrice - | SwapToLowerPrice - -function swapCaseToDescription(testCase: SwapTestCase): string { - const priceClause = testCase?.sqrtPriceLimit ? ` to price ${formatPrice(testCase.sqrtPriceLimit)}` : '' - if ('exactOut' in testCase) { - if (testCase.exactOut) { - if (testCase.zeroForOne) { - return `swap token0 for exactly ${formatTokenAmount(testCase.amount1)} token1${priceClause}` - } else { - return `swap token1 for exactly ${formatTokenAmount(testCase.amount0)} token0${priceClause}` - } - } else { - if (testCase.zeroForOne) { - return `swap exactly ${formatTokenAmount(testCase.amount0)} token0 for token1${priceClause}` - } else { - return `swap exactly ${formatTokenAmount(testCase.amount1)} token1 for token0${priceClause}` - } - } - } else { - if (testCase.zeroForOne) { - return `swap token0 for token1${priceClause}` - } else { - return `swap token1 for token0${priceClause}` - } - } -} - -type PoolFunctions = ReturnType - -// can't use address zero because the ERC20 token does not allow it -const SWAP_RECIPIENT_ADDRESS = constants.AddressZero.slice(0, -1) + '1' -const POSITION_PROCEEDS_OUTPUT_ADDRESS = constants.AddressZero.slice(0, -1) + '2' - -async function executeSwap( - pool: MockTimeUniswapV3Pool, - testCase: SwapTestCase, - poolFunctions: PoolFunctions -): Promise { - let swap: ContractTransaction - if ('exactOut' in testCase) { - if (testCase.exactOut) { - if (testCase.zeroForOne) { - swap = await poolFunctions.swap0ForExact1(testCase.amount1, SWAP_RECIPIENT_ADDRESS, testCase.sqrtPriceLimit) - } else { - swap = await poolFunctions.swap1ForExact0(testCase.amount0, SWAP_RECIPIENT_ADDRESS, testCase.sqrtPriceLimit) - } - } else { - if (testCase.zeroForOne) { - swap = await poolFunctions.swapExact0For1(testCase.amount0, SWAP_RECIPIENT_ADDRESS, testCase.sqrtPriceLimit) - } else { - swap = await poolFunctions.swapExact1For0(testCase.amount1, SWAP_RECIPIENT_ADDRESS, testCase.sqrtPriceLimit) - } - } - } else { - if (testCase.zeroForOne) { - swap = await poolFunctions.swapToLowerPrice(testCase.sqrtPriceLimit, SWAP_RECIPIENT_ADDRESS) - } else { - swap = await poolFunctions.swapToHigherPrice(testCase.sqrtPriceLimit, SWAP_RECIPIENT_ADDRESS) - } - } - return swap -} - -const DEFAULT_POOL_SWAP_TESTS: SwapTestCase[] = [ - // swap large amounts in/out - { - zeroForOne: true, - exactOut: false, - amount0: expandTo18Decimals(1), - }, - { - zeroForOne: false, - exactOut: false, - amount1: expandTo18Decimals(1), - }, - { - zeroForOne: true, - exactOut: true, - amount1: expandTo18Decimals(1), - }, - { - zeroForOne: false, - exactOut: true, - amount0: expandTo18Decimals(1), - }, - // swap large amounts in/out with a price limit - { - zeroForOne: true, - exactOut: false, - amount0: expandTo18Decimals(1), - sqrtPriceLimit: encodePriceSqrt(50, 100), - }, - { - zeroForOne: false, - exactOut: false, - amount1: expandTo18Decimals(1), - sqrtPriceLimit: encodePriceSqrt(200, 100), - }, - { - zeroForOne: true, - exactOut: true, - amount1: expandTo18Decimals(1), - sqrtPriceLimit: encodePriceSqrt(50, 100), - }, - { - zeroForOne: false, - exactOut: true, - amount0: expandTo18Decimals(1), - sqrtPriceLimit: encodePriceSqrt(200, 100), - }, - // swap small amounts in/out - { - zeroForOne: true, - exactOut: false, - amount0: 1000, - }, - { - zeroForOne: false, - exactOut: false, - amount1: 1000, - }, - { - zeroForOne: true, - exactOut: true, - amount1: 1000, - }, - { - zeroForOne: false, - exactOut: true, - amount0: 1000, - }, - // swap arbitrary input to price - { - sqrtPriceLimit: encodePriceSqrt(5, 2), - zeroForOne: false, - }, - { - sqrtPriceLimit: encodePriceSqrt(2, 5), - zeroForOne: true, - }, - { - sqrtPriceLimit: encodePriceSqrt(5, 2), - zeroForOne: true, - }, - { - sqrtPriceLimit: encodePriceSqrt(2, 5), - zeroForOne: false, - }, -] - -interface Position { - tickLower: number - tickUpper: number - liquidity: BigNumberish -} - -interface PoolTestCase { - description: string - feeAmount: number - tickSpacing: number - startingPrice: BigNumber - positions: Position[] - swapTests?: SwapTestCase[] -} - -const TEST_POOLS: PoolTestCase[] = [ - { - description: 'low fee, 1:1 price, 2e18 max range liquidity', - feeAmount: FeeAmount.LOW, - tickSpacing: TICK_SPACINGS[FeeAmount.LOW], - startingPrice: encodePriceSqrt(1, 1), - positions: [ - { - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.LOW]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.LOW]), - liquidity: expandTo18Decimals(2), - }, - ], - }, - { - description: 'medium fee, 1:1 price, 2e18 max range liquidity', - feeAmount: FeeAmount.MEDIUM, - tickSpacing: TICK_SPACINGS[FeeAmount.MEDIUM], - startingPrice: encodePriceSqrt(1, 1), - positions: [ - { - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - liquidity: expandTo18Decimals(2), - }, - ], - }, - { - description: 'high fee, 1:1 price, 2e18 max range liquidity', - feeAmount: FeeAmount.HIGH, - tickSpacing: TICK_SPACINGS[FeeAmount.HIGH], - startingPrice: encodePriceSqrt(1, 1), - positions: [ - { - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.HIGH]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.HIGH]), - liquidity: expandTo18Decimals(2), - }, - ], - }, - { - description: 'medium fee, 10:1 price, 2e18 max range liquidity', - feeAmount: FeeAmount.MEDIUM, - tickSpacing: TICK_SPACINGS[FeeAmount.MEDIUM], - startingPrice: encodePriceSqrt(10, 1), - positions: [ - { - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - liquidity: expandTo18Decimals(2), - }, - ], - }, - { - description: 'medium fee, 1:10 price, 2e18 max range liquidity', - feeAmount: FeeAmount.MEDIUM, - tickSpacing: TICK_SPACINGS[FeeAmount.MEDIUM], - startingPrice: encodePriceSqrt(1, 10), - positions: [ - { - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - liquidity: expandTo18Decimals(2), - }, - ], - }, - { - description: 'medium fee, 1:1 price, 0 liquidity, all liquidity around current price', - feeAmount: FeeAmount.MEDIUM, - tickSpacing: TICK_SPACINGS[FeeAmount.MEDIUM], - startingPrice: encodePriceSqrt(1, 1), - positions: [ - { - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: -TICK_SPACINGS[FeeAmount.MEDIUM], - liquidity: expandTo18Decimals(2), - }, - { - tickLower: TICK_SPACINGS[FeeAmount.MEDIUM], - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - liquidity: expandTo18Decimals(2), - }, - ], - }, - { - description: 'medium fee, 1:1 price, additional liquidity around current price', - feeAmount: FeeAmount.MEDIUM, - tickSpacing: TICK_SPACINGS[FeeAmount.MEDIUM], - startingPrice: encodePriceSqrt(1, 1), - positions: [ - { - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - liquidity: expandTo18Decimals(2), - }, - { - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: -TICK_SPACINGS[FeeAmount.MEDIUM], - liquidity: expandTo18Decimals(2), - }, - { - tickLower: TICK_SPACINGS[FeeAmount.MEDIUM], - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - liquidity: expandTo18Decimals(2), - }, - ], - }, - { - description: 'low fee, large liquidity around current price (stable swap)', - feeAmount: FeeAmount.LOW, - tickSpacing: TICK_SPACINGS[FeeAmount.LOW], - startingPrice: encodePriceSqrt(1, 1), - positions: [ - { - tickLower: -TICK_SPACINGS[FeeAmount.LOW], - tickUpper: TICK_SPACINGS[FeeAmount.LOW], - liquidity: expandTo18Decimals(2), - }, - ], - }, - { - description: 'medium fee, token0 liquidity only', - feeAmount: FeeAmount.MEDIUM, - tickSpacing: TICK_SPACINGS[FeeAmount.MEDIUM], - startingPrice: encodePriceSqrt(1, 1), - positions: [ - { - tickLower: 0, - tickUpper: 2000 * TICK_SPACINGS[FeeAmount.MEDIUM], - liquidity: expandTo18Decimals(2), - }, - ], - }, - { - description: 'medium fee, token1 liquidity only', - feeAmount: FeeAmount.MEDIUM, - tickSpacing: TICK_SPACINGS[FeeAmount.MEDIUM], - startingPrice: encodePriceSqrt(1, 1), - positions: [ - { - tickLower: -2000 * TICK_SPACINGS[FeeAmount.MEDIUM], - tickUpper: 0, - liquidity: expandTo18Decimals(2), - }, - ], - }, - { - description: 'close to max price', - feeAmount: FeeAmount.MEDIUM, - tickSpacing: TICK_SPACINGS[FeeAmount.MEDIUM], - startingPrice: encodePriceSqrt(BigNumber.from(2).pow(127), 1), - positions: [ - { - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - liquidity: expandTo18Decimals(2), - }, - ], - }, - { - description: 'close to min price', - feeAmount: FeeAmount.MEDIUM, - tickSpacing: TICK_SPACINGS[FeeAmount.MEDIUM], - startingPrice: encodePriceSqrt(1, BigNumber.from(2).pow(127)), - positions: [ - { - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - liquidity: expandTo18Decimals(2), - }, - ], - }, - { - description: 'max full range liquidity at 1:1 price with default fee', - feeAmount: FeeAmount.MEDIUM, - tickSpacing: TICK_SPACINGS[FeeAmount.MEDIUM], - startingPrice: encodePriceSqrt(1, 1), - positions: [ - { - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - liquidity: getMaxLiquidityPerTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - }, - ], - }, - { - description: 'initialized at the max ratio', - feeAmount: FeeAmount.MEDIUM, - tickSpacing: TICK_SPACINGS[FeeAmount.MEDIUM], - startingPrice: MAX_SQRT_RATIO.sub(1), - positions: [ - { - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - liquidity: expandTo18Decimals(2), - }, - ], - }, - { - description: 'initialized at the min ratio', - feeAmount: FeeAmount.MEDIUM, - tickSpacing: TICK_SPACINGS[FeeAmount.MEDIUM], - startingPrice: MIN_SQRT_RATIO, - positions: [ - { - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - liquidity: expandTo18Decimals(2), - }, - ], - }, -] - -describe('UniswapV3Pool swap tests', () => { - let wallet: Wallet, other: Wallet - - let loadFixture: ReturnType - - before('create fixture loader', async () => { - ;[wallet, other] = await (ethers as any).getSigners() - - loadFixture = createFixtureLoader([wallet]) - }) - - for (const poolCase of TEST_POOLS) { - describe(poolCase.description, () => { - const poolCaseFixture = async () => { - const { createPool, token0, token1, swapTargetCallee: swapTarget } = await poolFixture( - [wallet], - waffle.provider - ) - const pool = await createPool(poolCase.feeAmount, poolCase.tickSpacing) - const poolFunctions = createPoolFunctions({ swapTarget, token0, token1, pool }) - await pool.initialize(poolCase.startingPrice) - // mint all positions - for (const position of poolCase.positions) { - await poolFunctions.mint(wallet.address, position.tickLower, position.tickUpper, position.liquidity) - } - - const [poolBalance0, poolBalance1] = await Promise.all([ - token0.balanceOf(pool.address), - token1.balanceOf(pool.address), - ]) - - return { token0, token1, pool, poolFunctions, poolBalance0, poolBalance1, swapTarget } - } - - let token0: TestERC20 - let token1: TestERC20 - - let poolBalance0: BigNumber - let poolBalance1: BigNumber - - let pool: MockTimeUniswapV3Pool - let swapTarget: TestUniswapV3Callee - let poolFunctions: PoolFunctions - - beforeEach('load fixture', async () => { - ;({ token0, token1, pool, poolFunctions, poolBalance0, poolBalance1, swapTarget } = await loadFixture( - poolCaseFixture - )) - }) - - afterEach('check can burn positions', async () => { - for (const { liquidity, tickUpper, tickLower } of poolCase.positions) { - await pool.burn(tickLower, tickUpper, liquidity) - await pool.collect(POSITION_PROCEEDS_OUTPUT_ADDRESS, tickLower, tickUpper, MaxUint128, MaxUint128) - } - }) - - for (const testCase of poolCase.swapTests ?? DEFAULT_POOL_SWAP_TESTS) { - it(swapCaseToDescription(testCase), async () => { - const slot0 = await pool.slot0() - const tx = executeSwap(pool, testCase, poolFunctions) - try { - await tx - } catch (error) { - expect({ - swapError: error.message, - poolBalance0: poolBalance0.toString(), - poolBalance1: poolBalance1.toString(), - poolPriceBefore: formatPrice(slot0.sqrtPriceX96), - tickBefore: slot0.tick, - }).to.matchSnapshot('swap error') - return - } - const [ - poolBalance0After, - poolBalance1After, - slot0After, - liquidityAfter, - feeGrowthGlobal0X128, - feeGrowthGlobal1X128, - ] = await Promise.all([ - token0.balanceOf(pool.address), - token1.balanceOf(pool.address), - pool.slot0(), - pool.liquidity(), - pool.feeGrowthGlobal0X128(), - pool.feeGrowthGlobal1X128(), - ]) - const poolBalance0Delta = poolBalance0After.sub(poolBalance0) - const poolBalance1Delta = poolBalance1After.sub(poolBalance1) - - // check all the events were emitted corresponding to balance changes - if (poolBalance0Delta.eq(0)) await expect(tx).to.not.emit(token0, 'Transfer') - else if (poolBalance0Delta.lt(0)) - await expect(tx) - .to.emit(token0, 'Transfer') - .withArgs(pool.address, SWAP_RECIPIENT_ADDRESS, poolBalance0Delta.mul(-1)) - else await expect(tx).to.emit(token0, 'Transfer').withArgs(wallet.address, pool.address, poolBalance0Delta) - - if (poolBalance1Delta.eq(0)) await expect(tx).to.not.emit(token1, 'Transfer') - else if (poolBalance1Delta.lt(0)) - await expect(tx) - .to.emit(token1, 'Transfer') - .withArgs(pool.address, SWAP_RECIPIENT_ADDRESS, poolBalance1Delta.mul(-1)) - else await expect(tx).to.emit(token1, 'Transfer').withArgs(wallet.address, pool.address, poolBalance1Delta) - - // check that the swap event was emitted too - await expect(tx) - .to.emit(pool, 'Swap') - .withArgs( - swapTarget.address, - SWAP_RECIPIENT_ADDRESS, - poolBalance0Delta, - poolBalance1Delta, - slot0After.sqrtPriceX96, - liquidityAfter, - slot0After.tick - ) - - const executionPrice = new Decimal(poolBalance1Delta.toString()).div(poolBalance0Delta.toString()).mul(-1) - - expect({ - amount0Before: poolBalance0.toString(), - amount1Before: poolBalance1.toString(), - amount0Delta: poolBalance0Delta.toString(), - amount1Delta: poolBalance1Delta.toString(), - feeGrowthGlobal0X128Delta: feeGrowthGlobal0X128.toString(), - feeGrowthGlobal1X128Delta: feeGrowthGlobal1X128.toString(), - tickBefore: slot0.tick, - poolPriceBefore: formatPrice(slot0.sqrtPriceX96), - tickAfter: slot0After.tick, - poolPriceAfter: formatPrice(slot0After.sqrtPriceX96), - executionPrice: executionPrice.toPrecision(5), - }).to.matchSnapshot('balances') - }) - } - }) - } -}) diff --git a/lib/v3-core/test/UniswapV3Router.spec.ts b/lib/v3-core/test/UniswapV3Router.spec.ts deleted file mode 100644 index 09af949..0000000 --- a/lib/v3-core/test/UniswapV3Router.spec.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { Wallet } from 'ethers' -import { ethers, waffle } from 'hardhat' -import { TestERC20 } from '../typechain/TestERC20' -import { UniswapV3Factory } from '../typechain/UniswapV3Factory' -import { MockTimeUniswapV3Pool } from '../typechain/MockTimeUniswapV3Pool' -import { expect } from './shared/expect' - -import { poolFixture } from './shared/fixtures' - -import { - FeeAmount, - TICK_SPACINGS, - createPoolFunctions, - PoolFunctions, - createMultiPoolFunctions, - encodePriceSqrt, - getMinTick, - getMaxTick, - expandTo18Decimals, -} from './shared/utilities' -import { TestUniswapV3Router } from '../typechain/TestUniswapV3Router' -import { TestUniswapV3Callee } from '../typechain/TestUniswapV3Callee' - -const feeAmount = FeeAmount.MEDIUM -const tickSpacing = TICK_SPACINGS[feeAmount] - -const createFixtureLoader = waffle.createFixtureLoader - -type ThenArg = T extends PromiseLike ? U : T - -describe('UniswapV3Pool', () => { - let wallet: Wallet, other: Wallet - - let token0: TestERC20 - let token1: TestERC20 - let token2: TestERC20 - let factory: UniswapV3Factory - let pool0: MockTimeUniswapV3Pool - let pool1: MockTimeUniswapV3Pool - - let pool0Functions: PoolFunctions - let pool1Functions: PoolFunctions - - let minTick: number - let maxTick: number - - let swapTargetCallee: TestUniswapV3Callee - let swapTargetRouter: TestUniswapV3Router - - let loadFixture: ReturnType - let createPool: ThenArg>['createPool'] - - before('create fixture loader', async () => { - ;[wallet, other] = await (ethers as any).getSigners() - - loadFixture = createFixtureLoader([wallet, other]) - }) - - beforeEach('deploy first fixture', async () => { - ;({ token0, token1, token2, factory, createPool, swapTargetCallee, swapTargetRouter } = await loadFixture( - poolFixture - )) - - const createPoolWrapped = async ( - amount: number, - spacing: number, - firstToken: TestERC20, - secondToken: TestERC20 - ): Promise<[MockTimeUniswapV3Pool, any]> => { - const pool = await createPool(amount, spacing, firstToken, secondToken) - const poolFunctions = createPoolFunctions({ - swapTarget: swapTargetCallee, - token0: firstToken, - token1: secondToken, - pool, - }) - minTick = getMinTick(spacing) - maxTick = getMaxTick(spacing) - return [pool, poolFunctions] - } - - // default to the 30 bips pool - ;[pool0, pool0Functions] = await createPoolWrapped(feeAmount, tickSpacing, token0, token1) - ;[pool1, pool1Functions] = await createPoolWrapped(feeAmount, tickSpacing, token1, token2) - }) - - it('constructor initializes immutables', async () => { - expect(await pool0.factory()).to.eq(factory.address) - expect(await pool0.token0()).to.eq(token0.address) - expect(await pool0.token1()).to.eq(token1.address) - expect(await pool1.factory()).to.eq(factory.address) - expect(await pool1.token0()).to.eq(token1.address) - expect(await pool1.token1()).to.eq(token2.address) - }) - - describe('multi-swaps', () => { - let inputToken: TestERC20 - let outputToken: TestERC20 - - beforeEach('initialize both pools', async () => { - inputToken = token0 - outputToken = token2 - - await pool0.initialize(encodePriceSqrt(1, 1)) - await pool1.initialize(encodePriceSqrt(1, 1)) - - await pool0Functions.mint(wallet.address, minTick, maxTick, expandTo18Decimals(1)) - await pool1Functions.mint(wallet.address, minTick, maxTick, expandTo18Decimals(1)) - }) - - it('multi-swap', async () => { - const token0OfPoolOutput = await pool1.token0() - const ForExact0 = outputToken.address === token0OfPoolOutput - - const { swapForExact0Multi, swapForExact1Multi } = createMultiPoolFunctions({ - inputToken: token0, - swapTarget: swapTargetRouter, - poolInput: pool0, - poolOutput: pool1, - }) - - const method = ForExact0 ? swapForExact0Multi : swapForExact1Multi - - await expect(method(100, wallet.address)) - .to.emit(outputToken, 'Transfer') - .withArgs(pool1.address, wallet.address, 100) - .to.emit(token1, 'Transfer') - .withArgs(pool0.address, pool1.address, 102) - .to.emit(inputToken, 'Transfer') - .withArgs(wallet.address, pool0.address, 104) - }) - }) -}) diff --git a/lib/v3-core/test/__snapshots__/BitMath.spec.ts.snap b/lib/v3-core/test/__snapshots__/BitMath.spec.ts.snap deleted file mode 100644 index fe68ee6..0000000 --- a/lib/v3-core/test/__snapshots__/BitMath.spec.ts.snap +++ /dev/null @@ -1,13 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`BitMath #leastSignificantBit gas cost of max uint128 1`] = `431`; - -exports[`BitMath #leastSignificantBit gas cost of max uint256 1`] = `431`; - -exports[`BitMath #leastSignificantBit gas cost of smaller number 1`] = `429`; - -exports[`BitMath #mostSignificantBit gas cost of max uint128 1`] = `367`; - -exports[`BitMath #mostSignificantBit gas cost of max uint256 1`] = `385`; - -exports[`BitMath #mostSignificantBit gas cost of smaller number 1`] = `295`; diff --git a/lib/v3-core/test/__snapshots__/LiquidityMath.spec.ts.snap b/lib/v3-core/test/__snapshots__/LiquidityMath.spec.ts.snap deleted file mode 100644 index 6b942a3..0000000 --- a/lib/v3-core/test/__snapshots__/LiquidityMath.spec.ts.snap +++ /dev/null @@ -1,5 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`LiquidityMath #addDelta gas add 1`] = `162`; - -exports[`LiquidityMath #addDelta gas sub 1`] = `176`; diff --git a/lib/v3-core/test/__snapshots__/NoDelegateCall.spec.ts.snap b/lib/v3-core/test/__snapshots__/NoDelegateCall.spec.ts.snap deleted file mode 100644 index 636990a..0000000 --- a/lib/v3-core/test/__snapshots__/NoDelegateCall.spec.ts.snap +++ /dev/null @@ -1,3 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`NoDelegateCall runtime overhead 1`] = `30`; diff --git a/lib/v3-core/test/__snapshots__/Oracle.spec.ts.snap b/lib/v3-core/test/__snapshots__/Oracle.spec.ts.snap deleted file mode 100644 index cd67254..0000000 --- a/lib/v3-core/test/__snapshots__/Oracle.spec.ts.snap +++ /dev/null @@ -1,87 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Oracle #grow gas for growing by 1 slot when index != cardinality - 1 1`] = `49081`; - -exports[`Oracle #grow gas for growing by 1 slot when index == cardinality - 1 1`] = `49081`; - -exports[`Oracle #grow gas for growing by 10 slots when index != cardinality - 1 1`] = `249223`; - -exports[`Oracle #grow gas for growing by 10 slots when index == cardinality - 1 1`] = `249223`; - -exports[`Oracle #initialize gas 1`] = `67770`; - -exports[`Oracle #observe before initialization gas for observe since most recent 1`] = `4746`; - -exports[`Oracle #observe before initialization gas for single observation at current time 1`] = `3565`; - -exports[`Oracle #observe before initialization gas for single observation at current time counterfactually computed 1`] = `4067`; - -exports[`Oracle #observe initialized with 5 observations with starting time of 5 fetch many values 1`] = ` -Object { - "secondsPerLiquidityCumulativeX128s": Array [ - "544451787073501541541399371890829138329", - "799663562264205389138930327464655296921", - "1045423049484883168306923099498710116305", - "1423514568285925905488450441089563684590", - "2152691068830794041481396028443352709138", - "2347138135642758877746181518404363115684", - "2395749902345750086812377890894615717321", - ], - "tickCumulatives": Array [ - -13, - -31, - -43, - -37, - -15, - 9, - 15, - ], -} -`; - -exports[`Oracle #observe initialized with 5 observations with starting time of 5 gas all of last 20 seconds 1`] = `91193`; - -exports[`Oracle #observe initialized with 5 observations with starting time of 5 gas between oldest and oldest + 1 1`] = `15811`; - -exports[`Oracle #observe initialized with 5 observations with starting time of 5 gas latest equal 1`] = `3565`; - -exports[`Oracle #observe initialized with 5 observations with starting time of 5 gas latest transform 1`] = `4067`; - -exports[`Oracle #observe initialized with 5 observations with starting time of 5 gas middle 1`] = `13986`; - -exports[`Oracle #observe initialized with 5 observations with starting time of 5 gas oldest 1`] = `15538`; - -exports[`Oracle #observe initialized with 5 observations with starting time of 4294967291 fetch many values 1`] = ` -Object { - "secondsPerLiquidityCumulativeX128s": Array [ - "544451787073501541541399371890829138329", - "799663562264205389138930327464655296921", - "1045423049484883168306923099498710116305", - "1423514568285925905488450441089563684590", - "2152691068830794041481396028443352709138", - "2347138135642758877746181518404363115684", - "2395749902345750086812377890894615717321", - ], - "tickCumulatives": Array [ - -13, - -31, - -43, - -37, - -15, - 9, - 15, - ], -} -`; - -exports[`Oracle #observe initialized with 5 observations with starting time of 4294967291 gas all of last 20 seconds 1`] = `91193`; - -exports[`Oracle #observe initialized with 5 observations with starting time of 4294967291 gas between oldest and oldest + 1 1`] = `15811`; - -exports[`Oracle #observe initialized with 5 observations with starting time of 4294967291 gas latest equal 1`] = `3565`; - -exports[`Oracle #observe initialized with 5 observations with starting time of 4294967291 gas latest transform 1`] = `4067`; - -exports[`Oracle #observe initialized with 5 observations with starting time of 4294967291 gas middle 1`] = `13986`; - -exports[`Oracle #observe initialized with 5 observations with starting time of 4294967291 gas oldest 1`] = `15538`; diff --git a/lib/v3-core/test/__snapshots__/SqrtPriceMath.spec.ts.snap b/lib/v3-core/test/__snapshots__/SqrtPriceMath.spec.ts.snap deleted file mode 100644 index 11308cc..0000000 --- a/lib/v3-core/test/__snapshots__/SqrtPriceMath.spec.ts.snap +++ /dev/null @@ -1,17 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`SqrtPriceMath #getAmount0Delta gas cost for amount0 where roundUp = true 1`] = `610`; - -exports[`SqrtPriceMath #getAmount0Delta gas cost for amount0 where roundUp = true 2`] = `478`; - -exports[`SqrtPriceMath #getAmount1Delta gas cost for amount0 where roundUp = false 1`] = `478`; - -exports[`SqrtPriceMath #getAmount1Delta gas cost for amount0 where roundUp = true 1`] = `610`; - -exports[`SqrtPriceMath #getNextSqrtPriceFromInput zeroForOne = false gas 1`] = `536`; - -exports[`SqrtPriceMath #getNextSqrtPriceFromInput zeroForOne = true gas 1`] = `753`; - -exports[`SqrtPriceMath #getNextSqrtPriceFromOutput zeroForOne = false gas 1`] = `848`; - -exports[`SqrtPriceMath #getNextSqrtPriceFromOutput zeroForOne = true gas 1`] = `441`; diff --git a/lib/v3-core/test/__snapshots__/SwapMath.spec.ts.snap b/lib/v3-core/test/__snapshots__/SwapMath.spec.ts.snap deleted file mode 100644 index df10cbd..0000000 --- a/lib/v3-core/test/__snapshots__/SwapMath.spec.ts.snap +++ /dev/null @@ -1,17 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`SwapMath #computeSwapStep gas swap one for zero exact in capped 1`] = `2103`; - -exports[`SwapMath #computeSwapStep gas swap one for zero exact in partial 1`] = `2802`; - -exports[`SwapMath #computeSwapStep gas swap one for zero exact out capped 1`] = `1855`; - -exports[`SwapMath #computeSwapStep gas swap one for zero exact out partial 1`] = `2802`; - -exports[`SwapMath #computeSwapStep gas swap zero for one exact in capped 1`] = `2104`; - -exports[`SwapMath #computeSwapStep gas swap zero for one exact in partial 1`] = `3106`; - -exports[`SwapMath #computeSwapStep gas swap zero for one exact out capped 1`] = `1856`; - -exports[`SwapMath #computeSwapStep gas swap zero for one exact out partial 1`] = `3106`; diff --git a/lib/v3-core/test/__snapshots__/TickBitmap.spec.ts.snap b/lib/v3-core/test/__snapshots__/TickBitmap.spec.ts.snap deleted file mode 100644 index 9d040d1..0000000 --- a/lib/v3-core/test/__snapshots__/TickBitmap.spec.ts.snap +++ /dev/null @@ -1,19 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`TickBitmap #flipTick gas cost of flipping a tick that results in deleting a word 1`] = `13427`; - -exports[`TickBitmap #flipTick gas cost of flipping first tick in word to initialized 1`] = `43965`; - -exports[`TickBitmap #flipTick gas cost of flipping second tick in word to initialized 1`] = `26865`; - -exports[`TickBitmap #nextInitializedTickWithinOneWord lte = false gas cost for entire word 1`] = `2627`; - -exports[`TickBitmap #nextInitializedTickWithinOneWord lte = false gas cost just below boundary 1`] = `2627`; - -exports[`TickBitmap #nextInitializedTickWithinOneWord lte = false gas cost on boundary 1`] = `2627`; - -exports[`TickBitmap #nextInitializedTickWithinOneWord lte = true gas cost for entire word 1`] = `2618`; - -exports[`TickBitmap #nextInitializedTickWithinOneWord lte = true gas cost just below boundary 1`] = `2928`; - -exports[`TickBitmap #nextInitializedTickWithinOneWord lte = true gas cost on boundary 1`] = `2618`; diff --git a/lib/v3-core/test/__snapshots__/TickMath.spec.ts.snap b/lib/v3-core/test/__snapshots__/TickMath.spec.ts.snap deleted file mode 100644 index 57e13fd..0000000 --- a/lib/v3-core/test/__snapshots__/TickMath.spec.ts.snap +++ /dev/null @@ -1,165 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`TickMath #getSqrtRatioAtTick tick -50 gas 1`] = `823`; - -exports[`TickMath #getSqrtRatioAtTick tick -50 result 1`] = `"79030349367926598376800521322"`; - -exports[`TickMath #getSqrtRatioAtTick tick -100 gas 1`] = `823`; - -exports[`TickMath #getSqrtRatioAtTick tick -100 result 1`] = `"78833030112140176575862854579"`; - -exports[`TickMath #getSqrtRatioAtTick tick -250 gas 1`] = `865`; - -exports[`TickMath #getSqrtRatioAtTick tick -250 result 1`] = `"78244023372248365697264290337"`; - -exports[`TickMath #getSqrtRatioAtTick tick -500 gas 1`] = `865`; - -exports[`TickMath #getSqrtRatioAtTick tick -500 result 1`] = `"77272108795590369356373805297"`; - -exports[`TickMath #getSqrtRatioAtTick tick -1000 gas 1`] = `865`; - -exports[`TickMath #getSqrtRatioAtTick tick -1000 result 1`] = `"75364347830767020784054125655"`; - -exports[`TickMath #getSqrtRatioAtTick tick -2500 gas 1`] = `851`; - -exports[`TickMath #getSqrtRatioAtTick tick -2500 result 1`] = `"69919044979842180277688105136"`; - -exports[`TickMath #getSqrtRatioAtTick tick -3000 gas 1`] = `879`; - -exports[`TickMath #getSqrtRatioAtTick tick -3000 result 1`] = `"68192822843687888778582228483"`; - -exports[`TickMath #getSqrtRatioAtTick tick -4000 gas 1`] = `865`; - -exports[`TickMath #getSqrtRatioAtTick tick -4000 result 1`] = `"64867181785621769311890333195"`; - -exports[`TickMath #getSqrtRatioAtTick tick -5000 gas 1`] = `851`; - -exports[`TickMath #getSqrtRatioAtTick tick -5000 result 1`] = `"61703726247759831737814779831"`; - -exports[`TickMath #getSqrtRatioAtTick tick -50000 gas 1`] = `865`; - -exports[`TickMath #getSqrtRatioAtTick tick -50000 result 1`] = `"6504256538020985011912221507"`; - -exports[`TickMath #getSqrtRatioAtTick tick -150000 gas 1`] = `893`; - -exports[`TickMath #getSqrtRatioAtTick tick -150000 result 1`] = `"43836292794701720435367485"`; - -exports[`TickMath #getSqrtRatioAtTick tick -250000 gas 1`] = `879`; - -exports[`TickMath #getSqrtRatioAtTick tick -250000 result 1`] = `"295440463448801648376846"`; - -exports[`TickMath #getSqrtRatioAtTick tick -500000 gas 1`] = `879`; - -exports[`TickMath #getSqrtRatioAtTick tick -500000 result 1`] = `"1101692437043807371"`; - -exports[`TickMath #getSqrtRatioAtTick tick -738203 gas 1`] = `911`; - -exports[`TickMath #getSqrtRatioAtTick tick -738203 result 1`] = `"7409801140451"`; - -exports[`TickMath #getSqrtRatioAtTick tick 50 gas 1`] = `863`; - -exports[`TickMath #getSqrtRatioAtTick tick 50 result 1`] = `"79426470787362580746886972461"`; - -exports[`TickMath #getSqrtRatioAtTick tick 100 gas 1`] = `863`; - -exports[`TickMath #getSqrtRatioAtTick tick 100 result 1`] = `"79625275426524748796330556128"`; - -exports[`TickMath #getSqrtRatioAtTick tick 250 gas 1`] = `905`; - -exports[`TickMath #getSqrtRatioAtTick tick 250 result 1`] = `"80224679980005306637834519095"`; - -exports[`TickMath #getSqrtRatioAtTick tick 500 gas 1`] = `905`; - -exports[`TickMath #getSqrtRatioAtTick tick 500 result 1`] = `"81233731461783161732293370115"`; - -exports[`TickMath #getSqrtRatioAtTick tick 1000 gas 1`] = `905`; - -exports[`TickMath #getSqrtRatioAtTick tick 1000 result 1`] = `"83290069058676223003182343270"`; - -exports[`TickMath #getSqrtRatioAtTick tick 2500 gas 1`] = `891`; - -exports[`TickMath #getSqrtRatioAtTick tick 2500 result 1`] = `"89776708723587163891445672585"`; - -exports[`TickMath #getSqrtRatioAtTick tick 3000 gas 1`] = `919`; - -exports[`TickMath #getSqrtRatioAtTick tick 3000 result 1`] = `"92049301871182272007977902845"`; - -exports[`TickMath #getSqrtRatioAtTick tick 4000 gas 1`] = `905`; - -exports[`TickMath #getSqrtRatioAtTick tick 4000 result 1`] = `"96768528593268422080558758223"`; - -exports[`TickMath #getSqrtRatioAtTick tick 5000 gas 1`] = `891`; - -exports[`TickMath #getSqrtRatioAtTick tick 5000 result 1`] = `"101729702841318637793976746270"`; - -exports[`TickMath #getSqrtRatioAtTick tick 50000 gas 1`] = `905`; - -exports[`TickMath #getSqrtRatioAtTick tick 50000 result 1`] = `"965075977353221155028623082916"`; - -exports[`TickMath #getSqrtRatioAtTick tick 150000 gas 1`] = `933`; - -exports[`TickMath #getSqrtRatioAtTick tick 150000 result 1`] = `"143194173941309278083010301478497"`; - -exports[`TickMath #getSqrtRatioAtTick tick 250000 gas 1`] = `919`; - -exports[`TickMath #getSqrtRatioAtTick tick 250000 result 1`] = `"21246587762933397357449903968194344"`; - -exports[`TickMath #getSqrtRatioAtTick tick 500000 gas 1`] = `919`; - -exports[`TickMath #getSqrtRatioAtTick tick 500000 result 1`] = `"5697689776495288729098254600827762987878"`; - -exports[`TickMath #getSqrtRatioAtTick tick 738203 gas 1`] = `951`; - -exports[`TickMath #getSqrtRatioAtTick tick 738203 result 1`] = `"847134979253254120489401328389043031315994541"`; - -exports[`TickMath #getTickAtSqrtRatio ratio 4295128739 gas 1`] = `2371`; - -exports[`TickMath #getTickAtSqrtRatio ratio 4295128739 result 1`] = `-887272`; - -exports[`TickMath #getTickAtSqrtRatio ratio 79228162514264337593543 gas 1`] = `2367`; - -exports[`TickMath #getTickAtSqrtRatio ratio 79228162514264337593543 result 1`] = `-276325`; - -exports[`TickMath #getTickAtSqrtRatio ratio 79228162514264337593543950 gas 1`] = `2367`; - -exports[`TickMath #getTickAtSqrtRatio ratio 79228162514264337593543950 result 1`] = `-138163`; - -exports[`TickMath #getTickAtSqrtRatio ratio 9903520314283042199192993792 gas 1`] = `1389`; - -exports[`TickMath #getTickAtSqrtRatio ratio 9903520314283042199192993792 result 1`] = `-41591`; - -exports[`TickMath #getTickAtSqrtRatio ratio 28011385487393069959365969113 gas 1`] = `2329`; - -exports[`TickMath #getTickAtSqrtRatio ratio 28011385487393069959365969113 result 1`] = `-20796`; - -exports[`TickMath #getTickAtSqrtRatio ratio 56022770974786139918731938227 gas 1`] = `2315`; - -exports[`TickMath #getTickAtSqrtRatio ratio 56022770974786139918731938227 result 1`] = `-6932`; - -exports[`TickMath #getTickAtSqrtRatio ratio 79228162514264337593543950336 gas 1`] = `2235`; - -exports[`TickMath #getTickAtSqrtRatio ratio 79228162514264337593543950336 result 1`] = `0`; - -exports[`TickMath #getTickAtSqrtRatio ratio 112045541949572279837463876454 gas 1`] = `2355`; - -exports[`TickMath #getTickAtSqrtRatio ratio 112045541949572279837463876454 result 1`] = `6931`; - -exports[`TickMath #getTickAtSqrtRatio ratio 224091083899144559674927752909 gas 1`] = `2369`; - -exports[`TickMath #getTickAtSqrtRatio ratio 224091083899144559674927752909 result 1`] = `20795`; - -exports[`TickMath #getTickAtSqrtRatio ratio 633825300114114700748351602688 gas 1`] = `2393`; - -exports[`TickMath #getTickAtSqrtRatio ratio 633825300114114700748351602688 result 1`] = `41590`; - -exports[`TickMath #getTickAtSqrtRatio ratio 79228162514264337593543950336000 gas 1`] = `2407`; - -exports[`TickMath #getTickAtSqrtRatio ratio 79228162514264337593543950336000 result 1`] = `138162`; - -exports[`TickMath #getTickAtSqrtRatio ratio 79228162514264337593543950336000000 gas 1`] = `2407`; - -exports[`TickMath #getTickAtSqrtRatio ratio 79228162514264337593543950336000000 result 1`] = `276324`; - -exports[`TickMath #getTickAtSqrtRatio ratio 1461446703485210103287273052203988822378723970341 gas 1`] = `2431`; - -exports[`TickMath #getTickAtSqrtRatio ratio 1461446703485210103287273052203988822378723970341 result 1`] = `887271`; diff --git a/lib/v3-core/test/__snapshots__/UniswapV3Factory.spec.ts.snap b/lib/v3-core/test/__snapshots__/UniswapV3Factory.spec.ts.snap deleted file mode 100644 index 109b0c9..0000000 --- a/lib/v3-core/test/__snapshots__/UniswapV3Factory.spec.ts.snap +++ /dev/null @@ -1,7 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`UniswapV3Factory #createPool gas 1`] = `4557092`; - -exports[`UniswapV3Factory factory bytecode size 1`] = `24535`; - -exports[`UniswapV3Factory pool bytecode size 1`] = `22142`; diff --git a/lib/v3-core/test/__snapshots__/UniswapV3Pool.arbitrage.spec.ts.snap b/lib/v3-core/test/__snapshots__/UniswapV3Pool.arbitrage.spec.ts.snap deleted file mode 100644 index 2e4e465..0000000 --- a/lib/v3-core/test/__snapshots__/UniswapV3Pool.arbitrage.spec.ts.snap +++ /dev/null @@ -1,977 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`UniswapV3Pool arbitrage tests protocol fee = 0; passive liquidity of 0.010000 exact input of 10e18 token0 with starting price of 1.0 and true price of 0.98 backrun to true price after swap only 1`] = ` -Object { - "arbBalanceDelta0": "9.9699", - "arbBalanceDelta1": "-0.0099043", - "backrun": Object { - "delta0": "-9.9699", - "delta1": "0.0099043", - "executionPrice": "0.00099342", - }, - "finalPrice": "0.97706", - "profit": Object { - "final": "9.7606", - }, -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 0; passive liquidity of 0.010000 exact input of 10e18 token0 with starting price of 1.0 and true price of 0.98 not sandwiched 1`] = ` -Object { - "amount0Delta": "10.000", - "amount1Delta": "-0.0099900", - "executionPrice": "0.00099900", - "priceAfter": "0.0000010040", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 0; passive liquidity of 0.010000 exact input of 10e18 token0 with starting price of 1.0 and true price of 0.98 sandwiched with swap to execution price then mint max liquidity/target/burn max liquidity 1`] = ` -Object { - "arbBalanceDelta0": "9.9990", - "arbBalanceDelta1": "-0.0099044", - "backrun": Object { - "delta0": "-0.30578", - "delta1": "0.0095969", - "executionPrice": "0.031385", - }, - "burn": Object { - "amount0": "9.9700", - "amount1": "1.0910e+12", - }, - "collect": Object { - "amount0": "0.030000", - "amount1": "0.0000", - }, - "finalPrice": "0.97706", - "frontrun": Object { - "delta0": "0.30682", - "delta1": "-0.0096834", - "executionPrice": "0.031561", - }, - "mint": Object { - "amount0": "0.0000", - "amount1": "1.0910e+12", - }, - "profit": Object { - "afterFrontrun": "-0.29100", - "afterSandwich": "9.4990", - "final": "9.7891", - }, - "sandwichedPrice": "0.00099910", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 0; passive liquidity of 0.010000 exact input of 10e18 token0 with starting price of 1.0 and true price of 1.01 backrun to true price after swap only 1`] = ` -Object { - "arbBalanceDelta0": "9.9700", - "arbBalanceDelta1": "-0.010055", - "backrun": Object { - "delta0": "-9.9700", - "delta1": "0.010055", - "executionPrice": "0.0010085", - }, - "finalPrice": "1.0070", - "profit": Object { - "final": "10.060", - }, -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 0; passive liquidity of 0.010000 exact input of 10e18 token0 with starting price of 1.0 and true price of 1.01 not sandwiched 1`] = ` -Object { - "amount0Delta": "10.000", - "amount1Delta": "-0.0099900", - "executionPrice": "0.00099900", - "priceAfter": "0.0000010040", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 0; passive liquidity of 0.010000 exact input of 10e18 token0 with starting price of 1.0 and true price of 1.01 sandwiched with swap to execution price then mint max liquidity/target/burn max liquidity 1`] = ` -Object { - "arbBalanceDelta0": "9.9991", - "arbBalanceDelta1": "-0.010055", - "backrun": Object { - "delta0": "-0.30593", - "delta1": "0.0097475", - "executionPrice": "0.031862", - }, - "burn": Object { - "amount0": "9.9700", - "amount1": "1.0910e+12", - }, - "collect": Object { - "amount0": "0.030000", - "amount1": "0.0000", - }, - "finalPrice": "1.0070", - "frontrun": Object { - "delta0": "0.30682", - "delta1": "-0.0096834", - "executionPrice": "0.031561", - }, - "mint": Object { - "amount0": "0.0000", - "amount1": "1.0910e+12", - }, - "profit": Object { - "afterFrontrun": "-0.30020", - "afterSandwich": "9.7898", - "final": "10.089", - }, - "sandwichedPrice": "0.00099910", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 0; passive liquidity of 1.0000 exact input of 10e18 token0 with starting price of 1.0 and true price of 0.98 backrun to true price after swap only 1`] = ` -Object { - "arbBalanceDelta0": "9.9583", - "arbBalanceDelta1": "-0.90001", - "backrun": Object { - "delta0": "-9.9583", - "delta1": "0.90001", - "executionPrice": "0.090377", - }, - "finalPrice": "0.97706", - "profit": Object { - "final": "8.8592", - }, -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 0; passive liquidity of 1.0000 exact input of 10e18 token0 with starting price of 1.0 and true price of 0.98 not sandwiched 1`] = ` -Object { - "amount0Delta": "10.000", - "amount1Delta": "-0.90884", - "executionPrice": "0.090884", - "priceAfter": "0.0083097", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 0; passive liquidity of 1.0000 exact input of 10e18 token0 with starting price of 1.0 and true price of 0.98 sandwiched with swap to execution price then mint max liquidity/target/burn max liquidity 1`] = ` -Object { - "arbBalanceDelta0": "9.9814", - "arbBalanceDelta1": "-0.90054", - "backrun": Object { - "delta0": "-2.2983", - "delta1": "0.68841", - "executionPrice": "0.29953", - }, - "burn": Object { - "amount0": "9.9700", - "amount1": "1.0412e+13", - }, - "collect": Object { - "amount0": "0.030000", - "amount1": "0.0000", - }, - "finalPrice": "0.97706", - "frontrun": Object { - "delta0": "2.3169", - "delta1": "-0.69788", - "executionPrice": "0.30121", - }, - "mint": Object { - "amount0": "0.0000", - "amount1": "1.0412e+13", - }, - "profit": Object { - "afterFrontrun": "-1.5727", - "afterSandwich": "7.3173", - "final": "8.8812", - }, - "sandwichedPrice": "0.091001", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 0; passive liquidity of 1.0000 exact input of 10e18 token0 with starting price of 1.0 and true price of 1.01 backrun to true price after swap only 1`] = ` -Object { - "arbBalanceDelta0": "9.9735", - "arbBalanceDelta1": "-0.91507", - "backrun": Object { - "delta0": "-9.9735", - "delta1": "0.91507", - "executionPrice": "0.091750", - }, - "finalPrice": "1.0070", - "profit": Object { - "final": "9.1581", - }, -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 0; passive liquidity of 1.0000 exact input of 10e18 token0 with starting price of 1.0 and true price of 1.01 not sandwiched 1`] = ` -Object { - "amount0Delta": "10.000", - "amount1Delta": "-0.90884", - "executionPrice": "0.090884", - "priceAfter": "0.0083097", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 0; passive liquidity of 1.0000 exact input of 10e18 token0 with starting price of 1.0 and true price of 1.01 sandwiched with swap to execution price then mint max liquidity/target/burn max liquidity 1`] = ` -Object { - "arbBalanceDelta0": "9.9965", - "arbBalanceDelta1": "-0.91560", - "backrun": Object { - "delta0": "-2.3134", - "delta1": "0.70347", - "executionPrice": "0.30408", - }, - "burn": Object { - "amount0": "9.9700", - "amount1": "1.0412e+13", - }, - "collect": Object { - "amount0": "0.030000", - "amount1": "0.0000", - }, - "finalPrice": "1.0070", - "frontrun": Object { - "delta0": "2.3169", - "delta1": "-0.69788", - "executionPrice": "0.30121", - }, - "mint": Object { - "amount0": "0.0000", - "amount1": "1.0412e+13", - }, - "profit": Object { - "afterFrontrun": "-1.6422", - "afterSandwich": "7.5478", - "final": "9.1809", - }, - "sandwichedPrice": "0.091001", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 0; passive liquidity of 10.000 exact input of 10e18 token0 with starting price of 1.0 and true price of 0.98 backrun to true price after swap only 1`] = ` -Object { - "arbBalanceDelta0": "9.8533", - "arbBalanceDelta1": "-4.8918", - "backrun": Object { - "delta0": "-9.8533", - "delta1": "4.8918", - "executionPrice": "0.49646", - }, - "finalPrice": "0.97706", - "profit": Object { - "final": "4.7644", - }, -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 0; passive liquidity of 10.000 exact input of 10e18 token0 with starting price of 1.0 and true price of 0.98 not sandwiched 1`] = ` -Object { - "amount0Delta": "10.000", - "amount1Delta": "-4.9925", - "executionPrice": "0.49925", - "priceAfter": "0.25075", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 0; passive liquidity of 10.000 exact input of 10e18 token0 with starting price of 1.0 and true price of 0.98 sandwiched with swap to execution price then mint max liquidity/target/burn max liquidity 1`] = ` -Object { - "arbBalanceDelta0": "9.8709", - "arbBalanceDelta1": "-4.8940", - "backrun": Object { - "delta0": "-4.0029", - "delta1": "2.8107", - "executionPrice": "0.70217", - }, - "burn": Object { - "amount0": "9.9700", - "amount1": "2.4408e+13", - }, - "collect": Object { - "amount0": "0.030000", - "amount1": "0.0000", - }, - "finalPrice": "0.97706", - "frontrun": Object { - "delta0": "4.1321", - "delta1": "-2.9177", - "executionPrice": "0.70611", - }, - "mint": Object { - "amount0": "0.0000", - "amount1": "2.4408e+13", - }, - "profit": Object { - "afterFrontrun": "-1.1317", - "afterSandwich": "3.6674", - "final": "4.7795", - }, - "sandwichedPrice": "0.50009", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 0; passive liquidity of 10.000 exact input of 10e18 token0 with starting price of 1.0 and true price of 1.01 backrun to true price after swap only 1`] = ` -Object { - "arbBalanceDelta0": "10.005", - "arbBalanceDelta1": "-5.0424", - "backrun": Object { - "delta0": "-10.005", - "delta1": "5.0424", - "executionPrice": "0.50401", - }, - "finalPrice": "1.0070", - "profit": Object { - "final": "5.0623", - }, -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 0; passive liquidity of 10.000 exact input of 10e18 token0 with starting price of 1.0 and true price of 1.01 not sandwiched 1`] = ` -Object { - "amount0Delta": "10.000", - "amount1Delta": "-4.9925", - "executionPrice": "0.49925", - "priceAfter": "0.25075", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 0; passive liquidity of 10.000 exact input of 10e18 token0 with starting price of 1.0 and true price of 1.01 sandwiched with swap to execution price then mint max liquidity/target/burn max liquidity 1`] = ` -Object { - "arbBalanceDelta0": "10.022", - "arbBalanceDelta1": "-5.0446", - "backrun": Object { - "delta0": "-4.1543", - "delta1": "2.9613", - "executionPrice": "0.71283", - }, - "burn": Object { - "amount0": "9.9700", - "amount1": "2.4408e+13", - }, - "collect": Object { - "amount0": "0.030000", - "amount1": "0.0000", - }, - "finalPrice": "1.0070", - "frontrun": Object { - "delta0": "4.1321", - "delta1": "-2.9177", - "executionPrice": "0.70611", - }, - "mint": Object { - "amount0": "0.0000", - "amount1": "2.4408e+13", - }, - "profit": Object { - "afterFrontrun": "-1.2557", - "afterSandwich": "3.8434", - "final": "5.0779", - }, - "sandwichedPrice": "0.50009", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 0; passive liquidity of 100.00 exact input of 10e18 token0 with starting price of 1.0 and true price of 0.98 backrun to true price after swap only 1`] = ` -Object { - "arbBalanceDelta0": "8.8029", - "arbBalanceDelta1": "-7.9363", - "backrun": Object { - "delta0": "-8.8029", - "delta1": "7.9363", - "executionPrice": "0.90155", - }, - "finalPrice": "0.97706", - "profit": Object { - "final": "0.69056", - }, -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 0; passive liquidity of 100.00 exact input of 10e18 token0 with starting price of 1.0 and true price of 0.98 not sandwiched 1`] = ` -Object { - "amount0Delta": "10.000", - "amount1Delta": "-9.0661", - "executionPrice": "0.90661", - "priceAfter": "0.82690", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 0; passive liquidity of 100.00 exact input of 10e18 token0 with starting price of 1.0 and true price of 0.98 sandwiched with swap to execution price then mint max liquidity/target/burn max liquidity 1`] = ` -Object { - "arbBalanceDelta0": "8.8190", - "arbBalanceDelta1": "-7.9680", - "backrun": Object { - "delta0": "-3.4354", - "delta1": "3.2562", - "executionPrice": "0.94781", - }, - "burn": Object { - "amount0": "9.9700", - "amount1": "3.2947e+13", - }, - "collect": Object { - "amount0": "0.030000", - "amount1": "0.0000", - }, - "finalPrice": "0.97706", - "frontrun": Object { - "delta0": "4.6164", - "delta1": "-4.4000", - "executionPrice": "0.95313", - }, - "mint": Object { - "amount0": "0.0000", - "amount1": "3.2947e+13", - }, - "profit": Object { - "afterFrontrun": "-0.12404", - "afterSandwich": "0.56403", - "final": "0.67460", - }, - "sandwichedPrice": "0.91119", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 0; passive liquidity of 100.00 exact input of 10e18 token0 with starting price of 1.0 and true price of 1.01 backrun to true price after swap only 1`] = ` -Object { - "arbBalanceDelta0": "10.317", - "arbBalanceDelta1": "-9.4423", - "backrun": Object { - "delta0": "-10.317", - "delta1": "9.4423", - "executionPrice": "0.91525", - }, - "finalPrice": "1.0070", - "profit": Object { - "final": "0.97752", - }, -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 0; passive liquidity of 100.00 exact input of 10e18 token0 with starting price of 1.0 and true price of 1.01 not sandwiched 1`] = ` -Object { - "amount0Delta": "10.000", - "amount1Delta": "-9.0661", - "executionPrice": "0.90661", - "priceAfter": "0.82690", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 0; passive liquidity of 100.00 exact input of 10e18 token0 with starting price of 1.0 and true price of 1.01 sandwiched with swap to execution price then mint max liquidity/target/burn max liquidity 1`] = ` -Object { - "arbBalanceDelta0": "10.333", - "arbBalanceDelta1": "-9.4741", - "backrun": Object { - "delta0": "-4.9492", - "delta1": "4.7622", - "executionPrice": "0.96221", - }, - "burn": Object { - "amount0": "9.9700", - "amount1": "3.2947e+13", - }, - "collect": Object { - "amount0": "0.030000", - "amount1": "0.0000", - }, - "finalPrice": "1.0070", - "frontrun": Object { - "delta0": "4.6164", - "delta1": "-4.4000", - "executionPrice": "0.95313", - }, - "mint": Object { - "amount0": "0.0000", - "amount1": "3.2947e+13", - }, - "profit": Object { - "afterFrontrun": "-0.26253", - "afterSandwich": "0.72554", - "final": "0.96205", - }, - "sandwichedPrice": "0.91119", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 6; passive liquidity of 0.010000 exact input of 10e18 token0 with starting price of 1.0 and true price of 0.98 backrun to true price after swap only 1`] = ` -Object { - "arbBalanceDelta0": "9.9699", - "arbBalanceDelta1": "-0.0099043", - "backrun": Object { - "delta0": "-9.9699", - "delta1": "0.0099043", - "executionPrice": "0.00099342", - }, - "finalPrice": "0.97706", - "profit": Object { - "final": "9.7606", - }, -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 6; passive liquidity of 0.010000 exact input of 10e18 token0 with starting price of 1.0 and true price of 0.98 not sandwiched 1`] = ` -Object { - "amount0Delta": "10.000", - "amount1Delta": "-0.0099900", - "executionPrice": "0.00099900", - "priceAfter": "0.0000010040", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 6; passive liquidity of 0.010000 exact input of 10e18 token0 with starting price of 1.0 and true price of 0.98 sandwiched with swap to execution price then mint max liquidity/target/burn max liquidity 1`] = ` -Object { - "arbBalanceDelta0": "9.9940", - "arbBalanceDelta1": "-0.0099044", - "backrun": Object { - "delta0": "-0.30578", - "delta1": "0.0095969", - "executionPrice": "0.031385", - }, - "burn": Object { - "amount0": "9.9700", - "amount1": "1.0910e+12", - }, - "collect": Object { - "amount0": "0.025000", - "amount1": "0.0000", - }, - "finalPrice": "0.97706", - "frontrun": Object { - "delta0": "0.30682", - "delta1": "-0.0096834", - "executionPrice": "0.031561", - }, - "mint": Object { - "amount0": "0.0000", - "amount1": "1.0910e+12", - }, - "profit": Object { - "afterFrontrun": "-0.29100", - "afterSandwich": "9.4941", - "final": "9.7842", - }, - "sandwichedPrice": "0.00099910", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 6; passive liquidity of 0.010000 exact input of 10e18 token0 with starting price of 1.0 and true price of 1.01 backrun to true price after swap only 1`] = ` -Object { - "arbBalanceDelta0": "9.9700", - "arbBalanceDelta1": "-0.010055", - "backrun": Object { - "delta0": "-9.9700", - "delta1": "0.010055", - "executionPrice": "0.0010085", - }, - "finalPrice": "1.0070", - "profit": Object { - "final": "10.060", - }, -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 6; passive liquidity of 0.010000 exact input of 10e18 token0 with starting price of 1.0 and true price of 1.01 not sandwiched 1`] = ` -Object { - "amount0Delta": "10.000", - "amount1Delta": "-0.0099900", - "executionPrice": "0.00099900", - "priceAfter": "0.0000010040", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 6; passive liquidity of 0.010000 exact input of 10e18 token0 with starting price of 1.0 and true price of 1.01 sandwiched with swap to execution price then mint max liquidity/target/burn max liquidity 1`] = ` -Object { - "arbBalanceDelta0": "9.9941", - "arbBalanceDelta1": "-0.010055", - "backrun": Object { - "delta0": "-0.30593", - "delta1": "0.0097475", - "executionPrice": "0.031862", - }, - "burn": Object { - "amount0": "9.9700", - "amount1": "1.0910e+12", - }, - "collect": Object { - "amount0": "0.025000", - "amount1": "0.0000", - }, - "finalPrice": "1.0070", - "frontrun": Object { - "delta0": "0.30682", - "delta1": "-0.0096834", - "executionPrice": "0.031561", - }, - "mint": Object { - "amount0": "0.0000", - "amount1": "1.0910e+12", - }, - "profit": Object { - "afterFrontrun": "-0.30020", - "afterSandwich": "9.7848", - "final": "10.084", - }, - "sandwichedPrice": "0.00099910", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 6; passive liquidity of 1.0000 exact input of 10e18 token0 with starting price of 1.0 and true price of 0.98 backrun to true price after swap only 1`] = ` -Object { - "arbBalanceDelta0": "9.9583", - "arbBalanceDelta1": "-0.90001", - "backrun": Object { - "delta0": "-9.9583", - "delta1": "0.90001", - "executionPrice": "0.090377", - }, - "finalPrice": "0.97706", - "profit": Object { - "final": "8.8592", - }, -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 6; passive liquidity of 1.0000 exact input of 10e18 token0 with starting price of 1.0 and true price of 0.98 not sandwiched 1`] = ` -Object { - "amount0Delta": "10.000", - "amount1Delta": "-0.90884", - "executionPrice": "0.090884", - "priceAfter": "0.0083097", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 6; passive liquidity of 1.0000 exact input of 10e18 token0 with starting price of 1.0 and true price of 0.98 sandwiched with swap to execution price then mint max liquidity/target/burn max liquidity 1`] = ` -Object { - "arbBalanceDelta0": "9.9764", - "arbBalanceDelta1": "-0.90054", - "backrun": Object { - "delta0": "-2.2983", - "delta1": "0.68841", - "executionPrice": "0.29953", - }, - "burn": Object { - "amount0": "9.9700", - "amount1": "1.0412e+13", - }, - "collect": Object { - "amount0": "0.025000", - "amount1": "0.0000", - }, - "finalPrice": "0.97706", - "frontrun": Object { - "delta0": "2.3169", - "delta1": "-0.69788", - "executionPrice": "0.30121", - }, - "mint": Object { - "amount0": "0.0000", - "amount1": "1.0412e+13", - }, - "profit": Object { - "afterFrontrun": "-1.5727", - "afterSandwich": "7.3124", - "final": "8.8763", - }, - "sandwichedPrice": "0.091001", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 6; passive liquidity of 1.0000 exact input of 10e18 token0 with starting price of 1.0 and true price of 1.01 backrun to true price after swap only 1`] = ` -Object { - "arbBalanceDelta0": "9.9735", - "arbBalanceDelta1": "-0.91507", - "backrun": Object { - "delta0": "-9.9735", - "delta1": "0.91507", - "executionPrice": "0.091750", - }, - "finalPrice": "1.0070", - "profit": Object { - "final": "9.1581", - }, -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 6; passive liquidity of 1.0000 exact input of 10e18 token0 with starting price of 1.0 and true price of 1.01 not sandwiched 1`] = ` -Object { - "amount0Delta": "10.000", - "amount1Delta": "-0.90884", - "executionPrice": "0.090884", - "priceAfter": "0.0083097", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 6; passive liquidity of 1.0000 exact input of 10e18 token0 with starting price of 1.0 and true price of 1.01 sandwiched with swap to execution price then mint max liquidity/target/burn max liquidity 1`] = ` -Object { - "arbBalanceDelta0": "9.9915", - "arbBalanceDelta1": "-0.91560", - "backrun": Object { - "delta0": "-2.3134", - "delta1": "0.70347", - "executionPrice": "0.30408", - }, - "burn": Object { - "amount0": "9.9700", - "amount1": "1.0412e+13", - }, - "collect": Object { - "amount0": "0.025000", - "amount1": "0.0000", - }, - "finalPrice": "1.0070", - "frontrun": Object { - "delta0": "2.3169", - "delta1": "-0.69788", - "executionPrice": "0.30121", - }, - "mint": Object { - "amount0": "0.0000", - "amount1": "1.0412e+13", - }, - "profit": Object { - "afterFrontrun": "-1.6422", - "afterSandwich": "7.5427", - "final": "9.1758", - }, - "sandwichedPrice": "0.091001", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 6; passive liquidity of 10.000 exact input of 10e18 token0 with starting price of 1.0 and true price of 0.98 backrun to true price after swap only 1`] = ` -Object { - "arbBalanceDelta0": "9.8533", - "arbBalanceDelta1": "-4.8918", - "backrun": Object { - "delta0": "-9.8533", - "delta1": "4.8918", - "executionPrice": "0.49646", - }, - "finalPrice": "0.97706", - "profit": Object { - "final": "4.7644", - }, -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 6; passive liquidity of 10.000 exact input of 10e18 token0 with starting price of 1.0 and true price of 0.98 not sandwiched 1`] = ` -Object { - "amount0Delta": "10.000", - "amount1Delta": "-4.9925", - "executionPrice": "0.49925", - "priceAfter": "0.25075", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 6; passive liquidity of 10.000 exact input of 10e18 token0 with starting price of 1.0 and true price of 0.98 sandwiched with swap to execution price then mint max liquidity/target/burn max liquidity 1`] = ` -Object { - "arbBalanceDelta0": "9.8659", - "arbBalanceDelta1": "-4.8940", - "backrun": Object { - "delta0": "-4.0029", - "delta1": "2.8107", - "executionPrice": "0.70217", - }, - "burn": Object { - "amount0": "9.9700", - "amount1": "2.4408e+13", - }, - "collect": Object { - "amount0": "0.025000", - "amount1": "0.0000", - }, - "finalPrice": "0.97706", - "frontrun": Object { - "delta0": "4.1321", - "delta1": "-2.9177", - "executionPrice": "0.70611", - }, - "mint": Object { - "amount0": "0.0000", - "amount1": "2.4408e+13", - }, - "profit": Object { - "afterFrontrun": "-1.1317", - "afterSandwich": "3.6625", - "final": "4.7746", - }, - "sandwichedPrice": "0.50009", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 6; passive liquidity of 10.000 exact input of 10e18 token0 with starting price of 1.0 and true price of 1.01 backrun to true price after swap only 1`] = ` -Object { - "arbBalanceDelta0": "10.005", - "arbBalanceDelta1": "-5.0424", - "backrun": Object { - "delta0": "-10.005", - "delta1": "5.0424", - "executionPrice": "0.50401", - }, - "finalPrice": "1.0070", - "profit": Object { - "final": "5.0623", - }, -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 6; passive liquidity of 10.000 exact input of 10e18 token0 with starting price of 1.0 and true price of 1.01 not sandwiched 1`] = ` -Object { - "amount0Delta": "10.000", - "amount1Delta": "-4.9925", - "executionPrice": "0.49925", - "priceAfter": "0.25075", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 6; passive liquidity of 10.000 exact input of 10e18 token0 with starting price of 1.0 and true price of 1.01 sandwiched with swap to execution price then mint max liquidity/target/burn max liquidity 1`] = ` -Object { - "arbBalanceDelta0": "10.017", - "arbBalanceDelta1": "-5.0446", - "backrun": Object { - "delta0": "-4.1543", - "delta1": "2.9613", - "executionPrice": "0.71283", - }, - "burn": Object { - "amount0": "9.9700", - "amount1": "2.4408e+13", - }, - "collect": Object { - "amount0": "0.025000", - "amount1": "0.0000", - }, - "finalPrice": "1.0070", - "frontrun": Object { - "delta0": "4.1321", - "delta1": "-2.9177", - "executionPrice": "0.70611", - }, - "mint": Object { - "amount0": "0.0000", - "amount1": "2.4408e+13", - }, - "profit": Object { - "afterFrontrun": "-1.2557", - "afterSandwich": "3.8384", - "final": "5.0729", - }, - "sandwichedPrice": "0.50009", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 6; passive liquidity of 100.00 exact input of 10e18 token0 with starting price of 1.0 and true price of 0.98 backrun to true price after swap only 1`] = ` -Object { - "arbBalanceDelta0": "8.8029", - "arbBalanceDelta1": "-7.9363", - "backrun": Object { - "delta0": "-8.8029", - "delta1": "7.9363", - "executionPrice": "0.90155", - }, - "finalPrice": "0.97706", - "profit": Object { - "final": "0.69056", - }, -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 6; passive liquidity of 100.00 exact input of 10e18 token0 with starting price of 1.0 and true price of 0.98 not sandwiched 1`] = ` -Object { - "amount0Delta": "10.000", - "amount1Delta": "-9.0661", - "executionPrice": "0.90661", - "priceAfter": "0.82690", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 6; passive liquidity of 100.00 exact input of 10e18 token0 with starting price of 1.0 and true price of 0.98 sandwiched with swap to execution price then mint max liquidity/target/burn max liquidity 1`] = ` -Object { - "arbBalanceDelta0": "8.8140", - "arbBalanceDelta1": "-7.9680", - "backrun": Object { - "delta0": "-3.4354", - "delta1": "3.2562", - "executionPrice": "0.94781", - }, - "burn": Object { - "amount0": "9.9700", - "amount1": "3.2947e+13", - }, - "collect": Object { - "amount0": "0.025000", - "amount1": "0.0000", - }, - "finalPrice": "0.97706", - "frontrun": Object { - "delta0": "4.6164", - "delta1": "-4.4000", - "executionPrice": "0.95313", - }, - "mint": Object { - "amount0": "0.0000", - "amount1": "3.2947e+13", - }, - "profit": Object { - "afterFrontrun": "-0.12404", - "afterSandwich": "0.55913", - "final": "0.66970", - }, - "sandwichedPrice": "0.91119", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 6; passive liquidity of 100.00 exact input of 10e18 token0 with starting price of 1.0 and true price of 1.01 backrun to true price after swap only 1`] = ` -Object { - "arbBalanceDelta0": "10.317", - "arbBalanceDelta1": "-9.4423", - "backrun": Object { - "delta0": "-10.317", - "delta1": "9.4423", - "executionPrice": "0.91525", - }, - "finalPrice": "1.0070", - "profit": Object { - "final": "0.97752", - }, -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 6; passive liquidity of 100.00 exact input of 10e18 token0 with starting price of 1.0 and true price of 1.01 not sandwiched 1`] = ` -Object { - "amount0Delta": "10.000", - "amount1Delta": "-9.0661", - "executionPrice": "0.90661", - "priceAfter": "0.82690", -} -`; - -exports[`UniswapV3Pool arbitrage tests protocol fee = 6; passive liquidity of 100.00 exact input of 10e18 token0 with starting price of 1.0 and true price of 1.01 sandwiched with swap to execution price then mint max liquidity/target/burn max liquidity 1`] = ` -Object { - "arbBalanceDelta0": "10.328", - "arbBalanceDelta1": "-9.4741", - "backrun": Object { - "delta0": "-4.9492", - "delta1": "4.7622", - "executionPrice": "0.96221", - }, - "burn": Object { - "amount0": "9.9700", - "amount1": "3.2947e+13", - }, - "collect": Object { - "amount0": "0.025000", - "amount1": "0.0000", - }, - "finalPrice": "1.0070", - "frontrun": Object { - "delta0": "4.6164", - "delta1": "-4.4000", - "executionPrice": "0.95313", - }, - "mint": Object { - "amount0": "0.0000", - "amount1": "3.2947e+13", - }, - "profit": Object { - "afterFrontrun": "-0.26253", - "afterSandwich": "0.72049", - "final": "0.95700", - }, - "sandwichedPrice": "0.91119", -} -`; diff --git a/lib/v3-core/test/__snapshots__/UniswapV3Pool.gas.spec.ts.snap b/lib/v3-core/test/__snapshots__/UniswapV3Pool.gas.spec.ts.snap deleted file mode 100644 index 37bc657..0000000 --- a/lib/v3-core/test/__snapshots__/UniswapV3Pool.gas.spec.ts.snap +++ /dev/null @@ -1,169 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`UniswapV3Pool gas tests fee is off #burn above current price burn entire position after some time passes 1`] = `58703`; - -exports[`UniswapV3Pool gas tests fee is off #burn above current price burn when only position using ticks 1`] = `58703`; - -exports[`UniswapV3Pool gas tests fee is off #burn above current price entire position burn but other positions are using the ticks 1`] = `82740`; - -exports[`UniswapV3Pool gas tests fee is off #burn above current price partial position burn 1`] = `97740`; - -exports[`UniswapV3Pool gas tests fee is off #burn around current price burn entire position after some time passes 1`] = `69498`; - -exports[`UniswapV3Pool gas tests fee is off #burn around current price burn when only position using ticks 1`] = `66309`; - -exports[`UniswapV3Pool gas tests fee is off #burn around current price entire position burn but other positions are using the ticks 1`] = `87551`; - -exports[`UniswapV3Pool gas tests fee is off #burn around current price partial position burn 1`] = `102551`; - -exports[`UniswapV3Pool gas tests fee is off #burn below current price burn entire position after some time passes 1`] = `64624`; - -exports[`UniswapV3Pool gas tests fee is off #burn below current price burn when only position using ticks 1`] = `64624`; - -exports[`UniswapV3Pool gas tests fee is off #burn below current price entire position burn but other positions are using the ticks 1`] = `83381`; - -exports[`UniswapV3Pool gas tests fee is off #burn below current price partial position burn 1`] = `98381`; - -exports[`UniswapV3Pool gas tests fee is off #collect close to worst case 1`] = `35816`; - -exports[`UniswapV3Pool gas tests fee is off #increaseObservationCardinalityNext grow by 1 slot 1`] = `51098`; - -exports[`UniswapV3Pool gas tests fee is off #increaseObservationCardinalityNext no op 1`] = `24677`; - -exports[`UniswapV3Pool gas tests fee is off #mint above current price add to position after some time passes 1`] = `109351`; - -exports[`UniswapV3Pool gas tests fee is off #mint above current price add to position existing 1`] = `109351`; - -exports[`UniswapV3Pool gas tests fee is off #mint above current price new position mint first in range 1`] = `228025`; - -exports[`UniswapV3Pool gas tests fee is off #mint above current price second position in same range 1`] = `126451`; - -exports[`UniswapV3Pool gas tests fee is off #mint around current price add to position after some time passes 1`] = `147718`; - -exports[`UniswapV3Pool gas tests fee is off #mint around current price add to position existing 1`] = `138539`; - -exports[`UniswapV3Pool gas tests fee is off #mint around current price new position mint first in range 1`] = `328848`; - -exports[`UniswapV3Pool gas tests fee is off #mint around current price second position in same range 1`] = `155639`; - -exports[`UniswapV3Pool gas tests fee is off #mint below current price add to position after some time passes 1`] = `109943`; - -exports[`UniswapV3Pool gas tests fee is off #mint below current price add to position existing 1`] = `109943`; - -exports[`UniswapV3Pool gas tests fee is off #mint below current price new position mint first in range 1`] = `309729`; - -exports[`UniswapV3Pool gas tests fee is off #mint below current price second position in same range 1`] = `127043`; - -exports[`UniswapV3Pool gas tests fee is off #poke best case 1`] = `52006`; - -exports[`UniswapV3Pool gas tests fee is off #snapshotCumulativesInside tick above 1`] = `29643`; - -exports[`UniswapV3Pool gas tests fee is off #snapshotCumulativesInside tick below 1`] = `29605`; - -exports[`UniswapV3Pool gas tests fee is off #snapshotCumulativesInside tick inside 1`] = `37053`; - -exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 first swap in block moves tick, no initialized crossings 1`] = `114858`; - -exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 first swap in block with no tick movement 1`] = `99004`; - -exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 first swap in block, large swap crossing a single initialized tick 1`] = `129871`; - -exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 first swap in block, large swap crossing several initialized ticks 1`] = `152706`; - -exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 first swap in block, large swap, no initialized crossings 1`] = `129469`; - -exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 large swap crossing several initialized ticks after some time passes 1`] = `152706`; - -exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 large swap crossing several initialized ticks second time after some time passes 1`] = `212706`; - -exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 second swap in block moves tick, no initialized crossings 1`] = `114858`; - -exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 second swap in block with no tick movement 1`] = `99115`; - -exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 second swap in block, large swap crossing a single initialized tick 1`] = `116454`; - -exports[`UniswapV3Pool gas tests fee is off #swapExact0For1 second swap in block, large swap crossing several initialized ticks 1`] = `139267`; - -exports[`UniswapV3Pool gas tests fee is on #burn above current price burn entire position after some time passes 1`] = `58703`; - -exports[`UniswapV3Pool gas tests fee is on #burn above current price burn when only position using ticks 1`] = `58703`; - -exports[`UniswapV3Pool gas tests fee is on #burn above current price entire position burn but other positions are using the ticks 1`] = `82740`; - -exports[`UniswapV3Pool gas tests fee is on #burn above current price partial position burn 1`] = `97740`; - -exports[`UniswapV3Pool gas tests fee is on #burn around current price burn entire position after some time passes 1`] = `69498`; - -exports[`UniswapV3Pool gas tests fee is on #burn around current price burn when only position using ticks 1`] = `66309`; - -exports[`UniswapV3Pool gas tests fee is on #burn around current price entire position burn but other positions are using the ticks 1`] = `87551`; - -exports[`UniswapV3Pool gas tests fee is on #burn around current price partial position burn 1`] = `102551`; - -exports[`UniswapV3Pool gas tests fee is on #burn below current price burn entire position after some time passes 1`] = `64624`; - -exports[`UniswapV3Pool gas tests fee is on #burn below current price burn when only position using ticks 1`] = `64624`; - -exports[`UniswapV3Pool gas tests fee is on #burn below current price entire position burn but other positions are using the ticks 1`] = `83381`; - -exports[`UniswapV3Pool gas tests fee is on #burn below current price partial position burn 1`] = `98381`; - -exports[`UniswapV3Pool gas tests fee is on #collect close to worst case 1`] = `35816`; - -exports[`UniswapV3Pool gas tests fee is on #increaseObservationCardinalityNext grow by 1 slot 1`] = `51098`; - -exports[`UniswapV3Pool gas tests fee is on #increaseObservationCardinalityNext no op 1`] = `24677`; - -exports[`UniswapV3Pool gas tests fee is on #mint above current price add to position after some time passes 1`] = `109363`; - -exports[`UniswapV3Pool gas tests fee is on #mint above current price add to position existing 1`] = `109363`; - -exports[`UniswapV3Pool gas tests fee is on #mint above current price new position mint first in range 1`] = `228037`; - -exports[`UniswapV3Pool gas tests fee is on #mint above current price second position in same range 1`] = `126463`; - -exports[`UniswapV3Pool gas tests fee is on #mint around current price add to position after some time passes 1`] = `147730`; - -exports[`UniswapV3Pool gas tests fee is on #mint around current price add to position existing 1`] = `138551`; - -exports[`UniswapV3Pool gas tests fee is on #mint around current price new position mint first in range 1`] = `328860`; - -exports[`UniswapV3Pool gas tests fee is on #mint around current price second position in same range 1`] = `155651`; - -exports[`UniswapV3Pool gas tests fee is on #mint below current price add to position after some time passes 1`] = `109955`; - -exports[`UniswapV3Pool gas tests fee is on #mint below current price add to position existing 1`] = `109955`; - -exports[`UniswapV3Pool gas tests fee is on #mint below current price new position mint first in range 1`] = `309741`; - -exports[`UniswapV3Pool gas tests fee is on #mint below current price second position in same range 1`] = `127055`; - -exports[`UniswapV3Pool gas tests fee is on #poke best case 1`] = `52006`; - -exports[`UniswapV3Pool gas tests fee is on #snapshotCumulativesInside tick above 1`] = `29643`; - -exports[`UniswapV3Pool gas tests fee is on #snapshotCumulativesInside tick below 1`] = `29605`; - -exports[`UniswapV3Pool gas tests fee is on #snapshotCumulativesInside tick inside 1`] = `37053`; - -exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 first swap in block moves tick, no initialized crossings 1`] = `120257`; - -exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 first swap in block with no tick movement 1`] = `104256`; - -exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 first swap in block, large swap crossing a single initialized tick 1`] = `135417`; - -exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 first swap in block, large swap crossing several initialized ticks 1`] = `158693`; - -exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 first swap in block, large swap, no initialized crossings 1`] = `135162`; - -exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 large swap crossing several initialized ticks after some time passes 1`] = `158693`; - -exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 large swap crossing several initialized ticks second time after some time passes 1`] = `218693`; - -exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 second swap in block moves tick, no initialized crossings 1`] = `120257`; - -exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 second swap in block with no tick movement 1`] = `104367`; - -exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 second swap in block, large swap crossing a single initialized tick 1`] = `121853`; - -exports[`UniswapV3Pool gas tests fee is on #swapExact0For1 second swap in block, large swap crossing several initialized ticks 1`] = `145107`; diff --git a/lib/v3-core/test/__snapshots__/UniswapV3Pool.swaps.spec.ts.snap b/lib/v3-core/test/__snapshots__/UniswapV3Pool.swaps.spec.ts.snap deleted file mode 100644 index e36c7c0..0000000 --- a/lib/v3-core/test/__snapshots__/UniswapV3Pool.swaps.spec.ts.snap +++ /dev/null @@ -1,3541 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`UniswapV3Pool swap tests close to max price swap exactly 0.0000000000000010000 token0 for token1 1`] = ` -Object { - "amount0Before": "1", - "amount0Delta": "1000", - "amount1Before": "26087635650665564424699143612505016738", - "amount1Delta": "-26083549850867114346332688477747755628", - "executionPrice": "2.6084e+34", - "feeGrowthGlobal0X128Delta": "2381976568446569244235", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "4.1734e+30", - "poolPriceBefore": "1.7014e+38", - "tickAfter": 705098, - "tickBefore": 880340, -} -`; - -exports[`UniswapV3Pool swap tests close to max price swap exactly 0.0000000000000010000 token1 for token0 1`] = ` -Object { - "amount0Before": "1", - "amount0Delta": "0", - "amount1Before": "26087635650665564424699143612505016738", - "amount1Delta": "1000", - "executionPrice": "-Infinity", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "510423550381407695195", - "poolPriceAfter": "1.7014e+38", - "poolPriceBefore": "1.7014e+38", - "tickAfter": 880340, - "tickBefore": 880340, -} -`; - -exports[`UniswapV3Pool swap tests close to max price swap exactly 1.0000 token0 for token1 1`] = ` -Object { - "amount0Before": "1", - "amount0Delta": "1000000000000000000", - "amount1Before": "26087635650665564424699143612505016738", - "amount1Delta": "-26087635650665564420687107504180041533", - "executionPrice": "2.6088e+19", - "feeGrowthGlobal0X128Delta": "510423550381413479995299567101531162", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "4.0241", - "poolPriceBefore": "1.7014e+38", - "tickAfter": 13923, - "tickBefore": 880340, -} -`; - -exports[`UniswapV3Pool swap tests close to max price swap exactly 1.0000 token0 for token1 to price 0.50000 1`] = ` -Object { - "amount0Before": "1", - "amount0Delta": "1000000000000000000", - "amount1Before": "26087635650665564424699143612505016738", - "amount1Delta": "-26087635650665564420687107504180041533", - "executionPrice": "2.6088e+19", - "feeGrowthGlobal0X128Delta": "510423550381413479995299567101531162", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "4.0241", - "poolPriceBefore": "1.7014e+38", - "tickAfter": 13923, - "tickBefore": 880340, -} -`; - -exports[`UniswapV3Pool swap tests close to max price swap exactly 1.0000 token1 for token0 1`] = ` -Object { - "amount0Before": "1", - "amount0Delta": "0", - "amount1Before": "26087635650665564424699143612505016738", - "amount1Delta": "1000000000000000000", - "executionPrice": "-Infinity", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "510423550381407695195061911147652317", - "poolPriceAfter": "1.7014e+38", - "poolPriceBefore": "1.7014e+38", - "tickAfter": 880340, - "tickBefore": 880340, -} -`; - -exports[`UniswapV3Pool swap tests close to max price swap exactly 1.0000 token1 for token0 to price 2.0000 1`] = ` -Object { - "poolBalance0": "1", - "poolBalance1": "26087635650665564424699143612505016738", - "poolPriceBefore": "1.7014e+38", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 880340, -} -`; - -exports[`UniswapV3Pool swap tests close to max price swap token0 for exactly 0.0000000000000010000 token1 1`] = ` -Object { - "amount0Before": "1", - "amount0Delta": "2", - "amount1Before": "26087635650665564424699143612505016738", - "amount1Delta": "-1000", - "executionPrice": "500.00", - "feeGrowthGlobal0X128Delta": "170141183460469231731", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "1.7014e+38", - "poolPriceBefore": "1.7014e+38", - "tickAfter": 880340, - "tickBefore": 880340, -} -`; - -exports[`UniswapV3Pool swap tests close to max price swap token0 for exactly 1.0000 token1 1`] = ` -Object { - "amount0Before": "1", - "amount0Delta": "2", - "amount1Before": "26087635650665564424699143612505016738", - "amount1Delta": "-1000000000000000000", - "executionPrice": "5.0000e+17", - "feeGrowthGlobal0X128Delta": "170141183460469231731", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "1.7014e+38", - "poolPriceBefore": "1.7014e+38", - "tickAfter": 880340, - "tickBefore": 880340, -} -`; - -exports[`UniswapV3Pool swap tests close to max price swap token0 for exactly 1.0000 token1 to price 0.50000 1`] = ` -Object { - "amount0Before": "1", - "amount0Delta": "2", - "amount1Before": "26087635650665564424699143612505016738", - "amount1Delta": "-1000000000000000000", - "executionPrice": "5.0000e+17", - "feeGrowthGlobal0X128Delta": "170141183460469231731", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "1.7014e+38", - "poolPriceBefore": "1.7014e+38", - "tickAfter": 880340, - "tickBefore": 880340, -} -`; - -exports[`UniswapV3Pool swap tests close to max price swap token0 for token1 to price 0.40000 1`] = ` -Object { - "amount0Before": "1", - "amount0Delta": "3171793039286238109", - "amount1Before": "26087635650665564424699143612505016738", - "amount1Delta": "-26087635650665564423434232548437664977", - "executionPrice": "8.2249e+18", - "feeGrowthGlobal0X128Delta": "1618957864187523123655042148763283097", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.40000", - "poolPriceBefore": "1.7014e+38", - "tickAfter": -9164, - "tickBefore": 880340, -} -`; - -exports[`UniswapV3Pool swap tests close to max price swap token0 for token1 to price 2.5000 1`] = ` -Object { - "amount0Before": "1", - "amount0Delta": "1268717215714495281", - "amount1Before": "26087635650665564424699143612505016738", - "amount1Delta": "-26087635650665564421536865952336637378", - "executionPrice": "2.0562e+19", - "feeGrowthGlobal0X128Delta": "647583145675012618257449376796101507", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "2.5000", - "poolPriceBefore": "1.7014e+38", - "tickAfter": 9163, - "tickBefore": 880340, -} -`; - -exports[`UniswapV3Pool swap tests close to max price swap token1 for exactly 0.0000000000000010000 token0 1`] = ` -Object { - "amount0Before": "1", - "amount0Delta": "0", - "amount1Before": "26087635650665564424699143612505016738", - "amount1Delta": "10740898373457544742072477595619363803", - "executionPrice": "-Infinity", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "5482407482066087054477299856254072312542046383926535301", - "poolPriceAfter": "3.4026e+38", - "poolPriceBefore": "1.7014e+38", - "tickAfter": 887271, - "tickBefore": 880340, -} -`; - -exports[`UniswapV3Pool swap tests close to max price swap token1 for exactly 1.0000 token0 1`] = ` -Object { - "amount0Before": "1", - "amount0Delta": "0", - "amount1Before": "26087635650665564424699143612505016738", - "amount1Delta": "10740898373457544742072477595619363803", - "executionPrice": "-Infinity", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "5482407482066087054477299856254072312542046383926535301", - "poolPriceAfter": "3.4026e+38", - "poolPriceBefore": "1.7014e+38", - "tickAfter": 887271, - "tickBefore": 880340, -} -`; - -exports[`UniswapV3Pool swap tests close to max price swap token1 for exactly 1.0000 token0 to price 2.0000 1`] = ` -Object { - "poolBalance0": "1", - "poolBalance1": "26087635650665564424699143612505016738", - "poolPriceBefore": "1.7014e+38", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 880340, -} -`; - -exports[`UniswapV3Pool swap tests close to max price swap token1 for token0 to price 0.40000 1`] = ` -Object { - "poolBalance0": "1", - "poolBalance1": "26087635650665564424699143612505016738", - "poolPriceBefore": "1.7014e+38", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 880340, -} -`; - -exports[`UniswapV3Pool swap tests close to max price swap token1 for token0 to price 2.5000 1`] = ` -Object { - "poolBalance0": "1", - "poolBalance1": "26087635650665564424699143612505016738", - "poolPriceBefore": "1.7014e+38", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 880340, -} -`; - -exports[`UniswapV3Pool swap tests close to min price swap exactly 0.0000000000000010000 token0 for token1 1`] = ` -Object { - "amount0Before": "26037782196502120275425782622539039026", - "amount0Delta": "1000", - "amount1Before": "1", - "amount1Delta": "0", - "executionPrice": "0.0000", - "feeGrowthGlobal0X128Delta": "170141183460469231731687", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.0000000000000000000000000000000000000059000", - "poolPriceBefore": "0.0000000000000000000000000000000000000059000", - "tickAfter": -880303, - "tickBefore": -880303, -} -`; - -exports[`UniswapV3Pool swap tests close to min price swap exactly 0.0000000000000010000 token1 for token0 1`] = ` -Object { - "amount0Before": "26037782196502120275425782622539039026", - "amount0Delta": "-26033697540846965126433148994127431276", - "amount1Before": "1", - "amount1Delta": "1000", - "executionPrice": "0.000000000000000000000000000000000038412", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "2381976568446569244235", - "poolPriceAfter": "0.00000000000000000000000000000023974", - "poolPriceBefore": "0.0000000000000000000000000000000000000059000", - "tickAfter": -705093, - "tickBefore": -880303, -} -`; - -exports[`UniswapV3Pool swap tests close to min price swap exactly 1.0000 token0 for token1 1`] = ` -Object { - "amount0Before": "26037782196502120275425782622539039026", - "amount0Delta": "1000000000000000000", - "amount1Before": "1", - "amount1Delta": "0", - "executionPrice": "0.0000", - "feeGrowthGlobal0X128Delta": "170141183460469231731687303715884105728", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.0000000000000000000000000000000000000059000", - "poolPriceBefore": "0.0000000000000000000000000000000000000059000", - "tickAfter": -880303, - "tickBefore": -880303, -} -`; - -exports[`UniswapV3Pool swap tests close to min price swap exactly 1.0000 token0 for token1 to price 0.50000 1`] = ` -Object { - "poolBalance0": "26037782196502120275425782622539039026", - "poolBalance1": "1", - "poolPriceBefore": "0.0000000000000000000000000000000000000059000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": -880303, -} -`; - -exports[`UniswapV3Pool swap tests close to min price swap exactly 1.0000 token1 for token0 1`] = ` -Object { - "amount0Before": "26037782196502120275425782622539039026", - "amount0Delta": "-26037782196502120271413746514214063808", - "amount1Before": "1", - "amount1Delta": "1000000000000000000", - "executionPrice": "0.000000000000000000038406", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "510423550381413820277666488039994629", - "poolPriceAfter": "0.24850", - "poolPriceBefore": "0.0000000000000000000000000000000000000059000", - "tickAfter": -13924, - "tickBefore": -880303, -} -`; - -exports[`UniswapV3Pool swap tests close to min price swap exactly 1.0000 token1 for token0 to price 2.0000 1`] = ` -Object { - "amount0Before": "26037782196502120275425782622539039026", - "amount0Delta": "-26037782196502120271413746514214063808", - "amount1Before": "1", - "amount1Delta": "1000000000000000000", - "executionPrice": "0.000000000000000000038406", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "510423550381413820277666488039994629", - "poolPriceAfter": "0.24850", - "poolPriceBefore": "0.0000000000000000000000000000000000000059000", - "tickAfter": -13924, - "tickBefore": -880303, -} -`; - -exports[`UniswapV3Pool swap tests close to min price swap token0 for exactly 0.0000000000000010000 token1 1`] = ` -Object { - "amount0Before": "26037782196502120275425782622539039026", - "amount0Delta": "10790901831095468191587263901270792610", - "amount1Before": "1", - "amount1Delta": "0", - "executionPrice": "0.0000", - "feeGrowthGlobal0X128Delta": "5507930424444982259736347157352787128931407551935325049", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.0000000000000000000000000000000000000029390", - "poolPriceBefore": "0.0000000000000000000000000000000000000059000", - "tickAfter": -887272, - "tickBefore": -880303, -} -`; - -exports[`UniswapV3Pool swap tests close to min price swap token0 for exactly 1.0000 token1 1`] = ` -Object { - "amount0Before": "26037782196502120275425782622539039026", - "amount0Delta": "10790901831095468191587263901270792610", - "amount1Before": "1", - "amount1Delta": "0", - "executionPrice": "0.0000", - "feeGrowthGlobal0X128Delta": "5507930424444982259736347157352787128931407551935325049", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.0000000000000000000000000000000000000029390", - "poolPriceBefore": "0.0000000000000000000000000000000000000059000", - "tickAfter": -887272, - "tickBefore": -880303, -} -`; - -exports[`UniswapV3Pool swap tests close to min price swap token0 for exactly 1.0000 token1 to price 0.50000 1`] = ` -Object { - "poolBalance0": "26037782196502120275425782622539039026", - "poolBalance1": "1", - "poolPriceBefore": "0.0000000000000000000000000000000000000059000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": -880303, -} -`; - -exports[`UniswapV3Pool swap tests close to min price swap token0 for token1 to price 0.40000 1`] = ` -Object { - "poolBalance0": "26037782196502120275425782622539039026", - "poolBalance1": "1", - "poolPriceBefore": "0.0000000000000000000000000000000000000059000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": -880303, -} -`; - -exports[`UniswapV3Pool swap tests close to min price swap token0 for token1 to price 2.5000 1`] = ` -Object { - "poolBalance0": "26037782196502120275425782622539039026", - "poolBalance1": "1", - "poolPriceBefore": "0.0000000000000000000000000000000000000059000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": -880303, -} -`; - -exports[`UniswapV3Pool swap tests close to min price swap token1 for exactly 0.0000000000000010000 token0 1`] = ` -Object { - "amount0Before": "26037782196502120275425782622539039026", - "amount0Delta": "-1000", - "amount1Before": "1", - "amount1Delta": "2", - "executionPrice": "0.0020000", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "170141183460469231731", - "poolPriceAfter": "0.0000000000000000000000000000000000000059000", - "poolPriceBefore": "0.0000000000000000000000000000000000000059000", - "tickAfter": -880303, - "tickBefore": -880303, -} -`; - -exports[`UniswapV3Pool swap tests close to min price swap token1 for exactly 1.0000 token0 1`] = ` -Object { - "amount0Before": "26037782196502120275425782622539039026", - "amount0Delta": "-1000000000000000000", - "amount1Before": "1", - "amount1Delta": "2", - "executionPrice": "0.0000000000000000020000", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "170141183460469231731", - "poolPriceAfter": "0.0000000000000000000000000000000000000059000", - "poolPriceBefore": "0.0000000000000000000000000000000000000059000", - "tickAfter": -880303, - "tickBefore": -880303, -} -`; - -exports[`UniswapV3Pool swap tests close to min price swap token1 for exactly 1.0000 token0 to price 2.0000 1`] = ` -Object { - "amount0Before": "26037782196502120275425782622539039026", - "amount0Delta": "-1000000000000000000", - "amount1Before": "1", - "amount1Delta": "2", - "executionPrice": "0.0000000000000000020000", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "170141183460469231731", - "poolPriceAfter": "0.0000000000000000000000000000000000000059000", - "poolPriceBefore": "0.0000000000000000000000000000000000000059000", - "tickAfter": -880303, - "tickBefore": -880303, -} -`; - -exports[`UniswapV3Pool swap tests close to min price swap token1 for token0 to price 0.40000 1`] = ` -Object { - "amount0Before": "26037782196502120275425782622539039026", - "amount0Delta": "-26037782196502120272263504962370659661", - "amount1Before": "1", - "amount1Delta": "1268717215714495283", - "executionPrice": "0.000000000000000000048726", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "647583145675012958539816297734564973", - "poolPriceAfter": "0.40000", - "poolPriceBefore": "0.0000000000000000000000000000000000000059000", - "tickAfter": -9164, - "tickBefore": -880303, -} -`; - -exports[`UniswapV3Pool swap tests close to min price swap token1 for token0 to price 2.5000 1`] = ` -Object { - "amount0Before": "26037782196502120275425782622539039026", - "amount0Delta": "-26037782196502120274160871558471687260", - "amount1Before": "1", - "amount1Delta": "3171793039286238112", - "executionPrice": "0.00000000000000000012182", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "1618957864187523634078592530170978294", - "poolPriceAfter": "2.5000", - "poolPriceBefore": "0.0000000000000000000000000000000000000059000", - "tickAfter": 9163, - "tickBefore": -880303, -} -`; - -exports[`UniswapV3Pool swap tests high fee, 1:1 price, 2e18 max range liquidity swap exactly 0.0000000000000010000 token0 for token1 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "1000", - "amount1Before": "2000000000000000000", - "amount1Delta": "-989", - "executionPrice": "0.98900", - "feeGrowthGlobal0X128Delta": "1701411834604692317316", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": -1, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests high fee, 1:1 price, 2e18 max range liquidity swap exactly 0.0000000000000010000 token1 for token0 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "-989", - "amount1Before": "2000000000000000000", - "amount1Delta": "1000", - "executionPrice": "1.0111", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "1701411834604692317316", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 0, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests high fee, 1:1 price, 2e18 max range liquidity swap exactly 1.0000 token0 for token1 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "1000000000000000000", - "amount1Before": "2000000000000000000", - "amount1Delta": "-662207357859531772", - "executionPrice": "0.66221", - "feeGrowthGlobal0X128Delta": "1701411834604692317316873037158841057", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.44742", - "poolPriceBefore": "1.0000", - "tickAfter": -8043, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests high fee, 1:1 price, 2e18 max range liquidity swap exactly 1.0000 token0 for token1 to price 0.50000 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "836795075501202120", - "amount1Before": "2000000000000000000", - "amount1Delta": "-585786437626904951", - "executionPrice": "0.70004", - "feeGrowthGlobal0X128Delta": "1423733044596672457631004491657125052", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.50000", - "poolPriceBefore": "1.0000", - "tickAfter": -6932, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests high fee, 1:1 price, 2e18 max range liquidity swap exactly 1.0000 token1 for token0 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "-662207357859531772", - "amount1Before": "2000000000000000000", - "amount1Delta": "1000000000000000000", - "executionPrice": "1.5101", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "1701411834604692317316873037158841057", - "poolPriceAfter": "2.2350", - "poolPriceBefore": "1.0000", - "tickAfter": 8042, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests high fee, 1:1 price, 2e18 max range liquidity swap exactly 1.0000 token1 for token0 to price 2.0000 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "-585786437626904951", - "amount1Before": "2000000000000000000", - "amount1Delta": "836795075501202120", - "executionPrice": "1.4285", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "1423733044596672457631004491657125052", - "poolPriceAfter": "2.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 6931, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests high fee, 1:1 price, 2e18 max range liquidity swap token0 for exactly 0.0000000000000010000 token1 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "1012", - "amount1Before": "2000000000000000000", - "amount1Delta": "-1000", - "executionPrice": "0.98814", - "feeGrowthGlobal0X128Delta": "1871553018065161549048", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": -1, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests high fee, 1:1 price, 2e18 max range liquidity swap token0 for exactly 1.0000 token1 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "2020202020202020203", - "amount1Before": "2000000000000000000", - "amount1Delta": "-1000000000000000000", - "executionPrice": "0.49500", - "feeGrowthGlobal0X128Delta": "3437195625464025050172418213103875650", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.25000", - "poolPriceBefore": "1.0000", - "tickAfter": -13864, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests high fee, 1:1 price, 2e18 max range liquidity swap token0 for exactly 1.0000 token1 to price 0.50000 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "836795075501202120", - "amount1Before": "2000000000000000000", - "amount1Delta": "-585786437626904951", - "executionPrice": "0.70004", - "feeGrowthGlobal0X128Delta": "1423733044596672457631004491657125052", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.50000", - "poolPriceBefore": "1.0000", - "tickAfter": -6932, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests high fee, 1:1 price, 2e18 max range liquidity swap token0 for token1 to price 0.40000 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "1174017838553918518", - "amount1Before": "2000000000000000000", - "amount1Delta": "-735088935932648267", - "executionPrice": "0.62613", - "feeGrowthGlobal0X128Delta": "1997487844552658120479227965844634309", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.40000", - "poolPriceBefore": "1.0000", - "tickAfter": -9164, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests high fee, 1:1 price, 2e18 max range liquidity swap token0 for token1 to price 2.5000 1`] = ` -Object { - "poolBalance0": "2000000000000000000", - "poolBalance1": "2000000000000000000", - "poolPriceBefore": "1.0000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests high fee, 1:1 price, 2e18 max range liquidity swap token1 for exactly 0.0000000000000010000 token0 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "-1000", - "amount1Before": "2000000000000000000", - "amount1Delta": "1012", - "executionPrice": "1.0120", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "1871553018065161549048", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 0, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests high fee, 1:1 price, 2e18 max range liquidity swap token1 for exactly 1.0000 token0 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "-1000000000000000000", - "amount1Before": "2000000000000000000", - "amount1Delta": "2020202020202020203", - "executionPrice": "2.0202", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "3437195625464025050172418213103875650", - "poolPriceAfter": "4.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 13863, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests high fee, 1:1 price, 2e18 max range liquidity swap token1 for exactly 1.0000 token0 to price 2.0000 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "-585786437626904951", - "amount1Before": "2000000000000000000", - "amount1Delta": "836795075501202120", - "executionPrice": "1.4285", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "1423733044596672457631004491657125052", - "poolPriceAfter": "2.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 6931, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests high fee, 1:1 price, 2e18 max range liquidity swap token1 for token0 to price 0.40000 1`] = ` -Object { - "poolBalance0": "2000000000000000000", - "poolBalance1": "2000000000000000000", - "poolPriceBefore": "1.0000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests high fee, 1:1 price, 2e18 max range liquidity swap token1 for token0 to price 2.5000 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "-735088935932648267", - "amount1Before": "2000000000000000000", - "amount1Delta": "1174017838553918518", - "executionPrice": "1.5971", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "1997487844552658120479227965844634309", - "poolPriceAfter": "2.5000", - "poolPriceBefore": "1.0000", - "tickAfter": 9163, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the max ratio swap exactly 0.0000000000000010000 token0 for token1 1`] = ` -Object { - "amount0Before": "0", - "amount0Delta": "1000", - "amount1Before": "36796311329002736532545403775337522448", - "amount1Delta": "-36792225529204286454178948640580261338", - "executionPrice": "3.6792e+34", - "feeGrowthGlobal0X128Delta": "2381976568446569244235", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "4.1734e+30", - "poolPriceBefore": "3.4026e+38", - "tickAfter": 705098, - "tickBefore": 887271, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the max ratio swap exactly 0.0000000000000010000 token1 for token0 1`] = ` -Object { - "poolBalance0": "0", - "poolBalance1": "36796311329002736532545403775337522448", - "poolPriceBefore": "3.4026e+38", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 887271, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the max ratio swap exactly 1.0000 token0 for token1 1`] = ` -Object { - "amount0Before": "0", - "amount0Delta": "1000000000000000000", - "amount1Before": "36796311329002736532545403775337522448", - "amount1Delta": "-36796311329002736528533367667012547243", - "executionPrice": "3.6796e+19", - "feeGrowthGlobal0X128Delta": "510423550381413479995299567101531162", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "4.0241", - "poolPriceBefore": "3.4026e+38", - "tickAfter": 13923, - "tickBefore": 887271, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the max ratio swap exactly 1.0000 token0 for token1 to price 0.50000 1`] = ` -Object { - "amount0Before": "0", - "amount0Delta": "1000000000000000000", - "amount1Before": "36796311329002736532545403775337522448", - "amount1Delta": "-36796311329002736528533367667012547243", - "executionPrice": "3.6796e+19", - "feeGrowthGlobal0X128Delta": "510423550381413479995299567101531162", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "4.0241", - "poolPriceBefore": "3.4026e+38", - "tickAfter": 13923, - "tickBefore": 887271, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the max ratio swap exactly 1.0000 token1 for token0 1`] = ` -Object { - "poolBalance0": "0", - "poolBalance1": "36796311329002736532545403775337522448", - "poolPriceBefore": "3.4026e+38", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 887271, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the max ratio swap exactly 1.0000 token1 for token0 to price 2.0000 1`] = ` -Object { - "poolBalance0": "0", - "poolBalance1": "36796311329002736532545403775337522448", - "poolPriceBefore": "3.4026e+38", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 887271, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the max ratio swap token0 for exactly 0.0000000000000010000 token1 1`] = ` -Object { - "amount0Before": "0", - "amount0Delta": "2", - "amount1Before": "36796311329002736532545403775337522448", - "amount1Delta": "-1000", - "executionPrice": "500.00", - "feeGrowthGlobal0X128Delta": "170141183460469231731", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "3.3849e+38", - "poolPriceBefore": "3.4026e+38", - "tickAfter": 887219, - "tickBefore": 887271, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the max ratio swap token0 for exactly 1.0000 token1 1`] = ` -Object { - "amount0Before": "0", - "amount0Delta": "2", - "amount1Before": "36796311329002736532545403775337522448", - "amount1Delta": "-1000000000000000000", - "executionPrice": "5.0000e+17", - "feeGrowthGlobal0X128Delta": "170141183460469231731", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "3.3849e+38", - "poolPriceBefore": "3.4026e+38", - "tickAfter": 887219, - "tickBefore": 887271, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the max ratio swap token0 for exactly 1.0000 token1 to price 0.50000 1`] = ` -Object { - "amount0Before": "0", - "amount0Delta": "2", - "amount1Before": "36796311329002736532545403775337522448", - "amount1Delta": "-1000000000000000000", - "executionPrice": "5.0000e+17", - "feeGrowthGlobal0X128Delta": "170141183460469231731", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "3.3849e+38", - "poolPriceBefore": "3.4026e+38", - "tickAfter": 887219, - "tickBefore": 887271, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the max ratio swap token0 for token1 to price 0.40000 1`] = ` -Object { - "amount0Before": "0", - "amount0Delta": "3171793039286238109", - "amount1Before": "36796311329002736532545403775337522448", - "amount1Delta": "-36796311329002736531280492711270170687", - "executionPrice": "1.1601e+19", - "feeGrowthGlobal0X128Delta": "1618957864187523123655042148763283097", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.40000", - "poolPriceBefore": "3.4026e+38", - "tickAfter": -9164, - "tickBefore": 887271, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the max ratio swap token0 for token1 to price 2.5000 1`] = ` -Object { - "amount0Before": "0", - "amount0Delta": "1268717215714495281", - "amount1Before": "36796311329002736532545403775337522448", - "amount1Delta": "-36796311329002736529383126115169143088", - "executionPrice": "2.9003e+19", - "feeGrowthGlobal0X128Delta": "647583145675012618257449376796101507", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "2.5000", - "poolPriceBefore": "3.4026e+38", - "tickAfter": 9163, - "tickBefore": 887271, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the max ratio swap token1 for exactly 0.0000000000000010000 token0 1`] = ` -Object { - "poolBalance0": "0", - "poolBalance1": "36796311329002736532545403775337522448", - "poolPriceBefore": "3.4026e+38", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 887271, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the max ratio swap token1 for exactly 1.0000 token0 1`] = ` -Object { - "poolBalance0": "0", - "poolBalance1": "36796311329002736532545403775337522448", - "poolPriceBefore": "3.4026e+38", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 887271, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the max ratio swap token1 for exactly 1.0000 token0 to price 2.0000 1`] = ` -Object { - "poolBalance0": "0", - "poolBalance1": "36796311329002736532545403775337522448", - "poolPriceBefore": "3.4026e+38", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 887271, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the max ratio swap token1 for token0 to price 0.40000 1`] = ` -Object { - "poolBalance0": "0", - "poolBalance1": "36796311329002736532545403775337522448", - "poolPriceBefore": "3.4026e+38", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 887271, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the max ratio swap token1 for token0 to price 2.5000 1`] = ` -Object { - "poolBalance0": "0", - "poolBalance1": "36796311329002736532545403775337522448", - "poolPriceBefore": "3.4026e+38", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 887271, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the min ratio swap exactly 0.0000000000000010000 token0 for token1 1`] = ` -Object { - "poolBalance0": "36796311322104302062438284732106019258", - "poolBalance1": "0", - "poolPriceBefore": "0.0000000000000000000000000000000000000029390", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": -887272, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the min ratio swap exactly 0.0000000000000010000 token1 for token0 1`] = ` -Object { - "amount0Before": "36796311322104302062438284732106019258", - "amount0Delta": "-36792226666449146913445651103694411508", - "amount1Before": "0", - "amount1Delta": "1000", - "executionPrice": "0.000000000000000000000000000000000027180", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "2381976568446569244235", - "poolPriceAfter": "0.00000000000000000000000000000023974", - "poolPriceBefore": "0.0000000000000000000000000000000000000029390", - "tickAfter": -705093, - "tickBefore": -887272, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the min ratio swap exactly 1.0000 token0 for token1 1`] = ` -Object { - "poolBalance0": "36796311322104302062438284732106019258", - "poolBalance1": "0", - "poolPriceBefore": "0.0000000000000000000000000000000000000029390", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": -887272, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the min ratio swap exactly 1.0000 token0 for token1 to price 0.50000 1`] = ` -Object { - "poolBalance0": "36796311322104302062438284732106019258", - "poolBalance1": "0", - "poolPriceBefore": "0.0000000000000000000000000000000000000029390", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": -887272, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the min ratio swap exactly 1.0000 token1 for token0 1`] = ` -Object { - "amount0Before": "36796311322104302062438284732106019258", - "amount0Delta": "-36796311322104302058426248623781044040", - "amount1Before": "0", - "amount1Delta": "1000000000000000000", - "executionPrice": "0.000000000000000000027177", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "510423550381413820277666488039994629", - "poolPriceAfter": "0.24850", - "poolPriceBefore": "0.0000000000000000000000000000000000000029390", - "tickAfter": -13924, - "tickBefore": -887272, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the min ratio swap exactly 1.0000 token1 for token0 to price 2.0000 1`] = ` -Object { - "amount0Before": "36796311322104302062438284732106019258", - "amount0Delta": "-36796311322104302058426248623781044040", - "amount1Before": "0", - "amount1Delta": "1000000000000000000", - "executionPrice": "0.000000000000000000027177", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "510423550381413820277666488039994629", - "poolPriceAfter": "0.24850", - "poolPriceBefore": "0.0000000000000000000000000000000000000029390", - "tickAfter": -13924, - "tickBefore": -887272, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the min ratio swap token0 for exactly 0.0000000000000010000 token1 1`] = ` -Object { - "poolBalance0": "36796311322104302062438284732106019258", - "poolBalance1": "0", - "poolPriceBefore": "0.0000000000000000000000000000000000000029390", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": -887272, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the min ratio swap token0 for exactly 1.0000 token1 1`] = ` -Object { - "poolBalance0": "36796311322104302062438284732106019258", - "poolBalance1": "0", - "poolPriceBefore": "0.0000000000000000000000000000000000000029390", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": -887272, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the min ratio swap token0 for exactly 1.0000 token1 to price 0.50000 1`] = ` -Object { - "poolBalance0": "36796311322104302062438284732106019258", - "poolBalance1": "0", - "poolPriceBefore": "0.0000000000000000000000000000000000000029390", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": -887272, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the min ratio swap token0 for token1 to price 0.40000 1`] = ` -Object { - "poolBalance0": "36796311322104302062438284732106019258", - "poolBalance1": "0", - "poolPriceBefore": "0.0000000000000000000000000000000000000029390", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": -887272, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the min ratio swap token0 for token1 to price 2.5000 1`] = ` -Object { - "poolBalance0": "36796311322104302062438284732106019258", - "poolBalance1": "0", - "poolPriceBefore": "0.0000000000000000000000000000000000000029390", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": -887272, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the min ratio swap token1 for exactly 0.0000000000000010000 token0 1`] = ` -Object { - "amount0Before": "36796311322104302062438284732106019258", - "amount0Delta": "-1000", - "amount1Before": "0", - "amount1Delta": "2", - "executionPrice": "0.0020000", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "170141183460469231731", - "poolPriceAfter": "0.0000000000000000000000000000000000000029543", - "poolPriceBefore": "0.0000000000000000000000000000000000000029390", - "tickAfter": -887220, - "tickBefore": -887272, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the min ratio swap token1 for exactly 1.0000 token0 1`] = ` -Object { - "amount0Before": "36796311322104302062438284732106019258", - "amount0Delta": "-1000000000000000000", - "amount1Before": "0", - "amount1Delta": "2", - "executionPrice": "0.0000000000000000020000", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "170141183460469231731", - "poolPriceAfter": "0.0000000000000000000000000000000000000029543", - "poolPriceBefore": "0.0000000000000000000000000000000000000029390", - "tickAfter": -887220, - "tickBefore": -887272, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the min ratio swap token1 for exactly 1.0000 token0 to price 2.0000 1`] = ` -Object { - "amount0Before": "36796311322104302062438284732106019258", - "amount0Delta": "-1000000000000000000", - "amount1Before": "0", - "amount1Delta": "2", - "executionPrice": "0.0000000000000000020000", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "170141183460469231731", - "poolPriceAfter": "0.0000000000000000000000000000000000000029543", - "poolPriceBefore": "0.0000000000000000000000000000000000000029390", - "tickAfter": -887220, - "tickBefore": -887272, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the min ratio swap token1 for token0 to price 0.40000 1`] = ` -Object { - "amount0Before": "36796311322104302062438284732106019258", - "amount0Delta": "-36796311322104302059276007071937639893", - "amount1Before": "0", - "amount1Delta": "1268717215714495283", - "executionPrice": "0.000000000000000000034479", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "647583145675012958539816297734564973", - "poolPriceAfter": "0.40000", - "poolPriceBefore": "0.0000000000000000000000000000000000000029390", - "tickAfter": -9164, - "tickBefore": -887272, -} -`; - -exports[`UniswapV3Pool swap tests initialized at the min ratio swap token1 for token0 to price 2.5000 1`] = ` -Object { - "amount0Before": "36796311322104302062438284732106019258", - "amount0Delta": "-36796311322104302061173373668038667492", - "amount1Before": "0", - "amount1Delta": "3171793039286238112", - "executionPrice": "0.000000000000000000086199", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "1618957864187523634078592530170978294", - "poolPriceAfter": "2.5000", - "poolPriceBefore": "0.0000000000000000000000000000000000000029390", - "tickAfter": 9163, - "tickBefore": -887272, -} -`; - -exports[`UniswapV3Pool swap tests low fee, 1:1 price, 2e18 max range liquidity swap exactly 0.0000000000000010000 token0 for token1 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "1000", - "amount1Before": "2000000000000000000", - "amount1Delta": "-998", - "executionPrice": "0.99800", - "feeGrowthGlobal0X128Delta": "170141183460469231731", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": -1, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, 1:1 price, 2e18 max range liquidity swap exactly 0.0000000000000010000 token1 for token0 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "-998", - "amount1Before": "2000000000000000000", - "amount1Delta": "1000", - "executionPrice": "1.0020", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "170141183460469231731", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 0, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, 1:1 price, 2e18 max range liquidity swap exactly 1.0000 token0 for token1 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "1000000000000000000", - "amount1Before": "2000000000000000000", - "amount1Delta": "-666444407401233536", - "executionPrice": "0.66644", - "feeGrowthGlobal0X128Delta": "85070591730234956148210572796405514", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.44459", - "poolPriceBefore": "1.0000", - "tickAfter": -8107, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, 1:1 price, 2e18 max range liquidity swap exactly 1.0000 token0 for token1 to price 0.50000 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "828841545518949575", - "amount1Before": "2000000000000000000", - "amount1Delta": "-585786437626904950", - "executionPrice": "0.70675", - "feeGrowthGlobal0X128Delta": "70510040727899606087499539976421836", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.50000", - "poolPriceBefore": "1.0000", - "tickAfter": -6932, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, 1:1 price, 2e18 max range liquidity swap exactly 1.0000 token1 for token0 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "-666444407401233536", - "amount1Before": "2000000000000000000", - "amount1Delta": "1000000000000000000", - "executionPrice": "1.5005", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "85070591730234956148210572796405515", - "poolPriceAfter": "2.2493", - "poolPriceBefore": "1.0000", - "tickAfter": 8106, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, 1:1 price, 2e18 max range liquidity swap exactly 1.0000 token1 for token0 to price 2.0000 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "-585786437626904950", - "amount1Before": "2000000000000000000", - "amount1Delta": "828841545518949574", - "executionPrice": "1.4149", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "70510040727899435946316079507190105", - "poolPriceAfter": "2.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 6931, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, 1:1 price, 2e18 max range liquidity swap token0 for exactly 0.0000000000000010000 token1 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "1002", - "amount1Before": "2000000000000000000", - "amount1Delta": "-1000", - "executionPrice": "0.99800", - "feeGrowthGlobal0X128Delta": "170141183460469231731", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": -1, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, 1:1 price, 2e18 max range liquidity swap token0 for exactly 1.0000 token1 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "2001000500250125077", - "amount1Before": "2000000000000000000", - "amount1Delta": "-1000000000000000000", - "executionPrice": "0.49975", - "feeGrowthGlobal0X128Delta": "170226296608774038574344664756091446", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.25000", - "poolPriceBefore": "1.0000", - "tickAfter": -13864, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, 1:1 price, 2e18 max range liquidity swap token0 for exactly 1.0000 token1 to price 0.50000 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "828841545518949575", - "amount1Before": "2000000000000000000", - "amount1Delta": "-585786437626904950", - "executionPrice": "0.70675", - "feeGrowthGlobal0X128Delta": "70510040727899606087499539976421836", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.50000", - "poolPriceBefore": "1.0000", - "tickAfter": -6932, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, 1:1 price, 2e18 max range liquidity swap token0 for token1 to price 0.40000 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "1162859089713235953", - "amount1Before": "2000000000000000000", - "amount1Delta": "-735088935932648266", - "executionPrice": "0.63214", - "feeGrowthGlobal0X128Delta": "98925110860787308007692432636113977", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.40000", - "poolPriceBefore": "1.0000", - "tickAfter": -9164, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, 1:1 price, 2e18 max range liquidity swap token0 for token1 to price 2.5000 1`] = ` -Object { - "poolBalance0": "2000000000000000000", - "poolBalance1": "2000000000000000000", - "poolPriceBefore": "1.0000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, 1:1 price, 2e18 max range liquidity swap token1 for exactly 0.0000000000000010000 token0 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "-1000", - "amount1Before": "2000000000000000000", - "amount1Delta": "1002", - "executionPrice": "1.0020", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "170141183460469231731", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 0, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, 1:1 price, 2e18 max range liquidity swap token1 for exactly 1.0000 token0 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "-1000000000000000000", - "amount1Before": "2000000000000000000", - "amount1Delta": "2001000500250125079", - "executionPrice": "2.0010", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "170226296608774378856711585694554910", - "poolPriceAfter": "4.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 13863, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, 1:1 price, 2e18 max range liquidity swap token1 for exactly 1.0000 token0 to price 2.0000 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "-585786437626904950", - "amount1Before": "2000000000000000000", - "amount1Delta": "828841545518949574", - "executionPrice": "1.4149", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "70510040727899435946316079507190105", - "poolPriceAfter": "2.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 6931, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, 1:1 price, 2e18 max range liquidity swap token1 for token0 to price 0.40000 1`] = ` -Object { - "poolBalance0": "2000000000000000000", - "poolBalance1": "2000000000000000000", - "poolPriceBefore": "1.0000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, 1:1 price, 2e18 max range liquidity swap token1 for token0 to price 2.5000 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "-735088935932648266", - "amount1Before": "2000000000000000000", - "amount1Delta": "1162859089713235954", - "executionPrice": "1.5819", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "98925110860787308007692432636113978", - "poolPriceAfter": "2.5000", - "poolPriceBefore": "1.0000", - "tickAfter": 9163, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, large liquidity around current price (stable swap) swap exactly 0.0000000000000010000 token0 for token1 1`] = ` -Object { - "amount0Before": "999700069986003", - "amount0Delta": "1000", - "amount1Before": "999700069986003", - "amount1Delta": "-998", - "executionPrice": "0.99800", - "feeGrowthGlobal0X128Delta": "170141183460469231731", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": -1, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, large liquidity around current price (stable swap) swap exactly 0.0000000000000010000 token1 for token0 1`] = ` -Object { - "amount0Before": "999700069986003", - "amount0Delta": "-998", - "amount1Before": "999700069986003", - "amount1Delta": "1000", - "executionPrice": "1.0020", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "170141183460469231731", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 0, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, large liquidity around current price (stable swap) swap exactly 1.0000 token0 for token1 1`] = ` -Object { - "amount0Before": "999700069986003", - "amount0Delta": "1000700370186095", - "amount1Before": "999700069986003", - "amount1Delta": "-999700069986002", - "executionPrice": "0.99900", - "feeGrowthGlobal0X128Delta": "85130172636557991529041720559172", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.0000000000000000000000000000000000000029390", - "poolPriceBefore": "1.0000", - "tickAfter": -887272, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, large liquidity around current price (stable swap) swap exactly 1.0000 token0 for token1 to price 0.50000 1`] = ` -Object { - "amount0Before": "999700069986003", - "amount0Delta": "1000700370186095", - "amount1Before": "999700069986003", - "amount1Delta": "-999700069986002", - "executionPrice": "0.99900", - "feeGrowthGlobal0X128Delta": "85130172636557991529041720559172", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.50000", - "poolPriceBefore": "1.0000", - "tickAfter": -6932, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, large liquidity around current price (stable swap) swap exactly 1.0000 token1 for token0 1`] = ` -Object { - "amount0Before": "999700069986003", - "amount0Delta": "-999700069986002", - "amount1Before": "999700069986003", - "amount1Delta": "1000700370186095", - "executionPrice": "1.0010", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "85130172636557991529041720559172", - "poolPriceAfter": "3.4026e+38", - "poolPriceBefore": "1.0000", - "tickAfter": 887271, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, large liquidity around current price (stable swap) swap exactly 1.0000 token1 for token0 to price 2.0000 1`] = ` -Object { - "amount0Before": "999700069986003", - "amount0Delta": "-999700069986002", - "amount1Before": "999700069986003", - "amount1Delta": "1000700370186095", - "executionPrice": "1.0010", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "85130172636557991529041720559172", - "poolPriceAfter": "2.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 6931, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, large liquidity around current price (stable swap) swap token0 for exactly 0.0000000000000010000 token1 1`] = ` -Object { - "amount0Before": "999700069986003", - "amount0Delta": "1002", - "amount1Before": "999700069986003", - "amount1Delta": "-1000", - "executionPrice": "0.99800", - "feeGrowthGlobal0X128Delta": "170141183460469231731", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": -1, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, large liquidity around current price (stable swap) swap token0 for exactly 1.0000 token1 1`] = ` -Object { - "amount0Before": "999700069986003", - "amount0Delta": "1000700370186095", - "amount1Before": "999700069986003", - "amount1Delta": "-999700069986002", - "executionPrice": "0.99900", - "feeGrowthGlobal0X128Delta": "85130172636557991529041720559172", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.0000000000000000000000000000000000000029390", - "poolPriceBefore": "1.0000", - "tickAfter": -887272, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, large liquidity around current price (stable swap) swap token0 for exactly 1.0000 token1 to price 0.50000 1`] = ` -Object { - "amount0Before": "999700069986003", - "amount0Delta": "1000700370186095", - "amount1Before": "999700069986003", - "amount1Delta": "-999700069986002", - "executionPrice": "0.99900", - "feeGrowthGlobal0X128Delta": "85130172636557991529041720559172", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.50000", - "poolPriceBefore": "1.0000", - "tickAfter": -6932, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, large liquidity around current price (stable swap) swap token0 for token1 to price 0.40000 1`] = ` -Object { - "amount0Before": "999700069986003", - "amount0Delta": "1000700370186095", - "amount1Before": "999700069986003", - "amount1Delta": "-999700069986002", - "executionPrice": "0.99900", - "feeGrowthGlobal0X128Delta": "85130172636557991529041720559172", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.40000", - "poolPriceBefore": "1.0000", - "tickAfter": -9164, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, large liquidity around current price (stable swap) swap token0 for token1 to price 2.5000 1`] = ` -Object { - "poolBalance0": "999700069986003", - "poolBalance1": "999700069986003", - "poolPriceBefore": "1.0000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, large liquidity around current price (stable swap) swap token1 for exactly 0.0000000000000010000 token0 1`] = ` -Object { - "amount0Before": "999700069986003", - "amount0Delta": "-1000", - "amount1Before": "999700069986003", - "amount1Delta": "1002", - "executionPrice": "1.0020", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "170141183460469231731", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 0, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, large liquidity around current price (stable swap) swap token1 for exactly 1.0000 token0 1`] = ` -Object { - "amount0Before": "999700069986003", - "amount0Delta": "-999700069986002", - "amount1Before": "999700069986003", - "amount1Delta": "1000700370186095", - "executionPrice": "1.0010", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "85130172636557991529041720559172", - "poolPriceAfter": "3.4026e+38", - "poolPriceBefore": "1.0000", - "tickAfter": 887271, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, large liquidity around current price (stable swap) swap token1 for exactly 1.0000 token0 to price 2.0000 1`] = ` -Object { - "amount0Before": "999700069986003", - "amount0Delta": "-999700069986002", - "amount1Before": "999700069986003", - "amount1Delta": "1000700370186095", - "executionPrice": "1.0010", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "85130172636557991529041720559172", - "poolPriceAfter": "2.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 6931, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, large liquidity around current price (stable swap) swap token1 for token0 to price 0.40000 1`] = ` -Object { - "poolBalance0": "999700069986003", - "poolBalance1": "999700069986003", - "poolPriceBefore": "1.0000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests low fee, large liquidity around current price (stable swap) swap token1 for token0 to price 2.5000 1`] = ` -Object { - "amount0Before": "999700069986003", - "amount0Delta": "-999700069986002", - "amount1Before": "999700069986003", - "amount1Delta": "1000700370186095", - "executionPrice": "1.0010", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "85130172636557991529041720559172", - "poolPriceAfter": "2.5000", - "poolPriceBefore": "1.0000", - "tickAfter": 9163, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests max full range liquidity at 1:1 price with default fee swap exactly 0.0000000000000010000 token0 for token1 1`] = ` -Object { - "amount0Before": "11505743598341114571255423385623647", - "amount0Delta": "1000", - "amount1Before": "11505743598341114571255423385506404", - "amount1Delta": "0", - "executionPrice": "0.0000", - "feeGrowthGlobal0X128Delta": "29575000", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": -1, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests max full range liquidity at 1:1 price with default fee swap exactly 0.0000000000000010000 token1 for token0 1`] = ` -Object { - "amount0Before": "11505743598341114571255423385623647", - "amount0Delta": "0", - "amount1Before": "11505743598341114571255423385506404", - "amount1Delta": "1000", - "executionPrice": "-Infinity", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "29575000", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 0, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests max full range liquidity at 1:1 price with default fee swap exactly 1.0000 token0 for token1 1`] = ` -Object { - "amount0Before": "11505743598341114571255423385623647", - "amount0Delta": "1000000000000000000", - "amount1Before": "11505743598341114571255423385506404", - "amount1Delta": "-996999999999999318", - "executionPrice": "0.99700", - "feeGrowthGlobal0X128Delta": "88725000000017597125", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": -1, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests max full range liquidity at 1:1 price with default fee swap exactly 1.0000 token0 for token1 to price 0.50000 1`] = ` -Object { - "amount0Before": "11505743598341114571255423385623647", - "amount0Delta": "1000000000000000000", - "amount1Before": "11505743598341114571255423385506404", - "amount1Delta": "-996999999999999318", - "executionPrice": "0.99700", - "feeGrowthGlobal0X128Delta": "88725000000017597125", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": -1, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests max full range liquidity at 1:1 price with default fee swap exactly 1.0000 token1 for token0 1`] = ` -Object { - "amount0Before": "11505743598341114571255423385623647", - "amount0Delta": "-996999999999999232", - "amount1Before": "11505743598341114571255423385506404", - "amount1Delta": "1000000000000000000", - "executionPrice": "1.0030", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "88725000000020140575", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 0, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests max full range liquidity at 1:1 price with default fee swap exactly 1.0000 token1 for token0 to price 2.0000 1`] = ` -Object { - "amount0Before": "11505743598341114571255423385623647", - "amount0Delta": "-996999999999999232", - "amount1Before": "11505743598341114571255423385506404", - "amount1Delta": "1000000000000000000", - "executionPrice": "1.0030", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "88725000000020140575", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 0, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests max full range liquidity at 1:1 price with default fee swap token0 for exactly 0.0000000000000010000 token1 1`] = ` -Object { - "amount0Before": "11505743598341114571255423385623647", - "amount0Delta": "145660", - "amount1Before": "11505743598341114571255423385506404", - "amount1Delta": "-1000", - "executionPrice": "0.0068653", - "feeGrowthGlobal0X128Delta": "12924275", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": -1, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests max full range liquidity at 1:1 price with default fee swap token0 for exactly 1.0000 token1 1`] = ` -Object { - "amount0Before": "11505743598341114571255423385623647", - "amount0Delta": "1003009027081361181", - "amount1Before": "11505743598341114571255423385506404", - "amount1Delta": "-1000000000000000000", - "executionPrice": "0.99700", - "feeGrowthGlobal0X128Delta": "88991975927793784300", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": -1, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests max full range liquidity at 1:1 price with default fee swap token0 for exactly 1.0000 token1 to price 0.50000 1`] = ` -Object { - "amount0Before": "11505743598341114571255423385623647", - "amount0Delta": "1003009027081361181", - "amount1Before": "11505743598341114571255423385506404", - "amount1Delta": "-1000000000000000000", - "executionPrice": "0.99700", - "feeGrowthGlobal0X128Delta": "88991975927793784300", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": -1, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests max full range liquidity at 1:1 price with default fee swap token0 for token1 to price 0.40000 1`] = ` -Object { - "amount0Before": "11505743598341114571255423385623647", - "amount0Delta": "6706554036096900675845906992672697", - "amount1Before": "11505743598341114571255423385506404", - "amount1Delta": "-4228872409409224753601131225116702", - "executionPrice": "0.63056", - "feeGrowthGlobal0X128Delta": "595039006852697512464428097924911949", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.40000", - "poolPriceBefore": "1.0000", - "tickAfter": -9164, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests max full range liquidity at 1:1 price with default fee swap token0 for token1 to price 2.5000 1`] = ` -Object { - "poolBalance0": "11505743598341114571255423385623647", - "poolBalance1": "11505743598341114571255423385506404", - "poolPriceBefore": "1.0000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests max full range liquidity at 1:1 price with default fee swap token1 for exactly 0.0000000000000010000 token0 1`] = ` -Object { - "amount0Before": "11505743598341114571255423385623647", - "amount0Delta": "-1000", - "amount1Before": "11505743598341114571255423385506404", - "amount1Delta": "145660", - "executionPrice": "145.66", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "12924275", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 0, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests max full range liquidity at 1:1 price with default fee swap token1 for exactly 1.0000 token0 1`] = ` -Object { - "amount0Before": "11505743598341114571255423385623647", - "amount0Delta": "-1000000000000000000", - "amount1Before": "11505743598341114571255423385506404", - "amount1Delta": "1003009027081361094", - "executionPrice": "1.0030", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "88991975927793784300", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 0, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests max full range liquidity at 1:1 price with default fee swap token1 for exactly 1.0000 token0 to price 2.0000 1`] = ` -Object { - "amount0Before": "11505743598341114571255423385623647", - "amount0Delta": "-1000000000000000000", - "amount1Before": "11505743598341114571255423385506404", - "amount1Delta": "1003009027081361094", - "executionPrice": "1.0030", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "88991975927793784300", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 0, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests max full range liquidity at 1:1 price with default fee swap token1 for token0 to price 0.40000 1`] = ` -Object { - "poolBalance0": "11505743598341114571255423385623647", - "poolBalance1": "11505743598341114571255423385506404", - "poolPriceBefore": "1.0000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests max full range liquidity at 1:1 price with default fee swap token1 for token0 to price 2.5000 1`] = ` -Object { - "amount0Before": "11505743598341114571255423385623647", - "amount0Delta": "-4228872409409224753601131224936259", - "amount1Before": "11505743598341114571255423385506404", - "amount1Delta": "6706554036096900675845906992220230", - "executionPrice": "1.5859", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "595039006852697512464428097884749099", - "poolPriceAfter": "2.5000", - "poolPriceBefore": "1.0000", - "tickAfter": 9163, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 0 liquidity, all liquidity around current price swap exactly 0.0000000000000010000 token0 for token1 1`] = ` -Object { - "amount0Before": "1994009290088178439", - "amount0Delta": "1000", - "amount1Before": "1994009290088178439", - "amount1Delta": "-991", - "executionPrice": "0.99100", - "feeGrowthGlobal0X128Delta": "510423550381407695195", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.99402", - "poolPriceBefore": "1.0000", - "tickAfter": -61, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 0 liquidity, all liquidity around current price swap exactly 0.0000000000000010000 token1 for token0 1`] = ` -Object { - "amount0Before": "1994009290088178439", - "amount0Delta": "-991", - "amount1Before": "1994009290088178439", - "amount1Delta": "1000", - "executionPrice": "1.0091", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "510423550381407695195", - "poolPriceAfter": "1.0060", - "poolPriceBefore": "1.0000", - "tickAfter": 60, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 0 liquidity, all liquidity around current price swap exactly 1.0000 token0 for token1 1`] = ` -Object { - "amount0Before": "1994009290088178439", - "amount0Delta": "1000000000000000000", - "amount1Before": "1994009290088178439", - "amount1Delta": "-662011820624678025", - "executionPrice": "0.66201", - "feeGrowthGlobal0X128Delta": "510423550381407695195061911147652317", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.44355", - "poolPriceBefore": "1.0000", - "tickAfter": -8130, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 0 liquidity, all liquidity around current price swap exactly 1.0000 token0 for token1 to price 0.50000 1`] = ` -Object { - "amount0Before": "1994009290088178439", - "amount0Delta": "824893095908431542", - "amount1Before": "1994009290088178439", - "amount1Delta": "-579795727715083389", - "executionPrice": "0.70287", - "feeGrowthGlobal0X128Delta": "421044862698692740725170743495410672", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.50000", - "poolPriceBefore": "1.0000", - "tickAfter": -6932, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 0 liquidity, all liquidity around current price swap exactly 1.0000 token1 for token0 1`] = ` -Object { - "amount0Before": "1994009290088178439", - "amount0Delta": "-662011820624678025", - "amount1Before": "1994009290088178439", - "amount1Delta": "1000000000000000000", - "executionPrice": "1.5105", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "510423550381407695195061911147652317", - "poolPriceAfter": "2.2545", - "poolPriceBefore": "1.0000", - "tickAfter": 8129, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 0 liquidity, all liquidity around current price swap exactly 1.0000 token1 for token0 to price 2.0000 1`] = ` -Object { - "amount0Before": "1994009290088178439", - "amount0Delta": "-579795727715083389", - "amount1Before": "1994009290088178439", - "amount1Delta": "824893095908431542", - "executionPrice": "1.4227", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "421044862698692740725170743495410672", - "poolPriceAfter": "2.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 6931, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 0 liquidity, all liquidity around current price swap token0 for exactly 0.0000000000000010000 token1 1`] = ` -Object { - "amount0Before": "1994009290088178439", - "amount0Delta": "1011", - "amount1Before": "1994009290088178439", - "amount1Delta": "-1000", - "executionPrice": "0.98912", - "feeGrowthGlobal0X128Delta": "680564733841876926926", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.99402", - "poolPriceBefore": "1.0000", - "tickAfter": -61, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 0 liquidity, all liquidity around current price swap token0 for exactly 1.0000 token1 1`] = ` -Object { - "amount0Before": "1994009290088178439", - "amount0Delta": "2024171064311638316", - "amount1Before": "1994009290088178439", - "amount1Delta": "-1000000000000000000", - "executionPrice": "0.49403", - "feeGrowthGlobal0X128Delta": "1033184581225259164735720748018047287", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.24701", - "poolPriceBefore": "1.0000", - "tickAfter": -13984, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 0 liquidity, all liquidity around current price swap token0 for exactly 1.0000 token1 to price 0.50000 1`] = ` -Object { - "amount0Before": "1994009290088178439", - "amount0Delta": "824893095908431542", - "amount1Before": "1994009290088178439", - "amount1Delta": "-579795727715083389", - "executionPrice": "0.70287", - "feeGrowthGlobal0X128Delta": "421044862698692740725170743495410672", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.50000", - "poolPriceBefore": "1.0000", - "tickAfter": -6932, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 0 liquidity, all liquidity around current price swap token0 for token1 to price 0.40000 1`] = ` -Object { - "amount0Before": "1994009290088178439", - "amount0Delta": "1159748196632793863", - "amount1Before": "1994009290088178439", - "amount1Delta": "-729098226020826705", - "executionPrice": "0.62867", - "feeGrowthGlobal0X128Delta": "591962792073745646583043420635066071", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.40000", - "poolPriceBefore": "1.0000", - "tickAfter": -9164, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 0 liquidity, all liquidity around current price swap token0 for token1 to price 2.5000 1`] = ` -Object { - "poolBalance0": "1994009290088178439", - "poolBalance1": "1994009290088178439", - "poolPriceBefore": "1.0000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 0 liquidity, all liquidity around current price swap token1 for exactly 0.0000000000000010000 token0 1`] = ` -Object { - "amount0Before": "1994009290088178439", - "amount0Delta": "-1000", - "amount1Before": "1994009290088178439", - "amount1Delta": "1011", - "executionPrice": "1.0110", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "680564733841876926926", - "poolPriceAfter": "1.0060", - "poolPriceBefore": "1.0000", - "tickAfter": 60, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 0 liquidity, all liquidity around current price swap token1 for exactly 1.0000 token0 1`] = ` -Object { - "amount0Before": "1994009290088178439", - "amount0Delta": "-1000000000000000000", - "amount1Before": "1994009290088178439", - "amount1Delta": "2024171064311638316", - "executionPrice": "2.0242", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "1033184581225259164735720748018047287", - "poolPriceAfter": "4.0484", - "poolPriceBefore": "1.0000", - "tickAfter": 13983, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 0 liquidity, all liquidity around current price swap token1 for exactly 1.0000 token0 to price 2.0000 1`] = ` -Object { - "amount0Before": "1994009290088178439", - "amount0Delta": "-579795727715083389", - "amount1Before": "1994009290088178439", - "amount1Delta": "824893095908431542", - "executionPrice": "1.4227", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "421044862698692740725170743495410672", - "poolPriceAfter": "2.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 6931, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 0 liquidity, all liquidity around current price swap token1 for token0 to price 0.40000 1`] = ` -Object { - "poolBalance0": "1994009290088178439", - "poolBalance1": "1994009290088178439", - "poolPriceBefore": "1.0000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 0 liquidity, all liquidity around current price swap token1 for token0 to price 2.5000 1`] = ` -Object { - "amount0Before": "1994009290088178439", - "amount0Delta": "-729098226020826705", - "amount1Before": "1994009290088178439", - "amount1Delta": "1159748196632793863", - "executionPrice": "1.5907", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "591962792073745646583043420635066071", - "poolPriceAfter": "2.5000", - "poolPriceBefore": "1.0000", - "tickAfter": 9163, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 2e18 max range liquidity swap exactly 0.0000000000000010000 token0 for token1 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "1000", - "amount1Before": "2000000000000000000", - "amount1Delta": "-996", - "executionPrice": "0.99600", - "feeGrowthGlobal0X128Delta": "510423550381407695195", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": -1, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 2e18 max range liquidity swap exactly 0.0000000000000010000 token1 for token0 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "-996", - "amount1Before": "2000000000000000000", - "amount1Delta": "1000", - "executionPrice": "1.0040", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "510423550381407695195", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 0, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 2e18 max range liquidity swap exactly 1.0000 token0 for token1 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "1000000000000000000", - "amount1Before": "2000000000000000000", - "amount1Delta": "-665331998665331998", - "executionPrice": "0.66533", - "feeGrowthGlobal0X128Delta": "510423550381407695195061911147652317", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.44533", - "poolPriceBefore": "1.0000", - "tickAfter": -8090, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 2e18 max range liquidity swap exactly 1.0000 token0 for token1 to price 0.50000 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "830919884399388263", - "amount1Before": "2000000000000000000", - "amount1Delta": "-585786437626904951", - "executionPrice": "0.70499", - "feeGrowthGlobal0X128Delta": "424121077477644648929101317621422688", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.50000", - "poolPriceBefore": "1.0000", - "tickAfter": -6932, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 2e18 max range liquidity swap exactly 1.0000 token1 for token0 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "-665331998665331998", - "amount1Before": "2000000000000000000", - "amount1Delta": "1000000000000000000", - "executionPrice": "1.5030", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "510423550381407695195061911147652317", - "poolPriceAfter": "2.2455", - "poolPriceBefore": "1.0000", - "tickAfter": 8089, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 2e18 max range liquidity swap exactly 1.0000 token1 for token0 to price 2.0000 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "-585786437626904951", - "amount1Before": "2000000000000000000", - "amount1Delta": "830919884399388263", - "executionPrice": "1.4185", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "424121077477644648929101317621422688", - "poolPriceAfter": "2.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 6931, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 2e18 max range liquidity swap token0 for exactly 0.0000000000000010000 token1 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "1005", - "amount1Before": "2000000000000000000", - "amount1Delta": "-1000", - "executionPrice": "0.99502", - "feeGrowthGlobal0X128Delta": "680564733841876926926", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": -1, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 2e18 max range liquidity swap token0 for exactly 1.0000 token1 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "2006018054162487463", - "amount1Before": "2000000000000000000", - "amount1Delta": "-1000000000000000000", - "executionPrice": "0.49850", - "feeGrowthGlobal0X128Delta": "1023918857334819954209013958517557896", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.25000", - "poolPriceBefore": "1.0000", - "tickAfter": -13864, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 2e18 max range liquidity swap token0 for exactly 1.0000 token1 to price 0.50000 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "830919884399388263", - "amount1Before": "2000000000000000000", - "amount1Delta": "-585786437626904951", - "executionPrice": "0.70499", - "feeGrowthGlobal0X128Delta": "424121077477644648929101317621422688", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.50000", - "poolPriceBefore": "1.0000", - "tickAfter": -6932, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 2e18 max range liquidity swap token0 for token1 to price 0.40000 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "1165774985123750584", - "amount1Before": "2000000000000000000", - "amount1Delta": "-735088935932648267", - "executionPrice": "0.63056", - "feeGrowthGlobal0X128Delta": "595039006852697554786973994761078087", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.40000", - "poolPriceBefore": "1.0000", - "tickAfter": -9164, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 2e18 max range liquidity swap token0 for token1 to price 2.5000 1`] = ` -Object { - "poolBalance0": "2000000000000000000", - "poolBalance1": "2000000000000000000", - "poolPriceBefore": "1.0000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 2e18 max range liquidity swap token1 for exactly 0.0000000000000010000 token0 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "-1000", - "amount1Before": "2000000000000000000", - "amount1Delta": "1005", - "executionPrice": "1.0050", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "680564733841876926926", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 0, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 2e18 max range liquidity swap token1 for exactly 1.0000 token0 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "-1000000000000000000", - "amount1Before": "2000000000000000000", - "amount1Delta": "2006018054162487463", - "executionPrice": "2.0060", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "1023918857334819954209013958517557896", - "poolPriceAfter": "4.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 13863, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 2e18 max range liquidity swap token1 for exactly 1.0000 token0 to price 2.0000 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "-585786437626904951", - "amount1Before": "2000000000000000000", - "amount1Delta": "830919884399388263", - "executionPrice": "1.4185", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "424121077477644648929101317621422688", - "poolPriceAfter": "2.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 6931, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 2e18 max range liquidity swap token1 for token0 to price 0.40000 1`] = ` -Object { - "poolBalance0": "2000000000000000000", - "poolBalance1": "2000000000000000000", - "poolPriceBefore": "1.0000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, 2e18 max range liquidity swap token1 for token0 to price 2.5000 1`] = ` -Object { - "amount0Before": "2000000000000000000", - "amount0Delta": "-735088935932648267", - "amount1Before": "2000000000000000000", - "amount1Delta": "1165774985123750584", - "executionPrice": "1.5859", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "595039006852697554786973994761078087", - "poolPriceAfter": "2.5000", - "poolPriceBefore": "1.0000", - "tickAfter": 9163, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, additional liquidity around current price swap exactly 0.0000000000000010000 token0 for token1 1`] = ` -Object { - "amount0Before": "3994009290088178439", - "amount0Delta": "1000", - "amount1Before": "3994009290088178439", - "amount1Delta": "-996", - "executionPrice": "0.99600", - "feeGrowthGlobal0X128Delta": "510423550381407695195", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": -1, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, additional liquidity around current price swap exactly 0.0000000000000010000 token1 for token0 1`] = ` -Object { - "amount0Before": "3994009290088178439", - "amount0Delta": "-996", - "amount1Before": "3994009290088178439", - "amount1Delta": "1000", - "executionPrice": "1.0040", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "510423550381407695195", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 0, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, additional liquidity around current price swap exactly 1.0000 token0 for token1 1`] = ` -Object { - "amount0Before": "3994009290088178439", - "amount0Delta": "1000000000000000000", - "amount1Before": "3994009290088178439", - "amount1Delta": "-795933705287758544", - "executionPrice": "0.79593", - "feeGrowthGlobal0X128Delta": "256749882580179971840679703106063897", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.63923", - "poolPriceBefore": "1.0000", - "tickAfter": -4476, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, additional liquidity around current price swap exactly 1.0000 token0 for token1 to price 0.50000 1`] = ` -Object { - "amount0Before": "3994009290088178439", - "amount0Delta": "1000000000000000000", - "amount1Before": "3994009290088178439", - "amount1Delta": "-795933705287758544", - "executionPrice": "0.79593", - "feeGrowthGlobal0X128Delta": "256749882580179971840679703106063897", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.63923", - "poolPriceBefore": "1.0000", - "tickAfter": -4476, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, additional liquidity around current price swap exactly 1.0000 token1 for token0 1`] = ` -Object { - "amount0Before": "3994009290088178439", - "amount0Delta": "-795933705287758544", - "amount1Before": "3994009290088178439", - "amount1Delta": "1000000000000000000", - "executionPrice": "1.2564", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "256749882580179971840679703106063897", - "poolPriceAfter": "1.5644", - "poolPriceBefore": "1.0000", - "tickAfter": 4475, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, additional liquidity around current price swap exactly 1.0000 token1 for token0 to price 2.0000 1`] = ` -Object { - "amount0Before": "3994009290088178439", - "amount0Delta": "-795933705287758544", - "amount1Before": "3994009290088178439", - "amount1Delta": "1000000000000000000", - "executionPrice": "1.2564", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "256749882580179971840679703106063897", - "poolPriceAfter": "1.5644", - "poolPriceBefore": "1.0000", - "tickAfter": 4475, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, additional liquidity around current price swap token0 for exactly 0.0000000000000010000 token1 1`] = ` -Object { - "amount0Before": "3994009290088178439", - "amount0Delta": "1005", - "amount1Before": "3994009290088178439", - "amount1Delta": "-1000", - "executionPrice": "0.99502", - "feeGrowthGlobal0X128Delta": "680564733841876926926", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": -1, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, additional liquidity around current price swap token0 for exactly 1.0000 token1 1`] = ` -Object { - "amount0Before": "3994009290088178439", - "amount0Delta": "1342022152495072924", - "amount1Before": "3994009290088178439", - "amount1Delta": "-1000000000000000000", - "executionPrice": "0.74514", - "feeGrowthGlobal0X128Delta": "344037963272993171369654596359692757", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.56026", - "poolPriceBefore": "1.0000", - "tickAfter": -5794, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, additional liquidity around current price swap token0 for exactly 1.0000 token1 to price 0.50000 1`] = ` -Object { - "amount0Before": "3994009290088178439", - "amount0Delta": "1342022152495072924", - "amount1Before": "3994009290088178439", - "amount1Delta": "-1000000000000000000", - "executionPrice": "0.74514", - "feeGrowthGlobal0X128Delta": "344037963272993171369654596359692757", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.56026", - "poolPriceBefore": "1.0000", - "tickAfter": -5794, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, additional liquidity around current price swap token0 for token1 to price 0.40000 1`] = ` -Object { - "amount0Before": "3994009290088178439", - "amount0Delta": "2325523181756544449", - "amount1Before": "3994009290088178439", - "amount1Delta": "-1464187161953474971", - "executionPrice": "0.62962", - "feeGrowthGlobal0X128Delta": "595039006852697724928157455230309818", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.40000", - "poolPriceBefore": "1.0000", - "tickAfter": -9164, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, additional liquidity around current price swap token0 for token1 to price 2.5000 1`] = ` -Object { - "poolBalance0": "3994009290088178439", - "poolBalance1": "3994009290088178439", - "poolPriceBefore": "1.0000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, additional liquidity around current price swap token1 for exactly 0.0000000000000010000 token0 1`] = ` -Object { - "amount0Before": "3994009290088178439", - "amount0Delta": "-1000", - "amount1Before": "3994009290088178439", - "amount1Delta": "1005", - "executionPrice": "1.0050", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "680564733841876926926", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 0, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, additional liquidity around current price swap token1 for exactly 1.0000 token0 1`] = ` -Object { - "amount0Before": "3994009290088178439", - "amount0Delta": "-1000000000000000000", - "amount1Before": "3994009290088178439", - "amount1Delta": "1342022152495072924", - "executionPrice": "1.3420", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "344037963272993171369654596359692757", - "poolPriceAfter": "1.7849", - "poolPriceBefore": "1.0000", - "tickAfter": 5793, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, additional liquidity around current price swap token1 for exactly 1.0000 token0 to price 2.0000 1`] = ` -Object { - "amount0Before": "3994009290088178439", - "amount0Delta": "-1000000000000000000", - "amount1Before": "3994009290088178439", - "amount1Delta": "1342022152495072924", - "executionPrice": "1.3420", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "344037963272993171369654596359692757", - "poolPriceAfter": "1.7849", - "poolPriceBefore": "1.0000", - "tickAfter": 5793, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, additional liquidity around current price swap token1 for token0 to price 0.40000 1`] = ` -Object { - "poolBalance0": "3994009290088178439", - "poolBalance1": "3994009290088178439", - "poolPriceBefore": "1.0000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:1 price, additional liquidity around current price swap token1 for token0 to price 2.5000 1`] = ` -Object { - "amount0Before": "3994009290088178439", - "amount0Delta": "-1464187161953474971", - "amount1Before": "3994009290088178439", - "amount1Delta": "2325523181756544449", - "executionPrice": "1.5883", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "595039006852697724928157455230309818", - "poolPriceAfter": "2.5000", - "poolPriceBefore": "1.0000", - "tickAfter": 9163, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:10 price, 2e18 max range liquidity swap exactly 0.0000000000000010000 token0 for token1 1`] = ` -Object { - "amount0Before": "6324555320336758664", - "amount0Delta": "1000", - "amount1Before": "632455532033675867", - "amount1Delta": "-99", - "executionPrice": "0.099000", - "feeGrowthGlobal0X128Delta": "510423550381407695195", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.10000", - "poolPriceBefore": "0.10000", - "tickAfter": -23028, - "tickBefore": -23028, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:10 price, 2e18 max range liquidity swap exactly 0.0000000000000010000 token1 for token0 1`] = ` -Object { - "amount0Before": "6324555320336758664", - "amount0Delta": "-9969", - "amount1Before": "632455532033675867", - "amount1Delta": "1000", - "executionPrice": "0.10031", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "510423550381407695195", - "poolPriceAfter": "0.10000", - "poolPriceBefore": "0.10000", - "tickAfter": -23028, - "tickBefore": -23028, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:10 price, 2e18 max range liquidity swap exactly 1.0000 token0 for token1 1`] = ` -Object { - "amount0Before": "6324555320336758664", - "amount0Delta": "1000000000000000000", - "amount1Before": "632455532033675867", - "amount1Delta": "-86123526743846551", - "executionPrice": "0.086124", - "feeGrowthGlobal0X128Delta": "510423550381407695195061911147652317", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.074620", - "poolPriceBefore": "0.10000", - "tickAfter": -25955, - "tickBefore": -23028, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:10 price, 2e18 max range liquidity swap exactly 1.0000 token0 for token1 to price 0.50000 1`] = ` -Object { - "poolBalance0": "6324555320336758664", - "poolBalance1": "632455532033675867", - "poolPriceBefore": "0.10000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": -23028, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:10 price, 2e18 max range liquidity swap exactly 1.0000 token1 for token0 1`] = ` -Object { - "amount0Before": "6324555320336758664", - "amount0Delta": "-3869747612262812753", - "amount1Before": "632455532033675867", - "amount1Delta": "1000000000000000000", - "executionPrice": "0.25841", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "510423550381407865336245371616884047", - "poolPriceAfter": "0.66378", - "poolPriceBefore": "0.10000", - "tickAfter": -4099, - "tickBefore": -23028, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:10 price, 2e18 max range liquidity swap exactly 1.0000 token1 for token0 to price 2.0000 1`] = ` -Object { - "amount0Before": "6324555320336758664", - "amount0Delta": "-3869747612262812753", - "amount1Before": "632455532033675867", - "amount1Delta": "1000000000000000000", - "executionPrice": "0.25841", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "510423550381407865336245371616884047", - "poolPriceAfter": "0.66378", - "poolPriceBefore": "0.10000", - "tickAfter": -4099, - "tickBefore": -23028, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:10 price, 2e18 max range liquidity swap token0 for exactly 0.0000000000000010000 token1 1`] = ` -Object { - "amount0Before": "6324555320336758664", - "amount0Delta": "10032", - "amount1Before": "632455532033675867", - "amount1Delta": "-1000", - "executionPrice": "0.099681", - "feeGrowthGlobal0X128Delta": "5274376687274546183682", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.10000", - "poolPriceBefore": "0.10000", - "tickAfter": -23028, - "tickBefore": -23028, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:10 price, 2e18 max range liquidity swap token0 for exactly 1.0000 token1 1`] = ` -Object { - "amount0Before": "6324555320336758664", - "amount0Delta": "36907032419362389223785084665766560335", - "amount1Before": "632455532033675867", - "amount1Delta": "-632455532033675838", - "executionPrice": "0.000000000000000000017136", - "feeGrowthGlobal0X128Delta": "18838218521532665615644565874197034349094564536667752274", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.0000000000000000000000000000000000000029390", - "poolPriceBefore": "0.10000", - "tickAfter": -887272, - "tickBefore": -23028, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:10 price, 2e18 max range liquidity swap token0 for exactly 1.0000 token1 to price 0.50000 1`] = ` -Object { - "poolBalance0": "6324555320336758664", - "poolBalance1": "632455532033675867", - "poolPriceBefore": "0.10000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": -23028, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:10 price, 2e18 max range liquidity swap token0 for token1 to price 0.40000 1`] = ` -Object { - "poolBalance0": "6324555320336758664", - "poolBalance1": "632455532033675867", - "poolPriceBefore": "0.10000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": -23028, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:10 price, 2e18 max range liquidity swap token0 for token1 to price 2.5000 1`] = ` -Object { - "poolBalance0": "6324555320336758664", - "poolBalance1": "632455532033675867", - "poolPriceBefore": "0.10000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": -23028, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:10 price, 2e18 max range liquidity swap token1 for exactly 0.0000000000000010000 token0 1`] = ` -Object { - "amount0Before": "6324555320336758664", - "amount0Delta": "-1000", - "amount1Before": "632455532033675867", - "amount1Delta": "102", - "executionPrice": "0.10200", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "170141183460469231731", - "poolPriceAfter": "0.10000", - "poolPriceBefore": "0.10000", - "tickAfter": -23028, - "tickBefore": -23028, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:10 price, 2e18 max range liquidity swap token1 for exactly 1.0000 token0 1`] = ` -Object { - "amount0Before": "6324555320336758664", - "amount0Delta": "-1000000000000000000", - "amount1Before": "632455532033675867", - "amount1Delta": "119138326055954425", - "executionPrice": "0.11914", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "60811007371978153949466126675899993", - "poolPriceAfter": "0.14109", - "poolPriceBefore": "0.10000", - "tickAfter": -19585, - "tickBefore": -23028, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:10 price, 2e18 max range liquidity swap token1 for exactly 1.0000 token0 to price 2.0000 1`] = ` -Object { - "amount0Before": "6324555320336758664", - "amount0Delta": "-1000000000000000000", - "amount1Before": "632455532033675867", - "amount1Delta": "119138326055954425", - "executionPrice": "0.11914", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "60811007371978153949466126675899993", - "poolPriceAfter": "0.14109", - "poolPriceBefore": "0.10000", - "tickAfter": -19585, - "tickBefore": -23028, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:10 price, 2e18 max range liquidity swap token1 for token0 to price 0.40000 1`] = ` -Object { - "amount0Before": "6324555320336758664", - "amount0Delta": "-3162277660168379331", - "amount1Before": "632455532033675867", - "amount1Delta": "634358607857247611", - "executionPrice": "0.20060", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "323791572837503501799197590655727195", - "poolPriceAfter": "0.40000", - "poolPriceBefore": "0.10000", - "tickAfter": -9164, - "tickBefore": -23028, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 1:10 price, 2e18 max range liquidity swap token1 for token0 to price 2.5000 1`] = ` -Object { - "amount0Before": "6324555320336758664", - "amount0Delta": "-5059644256269406930", - "amount1Before": "632455532033675867", - "amount1Delta": "2537434431428990440", - "executionPrice": "0.50150", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "1295166291350014177337973823092140516", - "poolPriceAfter": "2.5000", - "poolPriceBefore": "0.10000", - "tickAfter": 9163, - "tickBefore": -23028, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 10:1 price, 2e18 max range liquidity swap exactly 0.0000000000000010000 token0 for token1 1`] = ` -Object { - "amount0Before": "632455532033675867", - "amount0Delta": "1000", - "amount1Before": "6324555320336758664", - "amount1Delta": "-9969", - "executionPrice": "9.9690", - "feeGrowthGlobal0X128Delta": "510423550381407695195", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "10.000", - "poolPriceBefore": "10.000", - "tickAfter": 23027, - "tickBefore": 23027, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 10:1 price, 2e18 max range liquidity swap exactly 0.0000000000000010000 token1 for token0 1`] = ` -Object { - "amount0Before": "632455532033675867", - "amount0Delta": "-99", - "amount1Before": "6324555320336758664", - "amount1Delta": "1000", - "executionPrice": "10.101", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "510423550381407695195", - "poolPriceAfter": "10.000", - "poolPriceBefore": "10.000", - "tickAfter": 23027, - "tickBefore": 23027, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 10:1 price, 2e18 max range liquidity swap exactly 1.0000 token0 for token1 1`] = ` -Object { - "amount0Before": "632455532033675867", - "amount0Delta": "1000000000000000000", - "amount1Before": "6324555320336758664", - "amount1Delta": "-3869747612262812754", - "executionPrice": "3.8697", - "feeGrowthGlobal0X128Delta": "510423550381407865336245371616884048", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "1.5065", - "poolPriceBefore": "10.000", - "tickAfter": 4098, - "tickBefore": 23027, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 10:1 price, 2e18 max range liquidity swap exactly 1.0000 token0 for token1 to price 0.50000 1`] = ` -Object { - "amount0Before": "632455532033675867", - "amount0Delta": "1000000000000000000", - "amount1Before": "6324555320336758664", - "amount1Delta": "-3869747612262812754", - "executionPrice": "3.8697", - "feeGrowthGlobal0X128Delta": "510423550381407865336245371616884048", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "1.5065", - "poolPriceBefore": "10.000", - "tickAfter": 4098, - "tickBefore": 23027, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 10:1 price, 2e18 max range liquidity swap exactly 1.0000 token1 for token0 1`] = ` -Object { - "amount0Before": "632455532033675867", - "amount0Delta": "-86123526743846551", - "amount1Before": "6324555320336758664", - "amount1Delta": "1000000000000000000", - "executionPrice": "11.611", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "510423550381407695195061911147652317", - "poolPriceAfter": "13.401", - "poolPriceBefore": "10.000", - "tickAfter": 25954, - "tickBefore": 23027, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 10:1 price, 2e18 max range liquidity swap exactly 1.0000 token1 for token0 to price 2.0000 1`] = ` -Object { - "poolBalance0": "632455532033675867", - "poolBalance1": "6324555320336758664", - "poolPriceBefore": "10.000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 23027, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 10:1 price, 2e18 max range liquidity swap token0 for exactly 0.0000000000000010000 token1 1`] = ` -Object { - "amount0Before": "632455532033675867", - "amount0Delta": "102", - "amount1Before": "6324555320336758664", - "amount1Delta": "-1000", - "executionPrice": "9.8039", - "feeGrowthGlobal0X128Delta": "170141183460469231731", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "10.000", - "poolPriceBefore": "10.000", - "tickAfter": 23027, - "tickBefore": 23027, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 10:1 price, 2e18 max range liquidity swap token0 for exactly 1.0000 token1 1`] = ` -Object { - "amount0Before": "632455532033675867", - "amount0Delta": "119138326055954425", - "amount1Before": "6324555320336758664", - "amount1Delta": "-1000000000000000000", - "executionPrice": "8.3936", - "feeGrowthGlobal0X128Delta": "60811007371978153949466126675899993", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "7.0877", - "poolPriceBefore": "10.000", - "tickAfter": 19584, - "tickBefore": 23027, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 10:1 price, 2e18 max range liquidity swap token0 for exactly 1.0000 token1 to price 0.50000 1`] = ` -Object { - "amount0Before": "632455532033675867", - "amount0Delta": "119138326055954425", - "amount1Before": "6324555320336758664", - "amount1Delta": "-1000000000000000000", - "executionPrice": "8.3936", - "feeGrowthGlobal0X128Delta": "60811007371978153949466126675899993", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "7.0877", - "poolPriceBefore": "10.000", - "tickAfter": 19584, - "tickBefore": 23027, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 10:1 price, 2e18 max range liquidity swap token0 for token1 to price 0.40000 1`] = ` -Object { - "amount0Before": "632455532033675867", - "amount0Delta": "2537434431428990438", - "amount1Before": "6324555320336758664", - "amount1Delta": "-5059644256269406930", - "executionPrice": "1.9940", - "feeGrowthGlobal0X128Delta": "1295166291350014007196790362622908786", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.40000", - "poolPriceBefore": "10.000", - "tickAfter": -9164, - "tickBefore": 23027, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 10:1 price, 2e18 max range liquidity swap token0 for token1 to price 2.5000 1`] = ` -Object { - "amount0Before": "632455532033675867", - "amount0Delta": "634358607857247610", - "amount1Before": "6324555320336758664", - "amount1Delta": "-3162277660168379331", - "executionPrice": "4.9850", - "feeGrowthGlobal0X128Delta": "323791572837503501799197590655727196", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "2.5000", - "poolPriceBefore": "10.000", - "tickAfter": 9163, - "tickBefore": 23027, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 10:1 price, 2e18 max range liquidity swap token1 for exactly 0.0000000000000010000 token0 1`] = ` -Object { - "amount0Before": "632455532033675867", - "amount0Delta": "-1000", - "amount1Before": "6324555320336758664", - "amount1Delta": "10032", - "executionPrice": "10.032", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "5274376687274546183682", - "poolPriceAfter": "10.000", - "poolPriceBefore": "10.000", - "tickAfter": 23027, - "tickBefore": 23027, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 10:1 price, 2e18 max range liquidity swap token1 for exactly 1.0000 token0 1`] = ` -Object { - "amount0Before": "632455532033675867", - "amount0Delta": "-632455532033675838", - "amount1Before": "6324555320336758664", - "amount1Delta": "36907032426281581270030941278837275671", - "executionPrice": "5.8355e+19", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "18838218525064384185660173270402201838945341643205005201", - "poolPriceAfter": "3.4026e+38", - "poolPriceBefore": "10.000", - "tickAfter": 887271, - "tickBefore": 23027, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 10:1 price, 2e18 max range liquidity swap token1 for exactly 1.0000 token0 to price 2.0000 1`] = ` -Object { - "poolBalance0": "632455532033675867", - "poolBalance1": "6324555320336758664", - "poolPriceBefore": "10.000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 23027, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 10:1 price, 2e18 max range liquidity swap token1 for token0 to price 0.40000 1`] = ` -Object { - "poolBalance0": "632455532033675867", - "poolBalance1": "6324555320336758664", - "poolPriceBefore": "10.000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 23027, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, 10:1 price, 2e18 max range liquidity swap token1 for token0 to price 2.5000 1`] = ` -Object { - "poolBalance0": "632455532033675867", - "poolBalance1": "6324555320336758664", - "poolPriceBefore": "10.000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 23027, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token0 liquidity only swap exactly 0.0000000000000010000 token0 for token1 1`] = ` -Object { - "amount0Before": "1995041008271423675", - "amount0Delta": "0", - "amount1Before": "0", - "amount1Delta": "0", - "executionPrice": "NaN", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.0000000000000000000000000000000000000029390", - "poolPriceBefore": "1.0000", - "tickAfter": -887272, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token0 liquidity only swap exactly 0.0000000000000010000 token1 for token0 1`] = ` -Object { - "amount0Before": "1995041008271423675", - "amount0Delta": "-996", - "amount1Before": "0", - "amount1Delta": "1000", - "executionPrice": "1.0040", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "510423550381407695195", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 0, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token0 liquidity only swap exactly 1.0000 token0 for token1 1`] = ` -Object { - "amount0Before": "1995041008271423675", - "amount0Delta": "0", - "amount1Before": "0", - "amount1Delta": "0", - "executionPrice": "NaN", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.0000000000000000000000000000000000000029390", - "poolPriceBefore": "1.0000", - "tickAfter": -887272, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token0 liquidity only swap exactly 1.0000 token0 for token1 to price 0.50000 1`] = ` -Object { - "amount0Before": "1995041008271423675", - "amount0Delta": "0", - "amount1Before": "0", - "amount1Delta": "0", - "executionPrice": "NaN", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.50000", - "poolPriceBefore": "1.0000", - "tickAfter": -6932, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token0 liquidity only swap exactly 1.0000 token1 for token0 1`] = ` -Object { - "amount0Before": "1995041008271423675", - "amount0Delta": "-665331998665331998", - "amount1Before": "0", - "amount1Delta": "1000000000000000000", - "executionPrice": "1.5030", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "510423550381407695195061911147652317", - "poolPriceAfter": "2.2455", - "poolPriceBefore": "1.0000", - "tickAfter": 8089, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token0 liquidity only swap exactly 1.0000 token1 for token0 to price 2.0000 1`] = ` -Object { - "amount0Before": "1995041008271423675", - "amount0Delta": "-585786437626904951", - "amount1Before": "0", - "amount1Delta": "830919884399388263", - "executionPrice": "1.4185", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "424121077477644648929101317621422688", - "poolPriceAfter": "2.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 6931, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token0 liquidity only swap token0 for exactly 0.0000000000000010000 token1 1`] = ` -Object { - "amount0Before": "1995041008271423675", - "amount0Delta": "0", - "amount1Before": "0", - "amount1Delta": "0", - "executionPrice": "NaN", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.0000000000000000000000000000000000000029390", - "poolPriceBefore": "1.0000", - "tickAfter": -887272, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token0 liquidity only swap token0 for exactly 1.0000 token1 1`] = ` -Object { - "amount0Before": "1995041008271423675", - "amount0Delta": "0", - "amount1Before": "0", - "amount1Delta": "0", - "executionPrice": "NaN", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.0000000000000000000000000000000000000029390", - "poolPriceBefore": "1.0000", - "tickAfter": -887272, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token0 liquidity only swap token0 for exactly 1.0000 token1 to price 0.50000 1`] = ` -Object { - "amount0Before": "1995041008271423675", - "amount0Delta": "0", - "amount1Before": "0", - "amount1Delta": "0", - "executionPrice": "NaN", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.50000", - "poolPriceBefore": "1.0000", - "tickAfter": -6932, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token0 liquidity only swap token0 for token1 to price 0.40000 1`] = ` -Object { - "amount0Before": "1995041008271423675", - "amount0Delta": "0", - "amount1Before": "0", - "amount1Delta": "0", - "executionPrice": "NaN", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.40000", - "poolPriceBefore": "1.0000", - "tickAfter": -9164, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token0 liquidity only swap token0 for token1 to price 2.5000 1`] = ` -Object { - "poolBalance0": "1995041008271423675", - "poolBalance1": "0", - "poolPriceBefore": "1.0000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token0 liquidity only swap token1 for exactly 0.0000000000000010000 token0 1`] = ` -Object { - "amount0Before": "1995041008271423675", - "amount0Delta": "-1000", - "amount1Before": "0", - "amount1Delta": "1005", - "executionPrice": "1.0050", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "680564733841876926926", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 0, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token0 liquidity only swap token1 for exactly 1.0000 token0 1`] = ` -Object { - "amount0Before": "1995041008271423675", - "amount0Delta": "-1000000000000000000", - "amount1Before": "0", - "amount1Delta": "2006018054162487463", - "executionPrice": "2.0060", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "1023918857334819954209013958517557896", - "poolPriceAfter": "4.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 13863, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token0 liquidity only swap token1 for exactly 1.0000 token0 to price 2.0000 1`] = ` -Object { - "amount0Before": "1995041008271423675", - "amount0Delta": "-585786437626904951", - "amount1Before": "0", - "amount1Delta": "830919884399388263", - "executionPrice": "1.4185", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "424121077477644648929101317621422688", - "poolPriceAfter": "2.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 6931, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token0 liquidity only swap token1 for token0 to price 0.40000 1`] = ` -Object { - "poolBalance0": "1995041008271423675", - "poolBalance1": "0", - "poolPriceBefore": "1.0000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token0 liquidity only swap token1 for token0 to price 2.5000 1`] = ` -Object { - "amount0Before": "1995041008271423675", - "amount0Delta": "-735088935932648267", - "amount1Before": "0", - "amount1Delta": "1165774985123750584", - "executionPrice": "1.5859", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "595039006852697554786973994761078087", - "poolPriceAfter": "2.5000", - "poolPriceBefore": "1.0000", - "tickAfter": 9163, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token1 liquidity only swap exactly 0.0000000000000010000 token0 for token1 1`] = ` -Object { - "amount0Before": "0", - "amount0Delta": "1000", - "amount1Before": "1995041008271423675", - "amount1Delta": "-996", - "executionPrice": "0.99600", - "feeGrowthGlobal0X128Delta": "510423550381407695195", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": -1, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token1 liquidity only swap exactly 0.0000000000000010000 token1 for token0 1`] = ` -Object { - "amount0Before": "0", - "amount0Delta": "0", - "amount1Before": "1995041008271423675", - "amount1Delta": "0", - "executionPrice": "NaN", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "3.4026e+38", - "poolPriceBefore": "1.0000", - "tickAfter": 887271, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token1 liquidity only swap exactly 1.0000 token0 for token1 1`] = ` -Object { - "amount0Before": "0", - "amount0Delta": "1000000000000000000", - "amount1Before": "1995041008271423675", - "amount1Delta": "-665331998665331998", - "executionPrice": "0.66533", - "feeGrowthGlobal0X128Delta": "510423550381407695195061911147652317", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.44533", - "poolPriceBefore": "1.0000", - "tickAfter": -8090, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token1 liquidity only swap exactly 1.0000 token0 for token1 to price 0.50000 1`] = ` -Object { - "amount0Before": "0", - "amount0Delta": "830919884399388263", - "amount1Before": "1995041008271423675", - "amount1Delta": "-585786437626904951", - "executionPrice": "0.70499", - "feeGrowthGlobal0X128Delta": "424121077477644648929101317621422688", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.50000", - "poolPriceBefore": "1.0000", - "tickAfter": -6932, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token1 liquidity only swap exactly 1.0000 token1 for token0 1`] = ` -Object { - "amount0Before": "0", - "amount0Delta": "0", - "amount1Before": "1995041008271423675", - "amount1Delta": "0", - "executionPrice": "NaN", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "3.4026e+38", - "poolPriceBefore": "1.0000", - "tickAfter": 887271, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token1 liquidity only swap exactly 1.0000 token1 for token0 to price 2.0000 1`] = ` -Object { - "amount0Before": "0", - "amount0Delta": "0", - "amount1Before": "1995041008271423675", - "amount1Delta": "0", - "executionPrice": "NaN", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "2.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 6931, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token1 liquidity only swap token0 for exactly 0.0000000000000010000 token1 1`] = ` -Object { - "amount0Before": "0", - "amount0Delta": "1005", - "amount1Before": "1995041008271423675", - "amount1Delta": "-1000", - "executionPrice": "0.99502", - "feeGrowthGlobal0X128Delta": "680564733841876926926", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "1.0000", - "poolPriceBefore": "1.0000", - "tickAfter": -1, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token1 liquidity only swap token0 for exactly 1.0000 token1 1`] = ` -Object { - "amount0Before": "0", - "amount0Delta": "2006018054162487463", - "amount1Before": "1995041008271423675", - "amount1Delta": "-1000000000000000000", - "executionPrice": "0.49850", - "feeGrowthGlobal0X128Delta": "1023918857334819954209013958517557896", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.25000", - "poolPriceBefore": "1.0000", - "tickAfter": -13864, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token1 liquidity only swap token0 for exactly 1.0000 token1 to price 0.50000 1`] = ` -Object { - "amount0Before": "0", - "amount0Delta": "830919884399388263", - "amount1Before": "1995041008271423675", - "amount1Delta": "-585786437626904951", - "executionPrice": "0.70499", - "feeGrowthGlobal0X128Delta": "424121077477644648929101317621422688", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.50000", - "poolPriceBefore": "1.0000", - "tickAfter": -6932, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token1 liquidity only swap token0 for token1 to price 0.40000 1`] = ` -Object { - "amount0Before": "0", - "amount0Delta": "1165774985123750584", - "amount1Before": "1995041008271423675", - "amount1Delta": "-735088935932648267", - "executionPrice": "0.63056", - "feeGrowthGlobal0X128Delta": "595039006852697554786973994761078087", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "0.40000", - "poolPriceBefore": "1.0000", - "tickAfter": -9164, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token1 liquidity only swap token0 for token1 to price 2.5000 1`] = ` -Object { - "poolBalance0": "0", - "poolBalance1": "1995041008271423675", - "poolPriceBefore": "1.0000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token1 liquidity only swap token1 for exactly 0.0000000000000010000 token0 1`] = ` -Object { - "amount0Before": "0", - "amount0Delta": "0", - "amount1Before": "1995041008271423675", - "amount1Delta": "0", - "executionPrice": "NaN", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "3.4026e+38", - "poolPriceBefore": "1.0000", - "tickAfter": 887271, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token1 liquidity only swap token1 for exactly 1.0000 token0 1`] = ` -Object { - "amount0Before": "0", - "amount0Delta": "0", - "amount1Before": "1995041008271423675", - "amount1Delta": "0", - "executionPrice": "NaN", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "3.4026e+38", - "poolPriceBefore": "1.0000", - "tickAfter": 887271, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token1 liquidity only swap token1 for exactly 1.0000 token0 to price 2.0000 1`] = ` -Object { - "amount0Before": "0", - "amount0Delta": "0", - "amount1Before": "1995041008271423675", - "amount1Delta": "0", - "executionPrice": "NaN", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "2.0000", - "poolPriceBefore": "1.0000", - "tickAfter": 6931, - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token1 liquidity only swap token1 for token0 to price 0.40000 1`] = ` -Object { - "poolBalance0": "0", - "poolBalance1": "1995041008271423675", - "poolPriceBefore": "1.0000", - "swapError": "VM Exception while processing transaction: revert SPL", - "tickBefore": 0, -} -`; - -exports[`UniswapV3Pool swap tests medium fee, token1 liquidity only swap token1 for token0 to price 2.5000 1`] = ` -Object { - "amount0Before": "0", - "amount0Delta": "0", - "amount1Before": "1995041008271423675", - "amount1Delta": "0", - "executionPrice": "NaN", - "feeGrowthGlobal0X128Delta": "0", - "feeGrowthGlobal1X128Delta": "0", - "poolPriceAfter": "2.5000", - "poolPriceBefore": "1.0000", - "tickAfter": 9163, - "tickBefore": 0, -} -`; diff --git a/lib/v3-core/test/shared/checkObservationEquals.ts b/lib/v3-core/test/shared/checkObservationEquals.ts deleted file mode 100644 index 744116c..0000000 --- a/lib/v3-core/test/shared/checkObservationEquals.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { BigNumber, BigNumberish } from 'ethers' -import { expect } from './expect' - -// helper function because we cannot do a simple deep equals with the -// observation result object returned from ethers because it extends array -export default function checkObservationEquals( - { - tickCumulative, - blockTimestamp, - initialized, - secondsPerLiquidityCumulativeX128, - }: { - tickCumulative: BigNumber - secondsPerLiquidityCumulativeX128: BigNumber - initialized: boolean - blockTimestamp: number - }, - expected: { - tickCumulative: BigNumberish - secondsPerLiquidityCumulativeX128: BigNumberish - initialized: boolean - blockTimestamp: number - } -) { - expect( - { - initialized, - blockTimestamp, - tickCumulative: tickCumulative.toString(), - secondsPerLiquidityCumulativeX128: secondsPerLiquidityCumulativeX128.toString(), - }, - `observation is equivalent` - ).to.deep.eq({ - ...expected, - tickCumulative: expected.tickCumulative.toString(), - secondsPerLiquidityCumulativeX128: expected.secondsPerLiquidityCumulativeX128.toString(), - }) -} diff --git a/lib/v3-core/test/shared/expect.ts b/lib/v3-core/test/shared/expect.ts deleted file mode 100644 index ac8f19b..0000000 --- a/lib/v3-core/test/shared/expect.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { expect, use } from 'chai' -import { solidity } from 'ethereum-waffle' -import { jestSnapshotPlugin } from 'mocha-chai-jest-snapshot' - -use(solidity) -use(jestSnapshotPlugin()) - -export { expect } diff --git a/lib/v3-core/test/shared/fixtures.ts b/lib/v3-core/test/shared/fixtures.ts deleted file mode 100644 index 11c84bb..0000000 --- a/lib/v3-core/test/shared/fixtures.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { BigNumber } from 'ethers' -import { ethers } from 'hardhat' -import { MockTimeUniswapV3Pool } from '../../typechain/MockTimeUniswapV3Pool' -import { TestERC20 } from '../../typechain/TestERC20' -import { UniswapV3Factory } from '../../typechain/UniswapV3Factory' -import { TestUniswapV3Callee } from '../../typechain/TestUniswapV3Callee' -import { TestUniswapV3Router } from '../../typechain/TestUniswapV3Router' -import { MockTimeUniswapV3PoolDeployer } from '../../typechain/MockTimeUniswapV3PoolDeployer' - -import { Fixture } from 'ethereum-waffle' - -interface FactoryFixture { - factory: UniswapV3Factory -} - -async function factoryFixture(): Promise { - const factoryFactory = await ethers.getContractFactory('UniswapV3Factory') - const factory = (await factoryFactory.deploy()) as UniswapV3Factory - return { factory } -} - -interface TokensFixture { - token0: TestERC20 - token1: TestERC20 - token2: TestERC20 -} - -async function tokensFixture(): Promise { - const tokenFactory = await ethers.getContractFactory('TestERC20') - const tokenA = (await tokenFactory.deploy(BigNumber.from(2).pow(255))) as TestERC20 - const tokenB = (await tokenFactory.deploy(BigNumber.from(2).pow(255))) as TestERC20 - const tokenC = (await tokenFactory.deploy(BigNumber.from(2).pow(255))) as TestERC20 - - const [token0, token1, token2] = [tokenA, tokenB, tokenC].sort((tokenA, tokenB) => - tokenA.address.toLowerCase() < tokenB.address.toLowerCase() ? -1 : 1 - ) - - return { token0, token1, token2 } -} - -type TokensAndFactoryFixture = FactoryFixture & TokensFixture - -interface PoolFixture extends TokensAndFactoryFixture { - swapTargetCallee: TestUniswapV3Callee - swapTargetRouter: TestUniswapV3Router - createPool( - fee: number, - tickSpacing: number, - firstToken?: TestERC20, - secondToken?: TestERC20 - ): Promise -} - -// Monday, October 5, 2020 9:00:00 AM GMT-05:00 -export const TEST_POOL_START_TIME = 1601906400 - -export const poolFixture: Fixture = async function (): Promise { - const { factory } = await factoryFixture() - const { token0, token1, token2 } = await tokensFixture() - - const MockTimeUniswapV3PoolDeployerFactory = await ethers.getContractFactory('MockTimeUniswapV3PoolDeployer') - const MockTimeUniswapV3PoolFactory = await ethers.getContractFactory('MockTimeUniswapV3Pool') - - const calleeContractFactory = await ethers.getContractFactory('TestUniswapV3Callee') - const routerContractFactory = await ethers.getContractFactory('TestUniswapV3Router') - - const swapTargetCallee = (await calleeContractFactory.deploy()) as TestUniswapV3Callee - const swapTargetRouter = (await routerContractFactory.deploy()) as TestUniswapV3Router - - return { - token0, - token1, - token2, - factory, - swapTargetCallee, - swapTargetRouter, - createPool: async (fee, tickSpacing, firstToken = token0, secondToken = token1) => { - const mockTimePoolDeployer = (await MockTimeUniswapV3PoolDeployerFactory.deploy()) as MockTimeUniswapV3PoolDeployer - const tx = await mockTimePoolDeployer.deploy( - factory.address, - firstToken.address, - secondToken.address, - fee, - tickSpacing - ) - - const receipt = await tx.wait() - const poolAddress = receipt.events?.[0].args?.pool as string - return MockTimeUniswapV3PoolFactory.attach(poolAddress) as MockTimeUniswapV3Pool - }, - } -} diff --git a/lib/v3-core/test/shared/format.ts b/lib/v3-core/test/shared/format.ts deleted file mode 100644 index 8d23da5..0000000 --- a/lib/v3-core/test/shared/format.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Decimal } from 'decimal.js' -import { BigNumberish } from 'ethers' - -export function formatTokenAmount(num: BigNumberish): string { - return new Decimal(num.toString()).dividedBy(new Decimal(10).pow(18)).toPrecision(5) -} - -export function formatPrice(price: BigNumberish): string { - return new Decimal(price.toString()).dividedBy(new Decimal(2).pow(96)).pow(2).toPrecision(5) -} diff --git a/lib/v3-core/test/shared/snapshotGasCost.ts b/lib/v3-core/test/shared/snapshotGasCost.ts deleted file mode 100644 index 5a606d2..0000000 --- a/lib/v3-core/test/shared/snapshotGasCost.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { TransactionReceipt, TransactionResponse } from '@ethersproject/abstract-provider' -import { expect } from './expect' -import { Contract, BigNumber, ContractTransaction } from 'ethers' - -export default async function snapshotGasCost( - x: - | TransactionResponse - | Promise - | ContractTransaction - | Promise - | TransactionReceipt - | Promise - | BigNumber - | Contract - | Promise -): Promise { - const resolved = await x - if ('deployTransaction' in resolved) { - const receipt = await resolved.deployTransaction.wait() - expect(receipt.gasUsed.toNumber()).toMatchSnapshot() - } else if ('wait' in resolved) { - const waited = await resolved.wait() - expect(waited.gasUsed.toNumber()).toMatchSnapshot() - } else if (BigNumber.isBigNumber(resolved)) { - expect(resolved.toNumber()).toMatchSnapshot() - } -} diff --git a/lib/v3-core/test/shared/utilities.ts b/lib/v3-core/test/shared/utilities.ts deleted file mode 100644 index 098149f..0000000 --- a/lib/v3-core/test/shared/utilities.ts +++ /dev/null @@ -1,258 +0,0 @@ -import bn from 'bignumber.js' -import { BigNumber, BigNumberish, constants, Contract, ContractTransaction, utils, Wallet } from 'ethers' -import { TestUniswapV3Callee } from '../../typechain/TestUniswapV3Callee' -import { TestUniswapV3Router } from '../../typechain/TestUniswapV3Router' -import { MockTimeUniswapV3Pool } from '../../typechain/MockTimeUniswapV3Pool' -import { TestERC20 } from '../../typechain/TestERC20' - -export const MaxUint128 = BigNumber.from(2).pow(128).sub(1) - -export const getMinTick = (tickSpacing: number) => Math.ceil(-887272 / tickSpacing) * tickSpacing -export const getMaxTick = (tickSpacing: number) => Math.floor(887272 / tickSpacing) * tickSpacing -export const getMaxLiquidityPerTick = (tickSpacing: number) => - BigNumber.from(2) - .pow(128) - .sub(1) - .div((getMaxTick(tickSpacing) - getMinTick(tickSpacing)) / tickSpacing + 1) - -export const MIN_SQRT_RATIO = BigNumber.from('4295128739') -export const MAX_SQRT_RATIO = BigNumber.from('1461446703485210103287273052203988822378723970342') - -export enum FeeAmount { - LOW = 500, - MEDIUM = 3000, - HIGH = 10000, -} - -export const TICK_SPACINGS: { [amount in FeeAmount]: number } = { - [FeeAmount.LOW]: 10, - [FeeAmount.MEDIUM]: 60, - [FeeAmount.HIGH]: 200, -} - -export function expandTo18Decimals(n: number): BigNumber { - return BigNumber.from(n).mul(BigNumber.from(10).pow(18)) -} - -export function getCreate2Address( - factoryAddress: string, - [tokenA, tokenB]: [string, string], - fee: number, - bytecode: string -): string { - const [token0, token1] = tokenA.toLowerCase() < tokenB.toLowerCase() ? [tokenA, tokenB] : [tokenB, tokenA] - const constructorArgumentsEncoded = utils.defaultAbiCoder.encode( - ['address', 'address', 'uint24'], - [token0, token1, fee] - ) - const create2Inputs = [ - '0xff', - factoryAddress, - // salt - utils.keccak256(constructorArgumentsEncoded), - // init code. bytecode + constructor arguments - utils.keccak256(bytecode), - ] - const sanitizedInputs = `0x${create2Inputs.map((i) => i.slice(2)).join('')}` - return utils.getAddress(`0x${utils.keccak256(sanitizedInputs).slice(-40)}`) -} - -bn.config({ EXPONENTIAL_AT: 999999, DECIMAL_PLACES: 40 }) - -// returns the sqrt price as a 64x96 -export function encodePriceSqrt(reserve1: BigNumberish, reserve0: BigNumberish): BigNumber { - return BigNumber.from( - new bn(reserve1.toString()) - .div(reserve0.toString()) - .sqrt() - .multipliedBy(new bn(2).pow(96)) - .integerValue(3) - .toString() - ) -} - -export function getPositionKey(address: string, lowerTick: number, upperTick: number): string { - return utils.keccak256(utils.solidityPack(['address', 'int24', 'int24'], [address, lowerTick, upperTick])) -} - -export type SwapFunction = ( - amount: BigNumberish, - to: Wallet | string, - sqrtPriceLimitX96?: BigNumberish -) => Promise -export type SwapToPriceFunction = (sqrtPriceX96: BigNumberish, to: Wallet | string) => Promise -export type FlashFunction = ( - amount0: BigNumberish, - amount1: BigNumberish, - to: Wallet | string, - pay0?: BigNumberish, - pay1?: BigNumberish -) => Promise -export type MintFunction = ( - recipient: string, - tickLower: BigNumberish, - tickUpper: BigNumberish, - liquidity: BigNumberish -) => Promise -export interface PoolFunctions { - swapToLowerPrice: SwapToPriceFunction - swapToHigherPrice: SwapToPriceFunction - swapExact0For1: SwapFunction - swap0ForExact1: SwapFunction - swapExact1For0: SwapFunction - swap1ForExact0: SwapFunction - flash: FlashFunction - mint: MintFunction -} -export function createPoolFunctions({ - swapTarget, - token0, - token1, - pool, -}: { - swapTarget: TestUniswapV3Callee - token0: TestERC20 - token1: TestERC20 - pool: MockTimeUniswapV3Pool -}): PoolFunctions { - async function swapToSqrtPrice( - inputToken: Contract, - targetPrice: BigNumberish, - to: Wallet | string - ): Promise { - const method = inputToken === token0 ? swapTarget.swapToLowerSqrtPrice : swapTarget.swapToHigherSqrtPrice - - await inputToken.approve(swapTarget.address, constants.MaxUint256) - - const toAddress = typeof to === 'string' ? to : to.address - - return method(pool.address, targetPrice, toAddress) - } - - async function swap( - inputToken: Contract, - [amountIn, amountOut]: [BigNumberish, BigNumberish], - to: Wallet | string, - sqrtPriceLimitX96?: BigNumberish - ): Promise { - const exactInput = amountOut === 0 - - const method = - inputToken === token0 - ? exactInput - ? swapTarget.swapExact0For1 - : swapTarget.swap0ForExact1 - : exactInput - ? swapTarget.swapExact1For0 - : swapTarget.swap1ForExact0 - - if (typeof sqrtPriceLimitX96 === 'undefined') { - if (inputToken === token0) { - sqrtPriceLimitX96 = MIN_SQRT_RATIO.add(1) - } else { - sqrtPriceLimitX96 = MAX_SQRT_RATIO.sub(1) - } - } - await inputToken.approve(swapTarget.address, constants.MaxUint256) - - const toAddress = typeof to === 'string' ? to : to.address - - return method(pool.address, exactInput ? amountIn : amountOut, toAddress, sqrtPriceLimitX96) - } - - const swapToLowerPrice: SwapToPriceFunction = (sqrtPriceX96, to) => { - return swapToSqrtPrice(token0, sqrtPriceX96, to) - } - - const swapToHigherPrice: SwapToPriceFunction = (sqrtPriceX96, to) => { - return swapToSqrtPrice(token1, sqrtPriceX96, to) - } - - const swapExact0For1: SwapFunction = (amount, to, sqrtPriceLimitX96) => { - return swap(token0, [amount, 0], to, sqrtPriceLimitX96) - } - - const swap0ForExact1: SwapFunction = (amount, to, sqrtPriceLimitX96) => { - return swap(token0, [0, amount], to, sqrtPriceLimitX96) - } - - const swapExact1For0: SwapFunction = (amount, to, sqrtPriceLimitX96) => { - return swap(token1, [amount, 0], to, sqrtPriceLimitX96) - } - - const swap1ForExact0: SwapFunction = (amount, to, sqrtPriceLimitX96) => { - return swap(token1, [0, amount], to, sqrtPriceLimitX96) - } - - const mint: MintFunction = async (recipient, tickLower, tickUpper, liquidity) => { - await token0.approve(swapTarget.address, constants.MaxUint256) - await token1.approve(swapTarget.address, constants.MaxUint256) - return swapTarget.mint(pool.address, recipient, tickLower, tickUpper, liquidity) - } - - const flash: FlashFunction = async (amount0, amount1, to, pay0?: BigNumberish, pay1?: BigNumberish) => { - const fee = await pool.fee() - if (typeof pay0 === 'undefined') { - pay0 = BigNumber.from(amount0) - .mul(fee) - .add(1e6 - 1) - .div(1e6) - .add(amount0) - } - if (typeof pay1 === 'undefined') { - pay1 = BigNumber.from(amount1) - .mul(fee) - .add(1e6 - 1) - .div(1e6) - .add(amount1) - } - return swapTarget.flash(pool.address, typeof to === 'string' ? to : to.address, amount0, amount1, pay0, pay1) - } - - return { - swapToLowerPrice, - swapToHigherPrice, - swapExact0For1, - swap0ForExact1, - swapExact1For0, - swap1ForExact0, - mint, - flash, - } -} - -export interface MultiPoolFunctions { - swapForExact0Multi: SwapFunction - swapForExact1Multi: SwapFunction -} - -export function createMultiPoolFunctions({ - inputToken, - swapTarget, - poolInput, - poolOutput, -}: { - inputToken: TestERC20 - swapTarget: TestUniswapV3Router - poolInput: MockTimeUniswapV3Pool - poolOutput: MockTimeUniswapV3Pool -}): MultiPoolFunctions { - async function swapForExact0Multi(amountOut: BigNumberish, to: Wallet | string): Promise { - const method = swapTarget.swapForExact0Multi - await inputToken.approve(swapTarget.address, constants.MaxUint256) - const toAddress = typeof to === 'string' ? to : to.address - return method(toAddress, poolInput.address, poolOutput.address, amountOut) - } - - async function swapForExact1Multi(amountOut: BigNumberish, to: Wallet | string): Promise { - const method = swapTarget.swapForExact1Multi - await inputToken.approve(swapTarget.address, constants.MaxUint256) - const toAddress = typeof to === 'string' ? to : to.address - return method(toAddress, poolInput.address, poolOutput.address, amountOut) - } - - return { - swapForExact0Multi, - swapForExact1Multi, - } -} diff --git a/lib/v3-core/tsconfig.json b/lib/v3-core/tsconfig.json deleted file mode 100644 index 1522f0b..0000000 --- a/lib/v3-core/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "compilerOptions": { - "target": "es2018", - "module": "commonjs", - "strict": true, - "esModuleInterop": true, - "outDir": "dist", - "typeRoots": ["./typechain", "./node_modules/@types"], - "types": ["@nomiclabs/hardhat-ethers", "@nomiclabs/hardhat-waffle"] - }, - "include": ["./test"], - "files": ["./hardhat.config.ts"] -} diff --git a/lib/v3-core/yarn.lock b/lib/v3-core/yarn.lock deleted file mode 100644 index d2e231b..0000000 --- a/lib/v3-core/yarn.lock +++ /dev/null @@ -1,9271 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/code-frame@^7.0.0": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" - integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== - dependencies: - "@babel/highlight" "^7.10.4" - -"@babel/helper-validator-identifier@^7.10.4", "@babel/helper-validator-identifier@^7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" - integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== - -"@babel/highlight@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" - integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== - dependencies: - "@babel/helper-validator-identifier" "^7.10.4" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/types@^7.0.0", "@babel/types@^7.3.0": - version "7.12.12" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.12.tgz#4608a6ec313abbd87afa55004d373ad04a96c299" - integrity sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ== - dependencies: - "@babel/helper-validator-identifier" "^7.12.11" - lodash "^4.17.19" - to-fast-properties "^2.0.0" - -"@cnakazawa/watch@^1.0.3": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" - integrity sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ== - dependencies: - exec-sh "^0.3.2" - minimist "^1.2.0" - -"@ensdomains/ens@^0.4.4": - version "0.4.5" - resolved "https://registry.yarnpkg.com/@ensdomains/ens/-/ens-0.4.5.tgz#e0aebc005afdc066447c6e22feb4eda89a5edbfc" - integrity sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw== - dependencies: - bluebird "^3.5.2" - eth-ens-namehash "^2.0.8" - solc "^0.4.20" - testrpc "0.0.1" - web3-utils "^1.0.0-beta.31" - -"@ensdomains/resolver@^0.2.4": - version "0.2.4" - resolved "https://registry.yarnpkg.com/@ensdomains/resolver/-/resolver-0.2.4.tgz#c10fe28bf5efbf49bff4666d909aed0265efbc89" - integrity sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA== - -"@ethereum-waffle/chai@^3.2.1": - version "3.2.1" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/chai/-/chai-3.2.1.tgz#5cb542b2a323adf0bc2dda00f48b0eb85944d8ab" - integrity sha512-0aG946J1+2Gg7WnEjtwPEWe+xwLTeBTy6LpCnGecosMf3YINkaf9Xv3Sd7CrXBR88ihCoUhfzfmOloMHIAQPAg== - dependencies: - "@ethereum-waffle/provider" "^3.2.1" - ethers "^5.0.0" - -"@ethereum-waffle/compiler@^3.2.1": - version "3.2.1" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/compiler/-/compiler-3.2.1.tgz#612a9056285a94ce28eb57b895770ad10e438bf9" - integrity sha512-URSsbTp4g8HPHAaA4KiAD6Aya9WPx/TULfOr+YpjCJ6YWXqE9wwi3ubf9qJUQxu6W6PsiczBaQhVhpI9RLoVUA== - dependencies: - "@resolver-engine/imports" "^0.3.3" - "@resolver-engine/imports-fs" "^0.3.3" - "@types/mkdirp" "^0.5.2" - "@types/node-fetch" "^2.5.5" - ethers "^5.0.1" - mkdirp "^0.5.1" - node-fetch "^2.6.0" - solc "^0.6.3" - -"@ethereum-waffle/ens@^3.2.1": - version "3.2.1" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/ens/-/ens-3.2.1.tgz#9f369112d62f7aa88d010be4d133b6d0f5e8c492" - integrity sha512-dXv/Mb8EgEYOKv2jjmkFNFCmSjNv8nPk1Gaegc0J/KXWuTU6CBOhWet7YS5joGO8ORK21MvN2qVgcQj+FYw0Dw== - dependencies: - "@ensdomains/ens" "^0.4.4" - "@ensdomains/resolver" "^0.2.4" - ethers "^5.0.1" - -"@ethereum-waffle/mock-contract@^3.2.1": - version "3.2.1" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/mock-contract/-/mock-contract-3.2.1.tgz#bf5f63f61c9749eb3270108893a88ff161e68f58" - integrity sha512-39GMp/IqsHF+3j3XK38cWA+nX7Q6ABfMsYkuAjtfpTguTFQKXx2C1/VJZwGOyb4de2pl4bssmN37VEraB3NWbQ== - dependencies: - "@ethersproject/abi" "^5.0.1" - ethers "^5.0.1" - -"@ethereum-waffle/provider@^3.2.1": - version "3.2.1" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/provider/-/provider-3.2.1.tgz#d84c0603936f09afa69ecb671d56f527e9818e71" - integrity sha512-doG18hThqldsYcZIIO0YoiwV+ERx0dCVY6bkg4FKZtoymNelf15zNycb881c6QD9RnLuz6A2Jp9lmnrAD+IvYQ== - dependencies: - "@ethereum-waffle/ens" "^3.2.1" - ethers "^5.0.1" - ganache-core "^2.10.2" - patch-package "^6.2.2" - postinstall-postinstall "^2.1.0" - -"@ethereumjs/block@^3.2.0", "@ethereumjs/block@^3.2.1": - version "3.2.1" - resolved "https://registry.yarnpkg.com/@ethereumjs/block/-/block-3.2.1.tgz#c24c345e6dd6299efa4bed40979280b7dda96d3a" - integrity sha512-FCxo5KwwULne2A2Yuae4iaGGqSsRjwzXOlDhGalOFiBbLfP3hE04RHaHGw4c8vh1PfOrLauwi0dQNUBkOG3zIA== - dependencies: - "@ethereumjs/common" "^2.2.0" - "@ethereumjs/tx" "^3.1.3" - ethereumjs-util "^7.0.10" - merkle-patricia-tree "^4.1.0" - -"@ethereumjs/blockchain@^5.2.1": - version "5.2.1" - resolved "https://registry.yarnpkg.com/@ethereumjs/blockchain/-/blockchain-5.2.1.tgz#83ed83647667265f1666f111caf065ef9d1e82b5" - integrity sha512-+hshP2qSOOFsiYvZCbaDQFG7jYTWafE8sfBi+pAsdhAHfP7BN7VLyob7qoQISgwS1s7NTR4c4+2t/woU9ahItw== - dependencies: - "@ethereumjs/block" "^3.2.0" - "@ethereumjs/common" "^2.2.0" - "@ethereumjs/ethash" "^1.0.0" - debug "^2.2.0" - ethereumjs-util "^7.0.9" - level-mem "^5.0.1" - lru-cache "^5.1.1" - rlp "^2.2.4" - semaphore-async-await "^1.5.1" - -"@ethereumjs/common@^2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.2.0.tgz#850a3e3e594ee707ad8d44a11e8152fb62450535" - integrity sha512-PyQiTG00MJtBRkJmv46ChZL8u2XWxNBeAthznAUIUiefxPAXjbkuiCZOuncgJS34/XkMbNc9zMt/PlgKRBElig== - dependencies: - crc-32 "^1.2.0" - ethereumjs-util "^7.0.9" - -"@ethereumjs/ethash@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@ethereumjs/ethash/-/ethash-1.0.0.tgz#4e77f85b37be1ade5393e8719bdabac3e796ddaa" - integrity sha512-iIqnGG6NMKesyOxv2YctB2guOVX18qMAWlj3QlZyrc+GqfzLqoihti+cVNQnyNxr7eYuPdqwLQOFuPe6g/uKjw== - dependencies: - "@types/levelup" "^4.3.0" - buffer-xor "^2.0.1" - ethereumjs-util "^7.0.7" - miller-rabin "^4.0.0" - -"@ethereumjs/tx@^3.1.3": - version "3.1.3" - resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.1.3.tgz#0e4b0ccec2f12b1f0bbbb0e7542dd79d9ec25d87" - integrity sha512-DJBu6cbwYtiPTFeCUR8DF5p+PF0jxs+0rALJZiEcTz2tiRPIEkM72GEbrkGuqzENLCzBrJHT43O0DxSYTqeo+g== - dependencies: - "@ethereumjs/common" "^2.2.0" - ethereumjs-util "^7.0.10" - -"@ethereumjs/vm@^5.3.2": - version "5.3.2" - resolved "https://registry.yarnpkg.com/@ethereumjs/vm/-/vm-5.3.2.tgz#b4d83a3d50a7ad22d6d412cc21bbde221b3e2871" - integrity sha512-QmCUQrW6xbhgEbQh9njue4kAJdM056C+ytBFUTF/kDYa3kNDm4Qxp9HUyTlt1OCSXvDhws0qqlh8+q+pmXpN7g== - dependencies: - "@ethereumjs/block" "^3.2.1" - "@ethereumjs/blockchain" "^5.2.1" - "@ethereumjs/common" "^2.2.0" - "@ethereumjs/tx" "^3.1.3" - async-eventemitter "^0.2.4" - core-js-pure "^3.0.1" - debug "^2.2.0" - ethereumjs-util "^7.0.10" - functional-red-black-tree "^1.0.1" - mcl-wasm "^0.7.1" - merkle-patricia-tree "^4.1.0" - rustbn.js "~0.2.0" - util.promisify "^1.0.1" - -"@ethersproject/abi@5.0.0-beta.153": - version "5.0.0-beta.153" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.0.0-beta.153.tgz#43a37172b33794e4562999f6e2d555b7599a8eee" - integrity sha512-aXweZ1Z7vMNzJdLpR1CZUAIgnwjrZeUSvN9syCwlBaEBUFJmFY+HHnfuTI5vIhVs/mRkfJVrbEyl51JZQqyjAg== - dependencies: - "@ethersproject/address" ">=5.0.0-beta.128" - "@ethersproject/bignumber" ">=5.0.0-beta.130" - "@ethersproject/bytes" ">=5.0.0-beta.129" - "@ethersproject/constants" ">=5.0.0-beta.128" - "@ethersproject/hash" ">=5.0.0-beta.128" - "@ethersproject/keccak256" ">=5.0.0-beta.127" - "@ethersproject/logger" ">=5.0.0-beta.129" - "@ethersproject/properties" ">=5.0.0-beta.131" - "@ethersproject/strings" ">=5.0.0-beta.130" - -"@ethersproject/abi@5.0.9", "@ethersproject/abi@^5.0.1", "@ethersproject/abi@^5.0.5": - version "5.0.9" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.0.9.tgz#738c1c557e56d8f395a5a27caef9b0449bc85a10" - integrity sha512-ily2OufA2DTrxkiHQw5GqbkMSnNKuwZBqKsajtT0ERhZy1r9w2CpW1bmtRMIGzaqQxCdn/GEoFogexk72cBBZQ== - 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" - -"@ethersproject/abi@^5.1.2": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.5.0.tgz#fb52820e22e50b854ff15ce1647cc508d6660613" - integrity sha512-loW7I4AohP5KycATvc0MgujU6JyCHPqHdeoo9z3Nr9xEiNioxa65ccdm1+fsoJhkuhdRtfcL8cfyGamz2AxZ5w== - 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" - -"@ethersproject/abstract-provider@5.0.7", "@ethersproject/abstract-provider@^5.0.4": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.0.7.tgz#04ee3bfe43323384e7fecf6c774975b8dec4bdc9" - integrity sha512-NF16JGn6M0zZP5ZS8KtDL2Rh7yHxZbUjBIHLNHMm/0X0BephhjUWy8jqs/Zks6kDJRzNthgmPVy41Ec0RYWPYA== - dependencies: - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/networks" "^5.0.3" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/transactions" "^5.0.5" - "@ethersproject/web" "^5.0.6" - -"@ethersproject/abstract-provider@^5.5.0": - version "5.5.1" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.5.1.tgz#2f1f6e8a3ab7d378d8ad0b5718460f85649710c5" - integrity sha512-m+MA/ful6eKbxpr99xUYeRvLkfnlqzrF8SZ46d/xFB1A7ZVknYc/sXJG0RcufF52Qn2jeFj1hhcoQ7IXjNKUqg== - 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" - -"@ethersproject/abstract-signer@5.0.9", "@ethersproject/abstract-signer@^5.0.4", "@ethersproject/abstract-signer@^5.0.6": - version "5.0.9" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.0.9.tgz#238ddc06031aeb9dfceee2add965292d7dd1acbf" - integrity sha512-CM5UNmXQaA03MyYARFDDRjHWBxujO41tVle7glf5kHcQsDDULgqSVpkliLJMtPzZjOKFeCVZBHybTZDEZg5zzg== - dependencies: - "@ethersproject/abstract-provider" "^5.0.4" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - -"@ethersproject/abstract-signer@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.5.0.tgz#590ff6693370c60ae376bf1c7ada59eb2a8dd08d" - integrity sha512-lj//7r250MXVLKI7sVarXAbZXbv9P50lgmJQGr2/is82EwEb8r7HrxsmMqAjTsztMYy7ohrIhGMIml+Gx4D3mA== - 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" - -"@ethersproject/address@5.0.8", "@ethersproject/address@>=5.0.0-beta.128", "@ethersproject/address@^5.0.4", "@ethersproject/address@^5.0.5": - version "5.0.8" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.8.tgz#0c551659144a5a7643c6bea337149d410825298f" - integrity sha512-V87DHiZMZR6hmFYmoGaHex0D53UEbZpW75uj8AqPbjYUmi65RB4N2LPRcJXuWuN2R0Y2CxkvW6ArijWychr5FA== - dependencies: - "@ethersproject/bignumber" "^5.0.10" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/rlp" "^5.0.3" - -"@ethersproject/address@^5.0.2": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.1.0.tgz#3854fd7ebcb6af7597de66f847c3345dae735b58" - integrity sha512-rfWQR12eHn2cpstCFS4RF7oGjfbkZb0oqep+BfrT+gWEGWG2IowJvIsacPOvzyS1jhNF4MQ4BS59B04Mbovteg== - dependencies: - "@ethersproject/bignumber" "^5.1.0" - "@ethersproject/bytes" "^5.1.0" - "@ethersproject/keccak256" "^5.1.0" - "@ethersproject/logger" "^5.1.0" - "@ethersproject/rlp" "^5.1.0" - -"@ethersproject/address@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.5.0.tgz#bcc6f576a553f21f3dd7ba17248f81b473c9c78f" - integrity sha512-l4Nj0eWlTUh6ro5IbPTgbpT4wRbdH5l8CQf7icF7sb/SI3Nhd9Y9HzhonTSTi6CefI0necIw7LJqQPopPLZyWw== - 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" - -"@ethersproject/base64@5.0.6", "@ethersproject/base64@^5.0.3": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.0.6.tgz#26311ebf29ea3d0b9c300ccf3e1fdc44b7481516" - integrity sha512-HwrGn8YMiUf7bcdVvB4NJ+eWT0BtEFpDtrYxVXEbR7p/XBSJjwiR7DEggIiRvxbualMKg+EZijQWJ3az2li0uw== - dependencies: - "@ethersproject/bytes" "^5.0.4" - -"@ethersproject/base64@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.5.0.tgz#881e8544e47ed976930836986e5eb8fab259c090" - integrity sha512-tdayUKhU1ljrlHzEWbStXazDpsx4eg1dBXUSI6+mHlYklOXoXF6lZvw8tnD6oVaWfnMxAgRSKROg3cVKtCcppA== - dependencies: - "@ethersproject/bytes" "^5.5.0" - -"@ethersproject/basex@5.0.6", "@ethersproject/basex@^5.0.3": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.0.6.tgz#ab95c32e48288a3d868726463506641cb1e9fb6b" - integrity sha512-Y/8dowRxBF3bsKkqEp7XN4kcFFQ0o5xxP1YyopfqkXejaOEGiD7ToQdQ0pIZpAJ5GreW56oFOTDDSO6ZcUCNYg== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/properties" "^5.0.3" - -"@ethersproject/bignumber@5.0.12", "@ethersproject/bignumber@>=5.0.0-beta.130", "@ethersproject/bignumber@^5.0.10", "@ethersproject/bignumber@^5.0.7", "@ethersproject/bignumber@^5.0.8": - version "5.0.12" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.0.12.tgz#fe4a78667d7cb01790f75131147e82d6ea7e7cba" - integrity sha512-mbFZjwthx6vFlHG9owXP/C5QkNvsA+xHpDCkPPPdG2n1dS9AmZAL5DI0InNLid60rQWL3MXpEl19tFmtL7Q9jw== - dependencies: - "@ethersproject/bytes" "^5.0.8" - "@ethersproject/logger" "^5.0.5" - bn.js "^4.4.0" - -"@ethersproject/bignumber@^5.1.0": - version "5.1.1" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.1.1.tgz#84812695253ccbc639117f7ac49ee1529b68e637" - integrity sha512-AVz5iqz7+70RIqoQTznsdJ6DOVBYciNlvO+AlQmPTB6ofCvoihI9bQdr6wljsX+d5W7Yc4nyvQvP4JMzg0Agig== - dependencies: - "@ethersproject/bytes" "^5.1.0" - "@ethersproject/logger" "^5.1.0" - bn.js "^4.4.0" - -"@ethersproject/bignumber@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.5.0.tgz#875b143f04a216f4f8b96245bde942d42d279527" - integrity sha512-6Xytlwvy6Rn3U3gKEc1vP7nR92frHkv6wtVr95LFR3jREXiCPzdWxKQ1cx4JGQBXxcguAwjA8murlYN2TSiEbg== - dependencies: - "@ethersproject/bytes" "^5.5.0" - "@ethersproject/logger" "^5.5.0" - bn.js "^4.11.9" - -"@ethersproject/bytes@5.0.8", "@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.0.4", "@ethersproject/bytes@^5.0.8": - version "5.0.8" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.0.8.tgz#cf1246a6a386086e590063a4602b1ffb6cc43db1" - integrity sha512-O+sJNVGzzuy51g+EMK8BegomqNIg+C2RO6vOt0XP6ac4o4saiq69FnjlsrNslaiMFVO7qcEHBsWJ9hx1tj1lMw== - dependencies: - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/bytes@^5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.1.0.tgz#55dfa9c4c21df1b1b538be3accb50fb76d5facfd" - integrity sha512-sGTxb+LVjFxJcJeUswAIK6ncgOrh3D8c192iEJd7mLr95V6du119rRfYT/b87WPkZ5I3gRBUYIYXtdgCWACe8g== - dependencies: - "@ethersproject/logger" "^5.1.0" - -"@ethersproject/bytes@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.5.0.tgz#cb11c526de657e7b45d2e0f0246fb3b9d29a601c" - integrity sha512-ABvc7BHWhZU9PNM/tANm/Qx4ostPGadAuQzWTr3doklZOhDlmcBqclrQe/ZXUIj3K8wC28oYeuRa+A37tX9kog== - dependencies: - "@ethersproject/logger" "^5.5.0" - -"@ethersproject/constants@5.0.7", "@ethersproject/constants@>=5.0.0-beta.128", "@ethersproject/constants@^5.0.4": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.0.7.tgz#44ff979e5781b17c8c6901266896c3ee745f4e7e" - integrity sha512-cbQK1UpE4hamB52Eg6DLhJoXeQ1plSzekh5Ujir1xdREdwdsZPPXKczkrWqBBR0KyywJZHN/o/hj0w8j7scSGg== - dependencies: - "@ethersproject/bignumber" "^5.0.7" - -"@ethersproject/constants@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.5.0.tgz#d2a2cd7d94bd1d58377d1d66c4f53c9be4d0a45e" - integrity sha512-2MsRRVChkvMWR+GyMGY4N1sAX9Mt3J9KykCsgUFd/1mwS0UH1qw+Bv9k1UJb3X3YJYFco9H20pjSlOIfCG5HYQ== - dependencies: - "@ethersproject/bignumber" "^5.5.0" - -"@ethersproject/contracts@5.0.8": - version "5.0.8" - resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.0.8.tgz#71d3ba16853a1555be2e161a6741df186f81c73b" - integrity sha512-PecBL4vnsrpuks2lzzkRsOts8csJy338HNDKDIivbFmx92BVzh3ohOOv3XsoYPSXIHQvobF959W+aSk3RCZL/g== - dependencies: - "@ethersproject/abi" "^5.0.5" - "@ethersproject/abstract-provider" "^5.0.4" - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/address" "^5.0.4" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - -"@ethersproject/hash@5.0.9", "@ethersproject/hash@>=5.0.0-beta.128", "@ethersproject/hash@^5.0.4": - version "5.0.9" - resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.0.9.tgz#81252a848185b584aa600db4a1a68cad9229a4d4" - integrity sha512-e8/i2ZDeGSgCxXT0vocL54+pMbw5oX5fNjb2E3bAIvdkh5kH29M7zz1jHu1QDZnptIuvCZepIbhUH8lxKE2/SQ== - dependencies: - "@ethersproject/abstract-signer" "^5.0.6" - "@ethersproject/address" "^5.0.5" - "@ethersproject/bignumber" "^5.0.8" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.4" - "@ethersproject/strings" "^5.0.4" - -"@ethersproject/hash@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.5.0.tgz#7cee76d08f88d1873574c849e0207dcb32380cc9" - integrity sha512-dnGVpK1WtBjmnp3mUT0PlU2MpapnwWI0PibldQEq1408tQBAbZpPidkWoVVuNMOl/lISO3+4hXZWCL3YV7qzfg== - 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" - -"@ethersproject/hdnode@5.0.7", "@ethersproject/hdnode@^5.0.4": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.0.7.tgz#c7bce94a337ea65e37c46bab09a83e1c1a555d99" - integrity sha512-89tphqlji4y/LNE1cSaMQ3hrBtJ4lO1qWGi2hn54LiHym85DTw+zAKbA8QgmdSdJDLGR/kc9VHaIPQ+vZQ2LkQ== - dependencies: - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/basex" "^5.0.3" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/pbkdf2" "^5.0.3" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/sha2" "^5.0.3" - "@ethersproject/signing-key" "^5.0.4" - "@ethersproject/strings" "^5.0.4" - "@ethersproject/transactions" "^5.0.5" - "@ethersproject/wordlists" "^5.0.4" - -"@ethersproject/json-wallets@5.0.9", "@ethersproject/json-wallets@^5.0.6": - version "5.0.9" - resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.0.9.tgz#2e1708c2854c4ab764e35920bd1f44c948b95434" - integrity sha512-EWuFvJd8nu90dkmJwmJddxOYCvFvMkKBsZi8rxTme2XEZsHKOFnybVkoL23u7ZtApuEfTKmVcR2PTwgZwqDsKw== - dependencies: - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/address" "^5.0.4" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/hdnode" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/pbkdf2" "^5.0.3" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/random" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - "@ethersproject/transactions" "^5.0.5" - aes-js "3.0.0" - scrypt-js "3.0.1" - -"@ethersproject/keccak256@5.0.6", "@ethersproject/keccak256@>=5.0.0-beta.127", "@ethersproject/keccak256@^5.0.3": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.6.tgz#5b5ba715ef1be86efde5c271f896fa0daf0e1efe" - integrity sha512-eJ4Id/i2rwrf5JXEA7a12bG1phuxjj47mPZgDUbttuNBodhSuZF2nEO5QdpaRjmlphQ8Kt9PNqY/z7lhtJptZg== - dependencies: - "@ethersproject/bytes" "^5.0.4" - js-sha3 "0.5.7" - -"@ethersproject/keccak256@^5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.1.0.tgz#fdcd88fb13bfef4271b225cdd8dec4d315c8e60e" - integrity sha512-vrTB1W6AEYoadww5c9UyVJ2YcSiyIUTNDRccZIgwTmFFoSHwBtcvG1hqy9RzJ1T0bMdATbM9Hfx2mJ6H0i7Hig== - dependencies: - "@ethersproject/bytes" "^5.1.0" - js-sha3 "0.5.7" - -"@ethersproject/keccak256@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.5.0.tgz#e4b1f9d7701da87c564ffe336f86dcee82983492" - integrity sha512-5VoFCTjo2rYbBe1l2f4mccaRFN/4VQEYFwwn04aJV2h7qf4ZvI2wFxUE1XOX+snbwCLRzIeikOqtAoPwMza9kg== - dependencies: - "@ethersproject/bytes" "^5.5.0" - js-sha3 "0.8.0" - -"@ethersproject/logger@5.0.8", "@ethersproject/logger@>=5.0.0-beta.129", "@ethersproject/logger@^5.0.5": - version "5.0.8" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.8.tgz#135c1903d35c878265f3cbf2b287042c4c20d5d4" - integrity sha512-SkJCTaVTnaZ3/ieLF5pVftxGEFX56pTH+f2Slrpv7cU0TNpUZNib84QQdukd++sWUp/S7j5t5NW+WegbXd4U/A== - -"@ethersproject/logger@^5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.1.0.tgz#4cdeeefac029373349d5818f39c31b82cc6d9bbf" - integrity sha512-wtUaD1lBX10HBXjjKV9VHCBnTdUaKQnQ2XSET1ezglqLdPdllNOIlLfhyCRqXm5xwcjExVI5ETokOYfjPtaAlw== - -"@ethersproject/logger@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.5.0.tgz#0c2caebeff98e10aefa5aef27d7441c7fd18cf5d" - integrity sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg== - -"@ethersproject/networks@5.0.6", "@ethersproject/networks@^5.0.3": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.0.6.tgz#4d6586bbebfde1c027504ebf6dfb783b29c3803a" - integrity sha512-2Cg1N5109zzFOBfkyuPj+FfF7ioqAsRffmybJ2lrsiB5skphIAE72XNSCs4fqktlf+rwSh/5o/UXRjXxvSktZw== - dependencies: - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/networks@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.5.0.tgz#babec47cab892c51f8dd652ce7f2e3e14283981a" - integrity sha512-KWfP3xOnJeF89Uf/FCJdV1a2aDJe5XTN2N52p4fcQ34QhDqQFkgQKZ39VGtiqUgHcLI8DfT0l9azC3KFTunqtA== - dependencies: - "@ethersproject/logger" "^5.5.0" - -"@ethersproject/pbkdf2@5.0.6", "@ethersproject/pbkdf2@^5.0.3": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.0.6.tgz#105dbfb08cd5fcf33869b42bfdc35a3ebd978cbd" - integrity sha512-CUYciSxR/AaCoKMJk3WUW+BDhR41G3C+O9lOeZ4bR1wDhLKL2Z8p0ciF5XDEiVbmI4CToW6boVKybeVMdngRrg== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/sha2" "^5.0.3" - -"@ethersproject/properties@5.0.6", "@ethersproject/properties@>=5.0.0-beta.131", "@ethersproject/properties@^5.0.3", "@ethersproject/properties@^5.0.4": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.6.tgz#44d82aaa294816fd63333e7def42426cf0e87b3b" - integrity sha512-a9DUMizYhJ0TbtuDkO9iYlb2CDlpSKqGPDr+amvlZhRspQ6jbl5Eq8jfu4SCcGlcfaTbguJmqGnyOGn1EFt6xA== - dependencies: - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/properties@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.5.0.tgz#61f00f2bb83376d2071baab02245f92070c59995" - integrity sha512-l3zRQg3JkD8EL3CPjNK5g7kMx4qSwiR60/uk5IVjd3oq1MZR5qUg40CNOoEJoX5wc3DyY5bt9EbMk86C7x0DNA== - dependencies: - "@ethersproject/logger" "^5.5.0" - -"@ethersproject/providers@5.0.17": - version "5.0.17" - resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.0.17.tgz#f380e7831149e24e7a1c6c9b5fb1d6dfc729d024" - integrity sha512-bJnvs5X7ttU5x2ekGJYG7R3Z+spZawLFfR0IDsbaMDLiCwZOyrgk+VTBU7amSFLT0WUhWFv8WwSUB+AryCQG1Q== - dependencies: - "@ethersproject/abstract-provider" "^5.0.4" - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/address" "^5.0.4" - "@ethersproject/basex" "^5.0.3" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/hash" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/networks" "^5.0.3" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/random" "^5.0.3" - "@ethersproject/rlp" "^5.0.3" - "@ethersproject/sha2" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - "@ethersproject/transactions" "^5.0.5" - "@ethersproject/web" "^5.0.6" - bech32 "1.1.4" - ws "7.2.3" - -"@ethersproject/random@5.0.6", "@ethersproject/random@^5.0.3": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.0.6.tgz#9be80a1065f2b8e6f321dccb3ebeb4886cac9ea4" - integrity sha512-8nsVNaZvZ9OD5NXfzE4mmz8IH/1DYJbAR95xpRxZkIuNmfn6QlMp49ccJYZWGhs6m0Zj2+FXjx3pzXfYlo9/dA== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/rlp@5.0.6", "@ethersproject/rlp@^5.0.3": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.6.tgz#29f9097348a3c330811997433b7df89ab51cd644" - integrity sha512-M223MTaydfmQSsvqAl0FJZDYFlSqt6cgbhnssLDwqCKYegAHE16vrFyo+eiOapYlt32XAIJm0BXlqSunULzZuQ== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/rlp@^5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.1.0.tgz#700f4f071c27fa298d3c1d637485fefe919dd084" - integrity sha512-vDTyHIwNPrecy55gKGZ47eJZhBm8LLBxihzi5ou+zrSvYTpkSTWRcKUlXFDFQVwfWB+P5PGyERAdiDEI76clxw== - dependencies: - "@ethersproject/bytes" "^5.1.0" - "@ethersproject/logger" "^5.1.0" - -"@ethersproject/rlp@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.5.0.tgz#530f4f608f9ca9d4f89c24ab95db58ab56ab99a0" - integrity sha512-hLv8XaQ8PTI9g2RHoQGf/WSxBfTB/NudRacbzdxmst5VHAqd1sMibWG7SENzT5Dj3yZ3kJYx+WiRYEcQTAkcYA== - dependencies: - "@ethersproject/bytes" "^5.5.0" - "@ethersproject/logger" "^5.5.0" - -"@ethersproject/sha2@5.0.6", "@ethersproject/sha2@^5.0.3": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.0.6.tgz#175116dc10b866a0a381f6316d094bcc510bee3c" - integrity sha512-30gypDLkfkP5gE3llqi0jEuRV8m4/nvzeqmqMxiihZ7veFQHqDaGpyFeHzFim+qGeH9fq0lgYjavLvwW69+Fkw== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - hash.js "1.1.3" - -"@ethersproject/signing-key@5.0.7", "@ethersproject/signing-key@^5.0.4": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.0.7.tgz#d03bfc5f565efb962bafebf8e6965e70d1c46d31" - integrity sha512-JYndnhFPKH0daPcIjyhi+GMcw3srIHkQ40hGRe6DA0CdGrpMfgyfSYDQ2D8HL2lgR+Xm4SHfEB0qba6+sCyrvg== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - elliptic "6.5.3" - -"@ethersproject/signing-key@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.5.0.tgz#2aa37169ce7e01e3e80f2c14325f624c29cedbe0" - integrity sha512-5VmseH7qjtNmDdZBswavhotYbWB0bOwKIlOTSlX14rKn5c11QmJwGt4GHeo7NrL/Ycl7uo9AHvEqs5xZgFBTng== - 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" - -"@ethersproject/solidity@5.0.7": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.0.7.tgz#72a3455f47a454db2dcf363992d42e9045dc7fce" - integrity sha512-dUevKUZ06p/VMLP/+cz4QUV+lA17NixucDJfm0ioWF0B3R0Lf+6wqwPchcqiAXlxkNFGIax7WNLgGMh4CkQ8iw== - dependencies: - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/sha2" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - -"@ethersproject/strings@5.0.7", "@ethersproject/strings@>=5.0.0-beta.130", "@ethersproject/strings@^5.0.4": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.7.tgz#8dc68f794c9e2901f3b75e53b2afbcb6b6c15037" - integrity sha512-a+6T80LvmXGMOOWQTZHtGGQEg1z4v8rm8oX70KNs55YtPXI/5J3LBbVf5pyqCKSlmiBw5IaepPvs5XGalRUSZQ== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/strings@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.5.0.tgz#e6784d00ec6c57710755699003bc747e98c5d549" - integrity sha512-9fy3TtF5LrX/wTrBaT8FGE6TDJyVjOvXynXJz5MT5azq+E6D92zuKNx7i29sWW2FjVOaWjAsiZ1ZWznuduTIIQ== - dependencies: - "@ethersproject/bytes" "^5.5.0" - "@ethersproject/constants" "^5.5.0" - "@ethersproject/logger" "^5.5.0" - -"@ethersproject/transactions@5.0.8", "@ethersproject/transactions@^5.0.0-beta.135", "@ethersproject/transactions@^5.0.5": - version "5.0.8" - resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.0.8.tgz#3b4d7041e13b957a9c4f131e0aea9dae7b6f5a23" - integrity sha512-i7NtOXVzUe+YSU6QufzlRrI2WzHaTmULAKHJv4duIZMLqzehCBXGA9lTpFgFdqGYcQJ7vOtNFC2BB2mSjmuXqg== - dependencies: - "@ethersproject/address" "^5.0.4" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/rlp" "^5.0.3" - "@ethersproject/signing-key" "^5.0.4" - -"@ethersproject/transactions@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.5.0.tgz#7e9bf72e97bcdf69db34fe0d59e2f4203c7a2908" - integrity sha512-9RZYSKX26KfzEd/1eqvv8pLauCKzDTub0Ko4LfIgaERvRuwyaNV78mJs7cpIgZaDl6RJui4o49lHwwCM0526zA== - 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" - -"@ethersproject/units@5.0.8": - version "5.0.8" - resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.0.8.tgz#563325b20fe1eceff7b61857711d5e2b3f38fd09" - integrity sha512-3O4MaNHFs05vC5v2ZGqVFVWtO1WyqFejO78M7Qh16njo282aoMlENtVI6cn2B36zOLFXRvYt2pYx6xCG53qKzg== - dependencies: - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/wallet@5.0.9": - version "5.0.9" - resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.0.9.tgz#976c7d950489c40308d676869d24e59ab7b82ad1" - integrity sha512-GfpQF56PO/945SJq7Wdg5F5U6wkxaDgkAzcgGbCW6Joz8oW8MzKItkvYCzMh+j/8gJMzFncsuqX4zg2gq3J6nQ== - dependencies: - "@ethersproject/abstract-provider" "^5.0.4" - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/address" "^5.0.4" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/hash" "^5.0.4" - "@ethersproject/hdnode" "^5.0.4" - "@ethersproject/json-wallets" "^5.0.6" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/random" "^5.0.3" - "@ethersproject/signing-key" "^5.0.4" - "@ethersproject/transactions" "^5.0.5" - "@ethersproject/wordlists" "^5.0.4" - -"@ethersproject/web@5.0.11", "@ethersproject/web@^5.0.6": - version "5.0.11" - resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.0.11.tgz#d47da612b958b4439e415782a53c8f8461522d68" - integrity sha512-x03ihbPoN1S8Gsh9WSwxkYxUIumLi02ZEKJku1C43sxBfe+mdprWyvujzYlpuoRNfWRgNhdRDKMP8JbG6MwNGA== - dependencies: - "@ethersproject/base64" "^5.0.3" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - -"@ethersproject/web@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.5.0.tgz#0e5bb21a2b58fb4960a705bfc6522a6acf461e28" - integrity sha512-BEgY0eL5oH4mAo37TNYVrFeHsIXLRxggCRG/ksRIxI2X5uj5IsjGmcNiRN/VirQOlBxcUhCgHhaDLG4m6XAVoA== - 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" - -"@ethersproject/wordlists@5.0.7", "@ethersproject/wordlists@^5.0.4": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.0.7.tgz#4e5ad38cfbef746b196a3290c0d41696eb7ab468" - integrity sha512-ZjQtYxm41FmHfYgpkdQG++EDcBPQWv9O6FfP6NndYRVaXaQZh6eq3sy7HQP8zCZ8dznKgy6ZyKECS8qdvnGHwA== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/hash" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - -"@jest/console@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-26.6.2.tgz#4e04bc464014358b03ab4937805ee36a0aeb98f2" - integrity sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g== - dependencies: - "@jest/types" "^26.6.2" - "@types/node" "*" - chalk "^4.0.0" - jest-message-util "^26.6.2" - jest-util "^26.6.2" - slash "^3.0.0" - -"@jest/test-result@^26.5.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-26.6.2.tgz#55da58b62df134576cc95476efa5f7949e3f5f18" - integrity sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ== - dependencies: - "@jest/console" "^26.6.2" - "@jest/types" "^26.6.2" - "@types/istanbul-lib-coverage" "^2.0.0" - collect-v8-coverage "^1.0.0" - -"@jest/types@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" - integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^15.0.0" - chalk "^4.0.0" - -"@nomiclabs/hardhat-ethers@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.2.tgz#c472abcba0c5185aaa4ad4070146e95213c68511" - integrity sha512-6quxWe8wwS4X5v3Au8q1jOvXYEPkS1Fh+cME5u6AwNdnI4uERvPlVjlgRWzpnb+Rrt1l/cEqiNRH9GlsBMSDQg== - -"@nomiclabs/hardhat-etherscan@^2.1.8": - version "2.1.8" - resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-2.1.8.tgz#e206275e96962cd15e5ba9148b44388bc922d8c2" - 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" - -"@nomiclabs/hardhat-waffle@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-waffle/-/hardhat-waffle-2.0.1.tgz#5d43654fba780720c5033dea240fe14f70ef4bd2" - integrity sha512-2YR2V5zTiztSH9n8BYWgtv3Q+EL0N5Ltm1PAr5z20uAY4SkkfylJ98CIqt18XFvxTD5x4K2wKBzddjV9ViDAZQ== - dependencies: - "@types/sinon-chai" "^3.2.3" - "@types/web3" "1.0.19" - -"@resolver-engine/core@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@resolver-engine/core/-/core-0.3.3.tgz#590f77d85d45bc7ecc4e06c654f41345db6ca967" - integrity sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ== - dependencies: - debug "^3.1.0" - is-url "^1.2.4" - request "^2.85.0" - -"@resolver-engine/fs@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@resolver-engine/fs/-/fs-0.3.3.tgz#fbf83fa0c4f60154a82c817d2fe3f3b0c049a973" - integrity sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ== - dependencies: - "@resolver-engine/core" "^0.3.3" - debug "^3.1.0" - -"@resolver-engine/imports-fs@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@resolver-engine/imports-fs/-/imports-fs-0.3.3.tgz#4085db4b8d3c03feb7a425fbfcf5325c0d1e6c1b" - integrity sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA== - dependencies: - "@resolver-engine/fs" "^0.3.3" - "@resolver-engine/imports" "^0.3.3" - debug "^3.1.0" - -"@resolver-engine/imports@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@resolver-engine/imports/-/imports-0.3.3.tgz#badfb513bb3ff3c1ee9fd56073e3144245588bcc" - integrity sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q== - dependencies: - "@resolver-engine/core" "^0.3.3" - debug "^3.1.0" - hosted-git-info "^2.6.0" - path-browserify "^1.0.0" - url "^0.11.0" - -"@sentry/core@5.29.2": - version "5.29.2" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.29.2.tgz#9e05fe197234161d57aabaf52fab336a7c520d81" - integrity sha512-7WYkoxB5IdlNEbwOwqSU64erUKH4laavPsM0/yQ+jojM76ErxlgEF0u//p5WaLPRzh3iDSt6BH+9TL45oNZeZw== - dependencies: - "@sentry/hub" "5.29.2" - "@sentry/minimal" "5.29.2" - "@sentry/types" "5.29.2" - "@sentry/utils" "5.29.2" - tslib "^1.9.3" - -"@sentry/hub@5.29.2": - version "5.29.2" - resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.29.2.tgz#208f10fe6674695575ad74182a1151f71d6df00a" - integrity sha512-LaAIo2hwUk9ykeh9RF0cwLy6IRw+DjEee8l1HfEaDFUM6TPGlNNGObMJNXb9/95jzWp7jWwOpQjoIE3jepdQJQ== - dependencies: - "@sentry/types" "5.29.2" - "@sentry/utils" "5.29.2" - tslib "^1.9.3" - -"@sentry/minimal@5.29.2": - version "5.29.2" - resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.29.2.tgz#420bebac8d03d30980fdb05c72d7b253d8aa541b" - integrity sha512-0aINSm8fGA1KyM7PavOBe1GDZDxrvnKt+oFnU0L+bTcw8Lr+of+v6Kwd97rkLRNOLw621xP076dL/7LSIzMuhw== - dependencies: - "@sentry/hub" "5.29.2" - "@sentry/types" "5.29.2" - tslib "^1.9.3" - -"@sentry/node@^5.18.1": - version "5.29.2" - resolved "https://registry.yarnpkg.com/@sentry/node/-/node-5.29.2.tgz#f0f0b4b2be63c9ddd702729fab998cead271dff1" - integrity sha512-98m1ZejmJgA+eiz6jEFyYYfp6kJZQnx6d6KrJDMxGfss4YTmmJY57bE4xStnjjk7WINDGzlCiHuk+wJFMBjuoA== - dependencies: - "@sentry/core" "5.29.2" - "@sentry/hub" "5.29.2" - "@sentry/tracing" "5.29.2" - "@sentry/types" "5.29.2" - "@sentry/utils" "5.29.2" - cookie "^0.4.1" - https-proxy-agent "^5.0.0" - lru_map "^0.3.3" - tslib "^1.9.3" - -"@sentry/tracing@5.29.2": - version "5.29.2" - resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.29.2.tgz#6012788547d2ab7893799d82c4941bda145dcd47" - integrity sha512-iumYbVRpvoU3BUuIooxibydeaOOjl5ysc+mzsqhRs2NGW/C3uKAsFXdvyNfqt3bxtRQwJEhwJByLP2u3pLThpw== - dependencies: - "@sentry/hub" "5.29.2" - "@sentry/minimal" "5.29.2" - "@sentry/types" "5.29.2" - "@sentry/utils" "5.29.2" - tslib "^1.9.3" - -"@sentry/types@5.29.2": - version "5.29.2" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.29.2.tgz#ac87383df1222c2d9b9f8f9ed7a6b86ea41a098a" - integrity sha512-dM9wgt8wy4WRty75QkqQgrw9FV9F+BOMfmc0iaX13Qos7i6Qs2Q0dxtJ83SoR4YGtW8URaHzlDtWlGs5egBiMA== - -"@sentry/utils@5.29.2": - version "5.29.2" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.29.2.tgz#99a5cdda2ea19d34a41932f138d470adcb3ee673" - integrity sha512-nEwQIDjtFkeE4k6yIk4Ka5XjGRklNLThWLs2xfXlL7uwrYOH2B9UBBOOIRUraBm/g/Xrra3xsam/kRxuiwtXZQ== - dependencies: - "@sentry/types" "5.29.2" - tslib "^1.9.3" - -"@sindresorhus/is@^0.14.0": - version "0.14.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" - integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== - -"@solidity-parser/parser@^0.10.1": - version "0.10.1" - resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.10.1.tgz#d3680d1ebebed21eee67f58a41eb92175204f0c7" - integrity sha512-tHDPCRMEBFDxBz5rioQRoKgOQGa/K2digdfR68cd5vO6IufAqoNt1sfjssQDf2KPqHPftICBQOqlcu0w5/Jisg== - -"@solidity-parser/parser@^0.11.0": - version "0.11.1" - resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.11.1.tgz#fa840af64840c930f24a9c82c08d4a092a068add" - integrity sha512-H8BSBoKE8EubJa0ONqecA2TviT3TnHeC4NpgnAHSUiuhZoQBfPB4L2P9bs8R6AoTW10Endvh3vc+fomVMIDIYQ== - -"@solidity-parser/parser@^0.8.2": - version "0.8.2" - resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.8.2.tgz#a6a5e93ac8dca6884a99a532f133beba59b87b69" - integrity sha512-8LySx3qrNXPgB5JiULfG10O3V7QTxI/TLzSw5hFQhXWSkVxZBAv4rZQ0sYgLEbc8g3L2lmnujj1hKul38Eu5NQ== - -"@szmarczak/http-timer@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" - integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== - dependencies: - defer-to-connect "^1.0.1" - -"@typechain/ethers-v5@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-4.0.0.tgz#2a8be5e108d23f3b8e6354d1618fdc2abcb00b07" - integrity sha512-Rw4WHPIuwTXWcHfmn9ICQISQhmJa6Ug5IjqPYLpsKqlED2L4W2JgQ6S9hYt4IKVmT//1yxIxD+iaa5tSQEEx1A== - -"@types/abstract-leveldown@*": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@types/abstract-leveldown/-/abstract-leveldown-5.0.1.tgz#3c7750d0186b954c7f2d2f6acc8c3c7ba0c3412e" - integrity sha512-wYxU3kp5zItbxKmeRYCEplS2MW7DzyBnxPGj+GJVHZEUZiK/nn5Ei1sUFgURDh+X051+zsGe28iud3oHjrYWQQ== - -"@types/babel__traverse@^7.0.4": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.11.0.tgz#b9a1efa635201ba9bc850323a8793ee2d36c04a0" - integrity sha512-kSjgDMZONiIfSH1Nxcr5JIRMwUetDki63FSQfpTCz8ogF3Ulqm8+mr5f78dUYs6vMiB6gBusQqfQmBvHZj/lwg== - dependencies: - "@babel/types" "^7.3.0" - -"@types/bn.js@*", "@types/bn.js@^4.11.3", "@types/bn.js@^4.11.5": - version "4.11.6" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" - integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== - dependencies: - "@types/node" "*" - -"@types/bn.js@^5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.0.tgz#32c5d271503a12653c62cf4d2b45e6eab8cebc68" - integrity sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA== - dependencies: - "@types/node" "*" - -"@types/chai@*", "@types/chai@^4.2.6": - version "4.2.14" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.14.tgz#44d2dd0b5de6185089375d976b4ec5caf6861193" - integrity sha512-G+ITQPXkwTrslfG5L/BksmbLUA0M1iybEsmCWPqzSxsRRhJZimBKJkoMi8fr/CPygPTj4zO5pJH7I2/cm9M7SQ== - -"@types/graceful-fs@^4.1.2": - version "4.1.4" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.4.tgz#4ff9f641a7c6d1a3508ff88bc3141b152772e753" - integrity sha512-mWA/4zFQhfvOA8zWkXobwJvBD7vzcxgrOQ0J5CH1votGqdq9m7+FwtGaqyCZqC3NyyBkc9z4m+iry4LlqcMWJg== - dependencies: - "@types/node" "*" - -"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762" - integrity sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw== - -"@types/istanbul-lib-report@*": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" - integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== - dependencies: - "@types/istanbul-lib-coverage" "*" - -"@types/istanbul-reports@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz#508b13aa344fa4976234e75dddcc34925737d821" - integrity sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA== - dependencies: - "@types/istanbul-lib-report" "*" - -"@types/levelup@^4.3.0": - version "4.3.1" - resolved "https://registry.yarnpkg.com/@types/levelup/-/levelup-4.3.1.tgz#7a53b9fd510716e11b2065332790fdf5f9b950b9" - integrity sha512-n//PeTpbHLjMLTIgW5B/g06W/6iuTBHuvUka2nFL9APMSVMNe2r4enADfu3CIE9IyV9E+uquf9OEQQqrDeg24A== - dependencies: - "@types/abstract-leveldown" "*" - "@types/node" "*" - -"@types/lru-cache@^5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.0.tgz#57f228f2b80c046b4a1bd5cac031f81f207f4f03" - integrity sha512-RaE0B+14ToE4l6UqdarKPnXwVDuigfFv+5j9Dze/Nqr23yyuqdNvzcZi3xB+3Agvi5R4EOgAksfv3lXX4vBt9w== - -"@types/mkdirp@^0.5.2": - version "0.5.2" - resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-0.5.2.tgz#503aacfe5cc2703d5484326b1b27efa67a339c1f" - integrity sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg== - dependencies: - "@types/node" "*" - -"@types/mocha@^5.2.7": - version "5.2.7" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.7.tgz#315d570ccb56c53452ff8638738df60726d5b6ea" - integrity sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ== - -"@types/node-fetch@^2.5.5": - version "2.5.7" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.7.tgz#20a2afffa882ab04d44ca786449a276f9f6bbf3c" - integrity sha512-o2WVNf5UhWRkxlf6eq+jMZDu7kjgpgJfl4xVNlvryc95O/6F2ld8ztKX+qu+Rjyet93WAWm5LjeX9H5FGkODvw== - dependencies: - "@types/node" "*" - form-data "^3.0.0" - -"@types/node@*": - version "14.14.14" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.14.tgz#f7fd5f3cc8521301119f63910f0fb965c7d761ae" - integrity sha512-UHnOPWVWV1z+VV8k6L1HhG7UbGBgIdghqF3l9Ny9ApPghbjICXkUJSd/b9gOgQfjM1r+37cipdw/HJ3F6ICEnQ== - -"@types/node@^12.12.6": - version "12.19.9" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.9.tgz#990ad687ad8b26ef6dcc34a4f69c33d40c95b679" - integrity sha512-yj0DOaQeUrk3nJ0bd3Y5PeDRJ6W0r+kilosLA+dzF3dola/o9hxhMSg2sFvVcA2UHS5JSOsZp4S0c1OEXc4m1Q== - -"@types/normalize-package-data@^2.4.0": - version "2.4.0" - resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" - integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== - -"@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.0.0", "@types/prettier@^2.1.1": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.1.5.tgz#b6ab3bba29e16b821d84e09ecfaded462b816b00" - integrity sha512-UEyp8LwZ4Dg30kVU2Q3amHHyTn1jEdhCIE59ANed76GaT1Vp76DD3ZWSAxgCrw6wJ0TqeoBpqmfUHiUDPs//HQ== - -"@types/resolve@^0.0.8": - version "0.0.8" - resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194" - integrity sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ== - dependencies: - "@types/node" "*" - -"@types/secp256k1@^4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.1.tgz#fb3aa61a1848ad97d7425ff9dcba784549fca5a4" - integrity sha512-+ZjSA8ELlOp8SlKi0YLB2tz9d5iPNEmOBd+8Rz21wTMdaXQIa9b6TEnD6l5qKOCypE7FSyPyck12qZJxSDNoog== - dependencies: - "@types/node" "*" - -"@types/sinon-chai@^3.2.3": - version "3.2.5" - resolved "https://registry.yarnpkg.com/@types/sinon-chai/-/sinon-chai-3.2.5.tgz#df21ae57b10757da0b26f512145c065f2ad45c48" - integrity sha512-bKQqIpew7mmIGNRlxW6Zli/QVyc3zikpGzCa797B/tRnD9OtHvZ/ts8sYXV+Ilj9u3QRaUEM8xrjgd1gwm1BpQ== - dependencies: - "@types/chai" "*" - "@types/sinon" "*" - -"@types/sinon@*": - version "9.0.10" - resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-9.0.10.tgz#7fb9bcb6794262482859cab66d59132fca18fcf7" - integrity sha512-/faDC0erR06wMdybwI/uR8wEKV/E83T0k4sepIpB7gXuy2gzx2xiOjmztq6a2Y6rIGJ04D+6UU0VBmWy+4HEMA== - dependencies: - "@types/sinonjs__fake-timers" "*" - -"@types/sinonjs__fake-timers@*": - version "6.0.2" - resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.2.tgz#3a84cf5ec3249439015e14049bd3161419bf9eae" - integrity sha512-dIPoZ3g5gcx9zZEszaxLSVTvMReD3xxyyDnQUjA6IYDG9Ba2AV0otMPs+77sG9ojB4Qr2N2Vk5RnKeuA0X/0bg== - -"@types/stack-utils@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff" - integrity sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw== - -"@types/underscore@*": - version "1.10.24" - resolved "https://registry.yarnpkg.com/@types/underscore/-/underscore-1.10.24.tgz#dede004deed3b3f99c4db0bdb9ee21cae25befdd" - integrity sha512-T3NQD8hXNW2sRsSbLNjF/aBo18MyJlbw0lSpQHB/eZZtScPdexN4HSa8cByYwTw9Wy7KuOFr81mlDQcQQaZ79w== - -"@types/web3@1.0.19": - version "1.0.19" - resolved "https://registry.yarnpkg.com/@types/web3/-/web3-1.0.19.tgz#46b85d91d398ded9ab7c85a5dd57cb33ac558924" - integrity sha512-fhZ9DyvDYDwHZUp5/STa9XW2re0E8GxoioYJ4pEUZ13YHpApSagixj7IAdoYH5uAK+UalGq6Ml8LYzmgRA/q+A== - dependencies: - "@types/bn.js" "*" - "@types/underscore" "*" - -"@types/yargs-parser@*": - version "20.2.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.0.tgz#dd3e6699ba3237f0348cd085e4698780204842f9" - integrity sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA== - -"@types/yargs@^15.0.0": - version "15.0.12" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.12.tgz#6234ce3e3e3fa32c5db301a170f96a599c960d74" - integrity sha512-f+fD/fQAo3BCbCDlrUpznF1A5Zp9rB0noS5vnoormHSIPFKL0Z2DcUJ3Gxp5ytH4uLRNxy7AwYUC9exZzqGMAw== - dependencies: - "@types/yargs-parser" "*" - -"@yarnpkg/lockfile@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" - integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== - -abort-controller@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" - integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== - dependencies: - event-target-shim "^5.0.0" - -abstract-leveldown@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-3.0.0.tgz#5cb89f958a44f526779d740d1440e743e0c30a57" - integrity sha512-KUWx9UWGQD12zsmLNj64/pndaz4iJh/Pj7nopgkfDG6RlCcbMZvT6+9l7dchK4idog2Is8VdC/PvNbFuFmalIQ== - dependencies: - xtend "~4.0.0" - -abstract-leveldown@^2.4.1, abstract-leveldown@~2.7.1: - version "2.7.2" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz#87a44d7ebebc341d59665204834c8b7e0932cc93" - integrity sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w== - dependencies: - xtend "~4.0.0" - -abstract-leveldown@^5.0.0, abstract-leveldown@~5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz#f7128e1f86ccabf7d2893077ce5d06d798e386c6" - integrity sha512-5mU5P1gXtsMIXg65/rsYGsi93+MlogXZ9FA8JnwKurHQg64bfXwGYVdVdijNTVNOlAsuIiOwHdvFFD5JqCJQ7A== - dependencies: - xtend "~4.0.0" - -abstract-leveldown@^6.2.1: - version "6.3.0" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz#d25221d1e6612f820c35963ba4bd739928f6026a" - 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" - -abstract-leveldown@~2.6.0: - version "2.6.3" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz#1c5e8c6a5ef965ae8c35dfb3a8770c476b82c4b8" - integrity sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA== - dependencies: - xtend "~4.0.0" - -abstract-leveldown@~6.2.1: - version "6.2.3" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz#036543d87e3710f2528e47040bc3261b77a9a8eb" - 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" - -accepts@~1.3.7: - version "1.3.7" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" - integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== - dependencies: - mime-types "~2.1.24" - negotiator "0.6.2" - -acorn-jsx@^5.0.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" - integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== - -acorn@^6.0.7: - version "6.4.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" - integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== - -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 sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0= - -aes-js@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.2.tgz#db9aabde85d5caabbfc0d4f2a4446960f627146a" - integrity sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ== - -agent-base@6: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -ajv@^6.10.2, ajv@^6.12.3, ajv@^6.6.1, ajv@^6.9.1: - 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" - -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-escapes@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" - integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== - -ansi-escapes@^4.3.0: - version "4.3.1" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61" - integrity sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA== - dependencies: - type-fest "^0.11.0" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - -ansi-regex@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" - integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== - -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= - -ansi-styles@^3.2.0, ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - 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" - -antlr4@4.7.1: - version "4.7.1" - resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.7.1.tgz#69984014f096e9e775f53dd9744bf994d8959773" - integrity sha512-haHyTW7Y9joE5MVs37P2lNYfU2RWBLfcRDD8OWldcdZm5TiCE91B5Xl1oWSwiDUSd4rlExpt2pu1fksYQjRBYQ== - -anymatch@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== - dependencies: - micromatch "^3.1.4" - normalize-path "^2.1.1" - -anymatch@^3.0.3, anymatch@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" - integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== - 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" - -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= - -arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= - -array-back@^1.0.3, array-back@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-1.0.4.tgz#644ba7f095f7ffcf7c43b5f0dc39d3c1f03c063b" - integrity sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs= - dependencies: - typical "^2.6.0" - -array-back@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-2.0.0.tgz#6877471d51ecc9c9bfa6136fb6c7d5fe69748022" - integrity sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw== - dependencies: - typical "^2.6.1" - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= - -asn1.js@^5.2.0: - version "5.4.1" - resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" - integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== - dependencies: - bn.js "^4.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - safer-buffer "^2.1.0" - -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - -assertion-error@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" - integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= - -ast-parents@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/ast-parents/-/ast-parents-0.0.1.tgz#508fd0f05d0c48775d9eccda2e174423261e8dd3" - integrity sha1-UI/Q8F0MSHddnszaLhdEIyYejdM= - -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== - -async-eventemitter@^0.2.2, async-eventemitter@^0.2.4: - version "0.2.4" - resolved "https://registry.yarnpkg.com/async-eventemitter/-/async-eventemitter-0.2.4.tgz#f5e7c8ca7d3e46aab9ec40a292baf686a0bafaca" - integrity sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw== - dependencies: - async "^2.4.0" - -async-limiter@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" - integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== - -async@2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.2.tgz#18330ea7e6e313887f5d2f2a904bac6fe4dd5381" - integrity sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg== - dependencies: - lodash "^4.17.11" - -async@^1.4.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" - integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= - -async@^2.0.1, async@^2.1.2, async@^2.4.0, async@^2.5.0, async@^2.6.1: - version "2.6.3" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" - integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== - dependencies: - lodash "^4.17.14" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -atob@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" - integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== - -babel-code-frame@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" - integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= - dependencies: - chalk "^1.1.3" - esutils "^2.0.2" - js-tokens "^3.0.2" - -babel-core@^6.0.14, babel-core@^6.26.0: - version "6.26.3" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" - integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA== - dependencies: - babel-code-frame "^6.26.0" - babel-generator "^6.26.0" - babel-helpers "^6.24.1" - babel-messages "^6.23.0" - babel-register "^6.26.0" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - convert-source-map "^1.5.1" - debug "^2.6.9" - json5 "^0.5.1" - lodash "^4.17.4" - minimatch "^3.0.4" - path-is-absolute "^1.0.1" - private "^0.1.8" - slash "^1.0.0" - source-map "^0.5.7" - -babel-generator@^6.26.0: - version "6.26.1" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" - integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== - dependencies: - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - detect-indent "^4.0.0" - jsesc "^1.3.0" - lodash "^4.17.4" - source-map "^0.5.7" - trim-right "^1.0.1" - -babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" - integrity sha1-zORReto1b0IgvK6KAsKzRvmlZmQ= - dependencies: - babel-helper-explode-assignable-expression "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-call-delegate@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" - integrity sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340= - dependencies: - babel-helper-hoist-variables "^6.24.1" - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-define-map@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" - integrity sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8= - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-helper-explode-assignable-expression@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" - integrity sha1-8luCz33BBDPFX3BZLVdGQArCLKo= - dependencies: - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-function-name@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" - integrity sha1-00dbjAPtmCQqJbSDUasYOZ01gKk= - dependencies: - babel-helper-get-function-arity "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-get-function-arity@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" - integrity sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-hoist-variables@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" - integrity sha1-HssnaJydJVE+rbyZFKc/VAi+enY= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-optimise-call-expression@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" - integrity sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-regex@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" - integrity sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI= - dependencies: - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-helper-remap-async-to-generator@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" - integrity sha1-XsWBgnrXI/7N04HxySg5BnbkVRs= - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-replace-supers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" - integrity sha1-v22/5Dk40XNpohPKiov3S2qQqxo= - dependencies: - babel-helper-optimise-call-expression "^6.24.1" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helpers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" - integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI= - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-messages@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" - integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-check-es2015-constants@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" - integrity sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-syntax-async-functions@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" - integrity sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU= - -babel-plugin-syntax-exponentiation-operator@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" - integrity sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4= - -babel-plugin-syntax-trailing-function-commas@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" - integrity sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM= - -babel-plugin-transform-async-to-generator@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" - integrity sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E= - dependencies: - babel-helper-remap-async-to-generator "^6.24.1" - babel-plugin-syntax-async-functions "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-arrow-functions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" - integrity sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" - integrity sha1-u8UbSflk1wy42OC5ToICRs46YUE= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-block-scoping@^6.23.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" - integrity sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8= - dependencies: - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-plugin-transform-es2015-classes@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" - integrity sha1-WkxYpQyclGHlZLSyo7+ryXolhNs= - dependencies: - babel-helper-define-map "^6.24.1" - babel-helper-function-name "^6.24.1" - babel-helper-optimise-call-expression "^6.24.1" - babel-helper-replace-supers "^6.24.1" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-computed-properties@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" - integrity sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM= - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-destructuring@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" - integrity sha1-mXux8auWf2gtKwh2/jWNYOdlxW0= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-duplicate-keys@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" - integrity sha1-c+s9MQypaePvnskcU3QabxV2Qj4= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-for-of@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" - integrity sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-function-name@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" - integrity sha1-g0yJhTvDaxrw86TF26qU/Y6sqos= - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-literals@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" - integrity sha1-T1SgLWzWbPkVKAAZox0xklN3yi4= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" - integrity sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ= - dependencies: - babel-plugin-transform-es2015-modules-commonjs "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: - version "6.26.2" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" - integrity sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q== - dependencies: - babel-plugin-transform-strict-mode "^6.24.1" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-types "^6.26.0" - -babel-plugin-transform-es2015-modules-systemjs@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" - integrity sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM= - dependencies: - babel-helper-hoist-variables "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-modules-umd@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" - integrity sha1-rJl+YoXNGO1hdq22B9YCNErThGg= - dependencies: - babel-plugin-transform-es2015-modules-amd "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-object-super@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" - integrity sha1-JM72muIcuDp/hgPa0CH1cusnj40= - dependencies: - babel-helper-replace-supers "^6.24.1" - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-parameters@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" - integrity sha1-V6w1GrScrxSpfNE7CfZv3wpiXys= - dependencies: - babel-helper-call-delegate "^6.24.1" - babel-helper-get-function-arity "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-shorthand-properties@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" - integrity sha1-JPh11nIch2YbvZmkYi5R8U3jiqA= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-spread@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" - integrity sha1-1taKmfia7cRTbIGlQujdnxdG+NE= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-sticky-regex@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" - integrity sha1-AMHNsaynERLN8M9hJsLta0V8zbw= - dependencies: - babel-helper-regex "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-template-literals@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" - integrity sha1-qEs0UPfp+PH2g51taH2oS7EjbY0= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-typeof-symbol@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" - integrity sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-unicode-regex@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" - integrity sha1-04sS9C6nMj9yk4fxinxa4frrNek= - dependencies: - babel-helper-regex "^6.24.1" - babel-runtime "^6.22.0" - regexpu-core "^2.0.0" - -babel-plugin-transform-exponentiation-operator@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" - integrity sha1-KrDJx/MJj6SJB3cruBP+QejeOg4= - dependencies: - babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" - babel-plugin-syntax-exponentiation-operator "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-regenerator@^6.22.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" - integrity sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8= - dependencies: - regenerator-transform "^0.10.0" - -babel-plugin-transform-strict-mode@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" - integrity sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-preset-env@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" - integrity sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg== - dependencies: - babel-plugin-check-es2015-constants "^6.22.0" - babel-plugin-syntax-trailing-function-commas "^6.22.0" - babel-plugin-transform-async-to-generator "^6.22.0" - babel-plugin-transform-es2015-arrow-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoping "^6.23.0" - babel-plugin-transform-es2015-classes "^6.23.0" - babel-plugin-transform-es2015-computed-properties "^6.22.0" - babel-plugin-transform-es2015-destructuring "^6.23.0" - babel-plugin-transform-es2015-duplicate-keys "^6.22.0" - babel-plugin-transform-es2015-for-of "^6.23.0" - babel-plugin-transform-es2015-function-name "^6.22.0" - babel-plugin-transform-es2015-literals "^6.22.0" - babel-plugin-transform-es2015-modules-amd "^6.22.0" - babel-plugin-transform-es2015-modules-commonjs "^6.23.0" - babel-plugin-transform-es2015-modules-systemjs "^6.23.0" - babel-plugin-transform-es2015-modules-umd "^6.23.0" - babel-plugin-transform-es2015-object-super "^6.22.0" - babel-plugin-transform-es2015-parameters "^6.23.0" - babel-plugin-transform-es2015-shorthand-properties "^6.22.0" - babel-plugin-transform-es2015-spread "^6.22.0" - babel-plugin-transform-es2015-sticky-regex "^6.22.0" - babel-plugin-transform-es2015-template-literals "^6.22.0" - babel-plugin-transform-es2015-typeof-symbol "^6.23.0" - babel-plugin-transform-es2015-unicode-regex "^6.22.0" - babel-plugin-transform-exponentiation-operator "^6.22.0" - babel-plugin-transform-regenerator "^6.22.0" - browserslist "^3.2.6" - invariant "^2.2.2" - semver "^5.3.0" - -babel-register@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" - integrity sha1-btAhFz4vy0htestFxgCahW9kcHE= - dependencies: - babel-core "^6.26.0" - babel-runtime "^6.26.0" - core-js "^2.5.0" - home-or-tmp "^2.0.0" - lodash "^4.17.4" - mkdirp "^0.5.1" - source-map-support "^0.4.15" - -babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" - integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.11.0" - -babel-template@^6.24.1, babel-template@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" - integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= - dependencies: - babel-runtime "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - lodash "^4.17.4" - -babel-traverse@^6.24.1, babel-traverse@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" - integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= - dependencies: - babel-code-frame "^6.26.0" - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - debug "^2.6.8" - globals "^9.18.0" - invariant "^2.2.2" - lodash "^4.17.4" - -babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" - integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= - dependencies: - babel-runtime "^6.26.0" - esutils "^2.0.2" - lodash "^4.17.4" - to-fast-properties "^1.0.3" - -babelify@^7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/babelify/-/babelify-7.3.0.tgz#aa56aede7067fd7bd549666ee16dc285087e88e5" - integrity sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU= - dependencies: - babel-core "^6.0.14" - object-assign "^4.0.0" - -babylon@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" - integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== - -backoff@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/backoff/-/backoff-2.5.0.tgz#f616eda9d3e4b66b8ca7fca79f695722c5f8e26f" - integrity sha1-9hbtqdPktmuMp/ynn2lXIsX44m8= - dependencies: - precond "0.2" - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -base-x@^3.0.2, base-x@^3.0.8: - version "3.0.8" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.8.tgz#1e1106c2537f0162e8b52474a557ebb09000018d" - integrity sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA== - dependencies: - safe-buffer "^5.0.1" - -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - 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== - -bignumber.js@^9.0.0, bignumber.js@^9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.1.tgz#8d7ba124c882bfd8e43260c67475518d0689e4e5" - integrity sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA== - -binary-extensions@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" - integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== - -bip39@2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.5.0.tgz#51cbd5179460504a63ea3c000db3f787ca051235" - integrity sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA== - dependencies: - create-hash "^1.1.0" - pbkdf2 "^3.0.9" - randombytes "^2.0.1" - safe-buffer "^5.0.1" - unorm "^1.3.3" - -blakejs@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.1.0.tgz#69df92ef953aa88ca51a32df6ab1c54a155fc7a5" - integrity sha1-ad+S75U6qIylGjLfarHFShVfx6U= - -bluebird@^3.5.0, bluebird@^3.5.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== - -bn.js@4.11.6: - version "4.11.6" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" - integrity sha1-UzRK2xRhehP26N0s4okF0cC6MhU= - -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.10.0, bn.js@^4.11.0, bn.js@^4.11.1, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.11.9, bn.js@^4.4.0, bn.js@^4.8.0: - version "4.11.9" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" - integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw== - -bn.js@^5.0.0, bn.js@^5.1.1, bn.js@^5.1.2: - version "5.1.3" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.3.tgz#beca005408f642ebebea80b042b4d18d2ac0ee6b" - integrity sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ== - -body-parser@1.19.0, body-parser@^1.16.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" - integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== - 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" - -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" - -braces@^2.3.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - -braces@^3.0.1, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -brorand@^1.0.1, brorand@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= - -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - -browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" - integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== - dependencies: - buffer-xor "^1.0.3" - cipher-base "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.3" - inherits "^2.0.1" - safe-buffer "^5.0.1" - -browserify-cipher@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" - integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== - dependencies: - browserify-aes "^1.0.4" - browserify-des "^1.0.0" - evp_bytestokey "^1.0.0" - -browserify-des@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" - integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== - dependencies: - cipher-base "^1.0.1" - des.js "^1.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" - integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== - dependencies: - bn.js "^5.0.0" - randombytes "^2.0.1" - -browserify-sign@^4.0.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3" - integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg== - dependencies: - bn.js "^5.1.1" - browserify-rsa "^4.0.1" - create-hash "^1.2.0" - create-hmac "^1.1.7" - elliptic "^6.5.3" - inherits "^2.0.4" - parse-asn1 "^5.1.5" - readable-stream "^3.6.0" - safe-buffer "^5.2.0" - -browserslist@^3.2.6: - version "3.2.8" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" - integrity sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ== - dependencies: - caniuse-lite "^1.0.30000844" - electron-to-chromium "^1.3.47" - -bs58@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" - integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo= - 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" - -bser@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" - integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== - dependencies: - node-int64 "^0.4.0" - -buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - -buffer-to-arraybuffer@^0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz#6064a40fa76eb43c723aba9ef8f6e1216d10511a" - integrity sha1-YGSkD6dutDxyOrqe+PbhIW0QURo= - -buffer-xor@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= - -buffer-xor@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-2.0.2.tgz#34f7c64f04c777a1f8aac5e661273bb9dd320289" - integrity sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ== - dependencies: - safe-buffer "^5.1.1" - -buffer@^5.0.5, buffer@^5.2.1, buffer@^5.5.0, buffer@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" - integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - -bufferutil@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.2.tgz#79f68631910f6b993d870fc77dc0a2894eb96cd5" - integrity sha512-AtnG3W6M8B2n4xDQ5R+70EXvOpnXsFYg/AK2yTZd+HQ/oxAdz+GI+DvjmhBw3L0ole+LJ0ngqY4JMbDzkfNzhA== - dependencies: - node-gyp-build "^4.2.0" - -bytes@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" - integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== - -bytewise-core@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/bytewise-core/-/bytewise-core-1.2.3.tgz#3fb410c7e91558eb1ab22a82834577aa6bd61d42" - integrity sha1-P7QQx+kVWOsasiqCg0V3qmvWHUI= - dependencies: - typewise-core "^1.2" - -bytewise@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/bytewise/-/bytewise-1.1.0.tgz#1d13cbff717ae7158094aa881b35d081b387253e" - integrity sha1-HRPL/3F65xWAlKqIGzXQgbOHJT4= - dependencies: - bytewise-core "^1.2.2" - typewise "^1.0.3" - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - -cacheable-request@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" - integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== - dependencies: - clone-response "^1.0.2" - get-stream "^5.1.0" - http-cache-semantics "^4.0.0" - keyv "^3.0.0" - lowercase-keys "^2.0.0" - normalize-url "^4.1.0" - responselike "^1.0.2" - -cachedown@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/cachedown/-/cachedown-1.0.0.tgz#d43f036e4510696b31246d7db31ebf0f7ac32d15" - integrity sha1-1D8DbkUQaWsxJG19sx6/D3rDLRU= - dependencies: - abstract-leveldown "^2.4.1" - lru-cache "^3.2.0" - -call-bind@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.0.tgz#24127054bb3f9bdcb4b1fb82418186072f77b8ce" - integrity sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^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" - -caller-callsite@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" - integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= - dependencies: - callsites "^2.0.0" - -caller-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" - integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= - dependencies: - caller-callsite "^2.0.0" - -callsites@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" - integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= - -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@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" - integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= - -camelcase@^5.0.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -caniuse-lite@^1.0.30000844: - version "1.0.30001170" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001170.tgz#0088bfecc6a14694969e391cc29d7eb6362ca6a7" - integrity sha512-Dd4d/+0tsK0UNLrZs3CvNukqalnVTRrxb5mcQm8rHL49t7V5ZaTygwXkrq+FB+dVDf++4ri8eJnFEJAB8332PA== - -capture-exit@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" - integrity sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g== - dependencies: - rsvp "^4.8.4" - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -cbor@^5.0.2: - version "5.2.0" - resolved "https://registry.yarnpkg.com/cbor/-/cbor-5.2.0.tgz#4cca67783ccd6de7b50ab4ed62636712f287a67c" - integrity sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A== - dependencies: - bignumber.js "^9.0.1" - nofilter "^1.0.4" - -chai@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5" - integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw== - 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.0" - type-detect "^4.0.5" - -chalk@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - 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.0.0, chalk@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" - integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== - -check-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= - -checkpoint-store@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/checkpoint-store/-/checkpoint-store-1.1.0.tgz#04e4cb516b91433893581e6d4601a78e9552ea06" - integrity sha1-BOTLUWuRQziTWB5tRgGnjpVS6gY= - dependencies: - functional-red-black-tree "^1.0.1" - -chokidar@3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.0.tgz#12c0714668c55800f659e262d4962a97faf554a6" - 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.4.0: - version "3.4.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.3.tgz#c1df38231448e45ca4ac588e6c79573ba6a57d5b" - integrity sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ== - 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.5.0" - optionalDependencies: - fsevents "~2.1.2" - -chownr@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== - -ci-info@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" - integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== - -cids@^0.7.1: - version "0.7.5" - resolved "https://registry.yarnpkg.com/cids/-/cids-0.7.5.tgz#60a08138a99bfb69b6be4ceb63bfef7a396b28b2" - integrity sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA== - dependencies: - buffer "^5.5.0" - class-is "^1.1.0" - multibase "~0.6.0" - multicodec "^1.0.0" - multihashes "~0.4.15" - -cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -class-is@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/class-is/-/class-is-1.1.0.tgz#9d3c0fba0440d211d843cec3dedfa48055005825" - integrity sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw== - -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - -cli-cursor@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" - integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= - dependencies: - restore-cursor "^2.0.0" - -cli-width@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48" - integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw== - -cliui@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" - integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - wrap-ansi "^2.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" - -clone-response@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" - integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= - dependencies: - mimic-response "^1.0.0" - -clone@2.1.2, clone@^2.0.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" - integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - -collect-v8-coverage@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" - integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -command-exists@^1.2.8: - version "1.2.9" - resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69" - integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w== - -command-line-args@^4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-4.0.7.tgz#f8d1916ecb90e9e121eda6428e41300bfb64cc46" - integrity sha512-aUdPvQRAyBvQd2n7jXcsMDz68ckBJELXNzBybCHOibUWEg0mWTnaYCSRU8h9R+aNRSvDihJtssSRCiDRpLaezA== - dependencies: - array-back "^2.0.0" - find-replace "^1.0.3" - typical "^2.6.1" - -commander@2.18.0: - version "2.18.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.18.0.tgz#2bf063ddee7c7891176981a2cc798e5754bc6970" - integrity sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ== - -commander@3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" - integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== - -component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -concat-stream@^1.5.1: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -content-disposition@0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" - integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== - dependencies: - safe-buffer "5.1.2" - -content-hash@^2.5.2: - version "2.5.2" - resolved "https://registry.yarnpkg.com/content-hash/-/content-hash-2.5.2.tgz#bbc2655e7c21f14fd3bfc7b7d4bfe6e454c9e211" - integrity sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw== - dependencies: - cids "^0.7.1" - multicodec "^0.5.5" - multihashes "^0.4.15" - -content-type@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== - -convert-source-map@^1.5.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" - integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== - dependencies: - safe-buffer "~5.1.1" - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= - -cookie@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" - integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== - -cookie@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" - integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== - -cookiejar@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c" - integrity sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA== - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= - -core-js-pure@^3.0.1: - version "3.8.1" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.8.1.tgz#23f84048f366fdfcf52d3fd1c68fec349177d119" - integrity sha512-Se+LaxqXlVXGvmexKGPvnUIYC1jwXu1H6Pkyb3uBM5d8/NELMYCHs/4/roD7721NxrTLyv7e5nXd5/QLBO+10g== - -core-js@^2.4.0, core-js@^2.5.0: - version "2.6.12" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" - integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== - -core-util-is@1.0.2, core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -cors@^2.8.1: - version "2.8.5" - resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" - integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== - dependencies: - object-assign "^4" - vary "^1" - -cosmiconfig@^5.0.7: - version "5.2.1" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" - integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== - dependencies: - import-fresh "^2.0.0" - is-directory "^0.3.1" - js-yaml "^3.13.1" - parse-json "^4.0.0" - -crc-32@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208" - integrity sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA== - dependencies: - exit-on-epipe "~1.0.1" - printj "~1.1.0" - -create-ecdh@^4.0.0: - version "4.0.4" - resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" - integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== - dependencies: - bn.js "^4.1.0" - elliptic "^6.5.3" - -create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - -create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" - integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== - dependencies: - cipher-base "^1.0.3" - create-hash "^1.1.0" - inherits "^2.0.1" - ripemd160 "^2.0.0" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -cross-fetch@^2.1.0, cross-fetch@^2.1.1: - version "2.2.3" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.2.3.tgz#e8a0b3c54598136e037f8650f8e823ccdfac198e" - integrity sha512-PrWWNH3yL2NYIb/7WF/5vFG3DCQiXDOVf8k3ijatbrtnwNuhMWLC7YF7uqf53tbTFDzHIUD8oITw4Bxt8ST3Nw== - dependencies: - node-fetch "2.1.2" - whatwg-fetch "2.0.4" - -cross-spawn@^6.0.0, cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -crypto-browserify@3.12.0: - version "3.12.0" - resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" - integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== - dependencies: - browserify-cipher "^1.0.0" - browserify-sign "^4.0.0" - create-ecdh "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.0" - diffie-hellman "^5.0.0" - inherits "^2.0.1" - pbkdf2 "^3.0.3" - public-encrypt "^4.0.0" - randombytes "^2.0.0" - randomfill "^1.0.3" - -d@1, d@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" - integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== - dependencies: - es5-ext "^0.10.50" - type "^1.0.1" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@3.2.6: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== - dependencies: - ms "^2.1.1" - -debug@4, debug@^4.0.1, debug@^4.1.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" - integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== - dependencies: - ms "2.1.2" - -debug@^3.1.0: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -decamelize@^1.1.1, decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= - -decimal.js@^10.2.1: - version "10.2.1" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.1.tgz#238ae7b0f0c793d3e3cea410108b35a2c01426a3" - integrity sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw== - -decode-uri-component@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= - -decompress-response@^3.2.0, decompress-response@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" - integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= - dependencies: - mimic-response "^1.0.0" - -deep-eql@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" - integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== - dependencies: - type-detect "^4.0.0" - -deep-equal@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" - integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== - dependencies: - is-arguments "^1.0.4" - is-date-object "^1.0.1" - is-regex "^1.0.4" - object-is "^1.0.1" - object-keys "^1.1.1" - regexp.prototype.flags "^1.2.0" - -deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= - -defer-to-connect@^1.0.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" - integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== - -deferred-leveldown@~1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz#3acd2e0b75d1669924bc0a4b642851131173e1eb" - integrity sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA== - dependencies: - abstract-leveldown "~2.6.0" - -deferred-leveldown@~4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-4.0.2.tgz#0b0570087827bf480a23494b398f04c128c19a20" - integrity sha512-5fMC8ek8alH16QiV0lTCis610D1Zt1+LA4MS4d63JgS32lrCjTFDUFz2ao09/j2I4Bqb5jL4FZYwu7Jz0XO1ww== - dependencies: - abstract-leveldown "~5.0.0" - inherits "^2.0.3" - -deferred-leveldown@~5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz#27a997ad95408b61161aa69bd489b86c71b78058" - integrity sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw== - dependencies: - abstract-leveldown "~6.2.1" - inherits "^2.0.3" - -define-properties@^1.1.2, define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - -defined@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" - integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= - -des.js@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" - integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== - dependencies: - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - -destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= - -detect-indent@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" - integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg= - dependencies: - repeating "^2.0.0" - -diff-sequences@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" - integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q== - -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@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -diffie-hellman@^5.0.0: - version "5.0.3" - resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" - integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== - dependencies: - bn.js "^4.1.0" - miller-rabin "^4.0.0" - randombytes "^2.0.0" - -dir-to-object@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/dir-to-object/-/dir-to-object-2.0.0.tgz#29723e9bd1c3e58e4f307bd04ff634c0370c8f8a" - integrity sha512-sXs0JKIhymON7T1UZuO2Ud6VTNAx/VTBXIl4+3mjb2RgfOpt+hectX0x04YqPOPdkeOAKoJuKqwqnXXURNPNEA== - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -dom-walk@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" - integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== - -dotignore@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/dotignore/-/dotignore-0.1.2.tgz#f942f2200d28c3a76fbdd6f0ee9f3257c8a2e905" - integrity sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw== - dependencies: - minimatch "^3.0.4" - -duplexer3@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" - integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= - -electron-to-chromium@^1.3.47: - version "1.3.633" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.633.tgz#16dd5aec9de03894e8d14a1db4cda8a369b9b7fe" - integrity sha512-bsVCsONiVX1abkWdH7KtpuDAhsQ3N3bjPYhROSAXE78roJKet0Y5wznA14JE9pzbwSZmSMAW6KiKYf1RvbTJkA== - -elliptic@6.5.3, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3: - version "6.5.3" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6" - integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw== - 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" - -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.0.0: - version "9.2.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.0.tgz#a26da8e832b16a9753309f25e35e3c0efb9a066a" - integrity sha512-DNc3KFPK18bPdElMJnf/Pkv5TXhxFU3YFDEuGLDRtPmV4rkmCjBkCSEp22u6rBHdSN9Vlp/GK7k98prmE1Jgug== - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= - -encoding-down@5.0.4, encoding-down@~5.0.0: - version "5.0.4" - resolved "https://registry.yarnpkg.com/encoding-down/-/encoding-down-5.0.4.tgz#1e477da8e9e9d0f7c8293d320044f8b2cd8e9614" - integrity sha512-8CIZLDcSKxgzT+zX8ZVfgNbu8Md2wq/iqa1Y7zyVR18QBEAc0Nmzuvj/N5ykSKpfGzjM8qxbaFntLPwnVoUhZw== - dependencies: - abstract-leveldown "^5.0.0" - inherits "^2.0.3" - level-codec "^9.0.0" - level-errors "^2.0.0" - xtend "^4.0.1" - -encoding-down@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/encoding-down/-/encoding-down-6.3.0.tgz#b1c4eb0e1728c146ecaef8e32963c549e76d082b" - integrity sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw== - dependencies: - abstract-leveldown "^6.2.1" - inherits "^2.0.3" - level-codec "^9.0.0" - level-errors "^2.0.0" - -encoding@^0.1.11: - version "0.1.13" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" - integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== - dependencies: - iconv-lite "^0.6.2" - -end-of-stream@^1.1.0: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -enquirer@^2.3.0: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - -env-paths@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.0.tgz#cdca557dc009152917d6166e2febe1f039685e43" - integrity sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA== - -errno@~0.1.1: - version "0.1.8" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" - integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== - dependencies: - prr "~1.0.1" - -error-ex@^1.2.0, 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.17.0-next.1, es-abstract@^1.17.2: - version "1.17.7" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.7.tgz#a4de61b2f66989fc7421676c1cb9787573ace54c" - integrity sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g== - 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" - -es-abstract@^1.18.0-next.1: - version "1.18.0-next.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.1.tgz#6e3a0a4bda717e5023ab3b8e90bec36108d22c68" - integrity sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA== - 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" - -es-abstract@^1.18.0-next.2: - version "1.18.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0.tgz#ab80b359eecb7ede4c298000390bc5ac3ec7b5a4" - integrity sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - get-intrinsic "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.2" - is-callable "^1.2.3" - is-negative-zero "^2.0.1" - is-regex "^1.1.2" - is-string "^1.0.5" - object-inspect "^1.9.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.0" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -es5-ext@^0.10.35, es5-ext@^0.10.50: - version "0.10.53" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" - integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q== - dependencies: - es6-iterator "~2.0.3" - es6-symbol "~3.1.3" - next-tick "~1.0.0" - -es6-iterator@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" - integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= - dependencies: - d "1" - es5-ext "^0.10.35" - es6-symbol "^3.1.1" - -es6-symbol@^3.1.1, es6-symbol@~3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" - integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== - dependencies: - d "^1.0.1" - ext "^1.1.2" - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= - -escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -escape-string-regexp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" - integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== - -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== - -eslint-scope@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" - integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -eslint-utils@^1.3.1: - version "1.4.3" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" - integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - -eslint@^5.6.0: - version "5.16.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea" - integrity sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg== - 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" - -espree@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a" - integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A== - dependencies: - acorn "^6.0.7" - acorn-jsx "^5.0.0" - eslint-visitor-keys "^1.0.0" - -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== - -esquery@^1.0.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.3.1.tgz#b78b5828aa8e214e29fb74c4d5b752e1c033da57" - integrity sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.1.0, estraverse@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" - integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= - -eth-block-tracker@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/eth-block-tracker/-/eth-block-tracker-3.0.1.tgz#95cd5e763c7293e0b1b2790a2a39ac2ac188a5e1" - integrity sha512-WUVxWLuhMmsfenfZvFO5sbl1qFY2IqUlw/FPVmjjdElpqLsZtSG+wPe9Dz7W/sB6e80HgFKknOmKk2eNlznHug== - dependencies: - eth-query "^2.1.0" - ethereumjs-tx "^1.3.3" - ethereumjs-util "^5.1.3" - ethjs-util "^0.1.3" - json-rpc-engine "^3.6.0" - pify "^2.3.0" - tape "^4.6.3" - -eth-ens-namehash@2.0.8, eth-ens-namehash@^2.0.8: - version "2.0.8" - resolved "https://registry.yarnpkg.com/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz#229ac46eca86d52e0c991e7cb2aef83ff0f68bcf" - integrity sha1-IprEbsqG1S4MmR58sq74P/D2i88= - dependencies: - idna-uts46-hx "^2.3.1" - js-sha3 "^0.5.7" - -eth-json-rpc-infura@^3.1.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/eth-json-rpc-infura/-/eth-json-rpc-infura-3.2.1.tgz#26702a821067862b72d979c016fd611502c6057f" - integrity sha512-W7zR4DZvyTn23Bxc0EWsq4XGDdD63+XPUCEhV2zQvQGavDVC4ZpFDK4k99qN7bd7/fjj37+rxmuBOBeIqCA5Mw== - dependencies: - cross-fetch "^2.1.1" - eth-json-rpc-middleware "^1.5.0" - json-rpc-engine "^3.4.0" - json-rpc-error "^2.0.0" - -eth-json-rpc-middleware@^1.5.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.6.0.tgz#5c9d4c28f745ccb01630f0300ba945f4bef9593f" - integrity sha512-tDVCTlrUvdqHKqivYMjtFZsdD7TtpNLBCfKAcOpaVs7orBMS/A8HWro6dIzNtTZIR05FAbJ3bioFOnZpuCew9Q== - dependencies: - async "^2.5.0" - eth-query "^2.1.2" - eth-tx-summary "^3.1.2" - ethereumjs-block "^1.6.0" - ethereumjs-tx "^1.3.3" - ethereumjs-util "^5.1.2" - ethereumjs-vm "^2.1.0" - fetch-ponyfill "^4.0.0" - json-rpc-engine "^3.6.0" - json-rpc-error "^2.0.0" - json-stable-stringify "^1.0.1" - promise-to-callback "^1.0.0" - tape "^4.6.3" - -eth-lib@0.2.8: - version "0.2.8" - resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.2.8.tgz#b194058bef4b220ad12ea497431d6cb6aa0623c8" - integrity sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw== - dependencies: - bn.js "^4.11.6" - elliptic "^6.4.0" - xhr-request-promise "^0.1.2" - -eth-lib@^0.1.26: - version "0.1.29" - resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.1.29.tgz#0c11f5060d42da9f931eab6199084734f4dbd1d9" - integrity sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ== - dependencies: - bn.js "^4.11.6" - elliptic "^6.4.0" - nano-json-stream-parser "^0.1.2" - servify "^0.1.12" - ws "^3.0.0" - xhr-request-promise "^0.1.2" - -eth-query@^2.0.2, eth-query@^2.1.0, eth-query@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/eth-query/-/eth-query-2.1.2.tgz#d6741d9000106b51510c72db92d6365456a6da5e" - integrity sha1-1nQdkAAQa1FRDHLbktY2VFam2l4= - dependencies: - json-rpc-random-id "^1.0.0" - xtend "^4.0.1" - -eth-sig-util@^1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-1.4.2.tgz#8d958202c7edbaae839707fba6f09ff327606210" - integrity sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA= - dependencies: - ethereumjs-abi "git+https://github.com/ethereumjs/ethereumjs-abi.git" - ethereumjs-util "^5.1.1" - -eth-sig-util@^2.0.0, eth-sig-util@^2.5.2: - version "2.5.3" - resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-2.5.3.tgz#6938308b38226e0b3085435474900b03036abcbe" - integrity sha512-KpXbCKmmBUNUTGh9MRKmNkIPietfhzBqqYqysDavLseIiMUGl95k6UcPEkALAZlj41e9E6yioYXc1PC333RKqw== - dependencies: - buffer "^5.2.1" - elliptic "^6.4.0" - ethereumjs-abi "0.6.5" - ethereumjs-util "^5.1.1" - tweetnacl "^1.0.0" - tweetnacl-util "^0.15.0" - -eth-tx-summary@^3.1.2: - version "3.2.4" - resolved "https://registry.yarnpkg.com/eth-tx-summary/-/eth-tx-summary-3.2.4.tgz#e10eb95eb57cdfe549bf29f97f1e4f1db679035c" - integrity sha512-NtlDnaVZah146Rm8HMRUNMgIwG/ED4jiqk0TME9zFheMl1jOp6jL1m0NKGjJwehXQ6ZKCPr16MTr+qspKpEXNg== - dependencies: - async "^2.1.2" - clone "^2.0.0" - concat-stream "^1.5.1" - end-of-stream "^1.1.0" - eth-query "^2.0.2" - ethereumjs-block "^1.4.1" - ethereumjs-tx "^1.1.1" - ethereumjs-util "^5.0.1" - ethereumjs-vm "^2.6.0" - through2 "^2.0.3" - -ethashjs@~0.0.7: - version "0.0.8" - resolved "https://registry.yarnpkg.com/ethashjs/-/ethashjs-0.0.8.tgz#227442f1bdee409a548fb04136e24c874f3aa6f9" - integrity sha512-/MSbf/r2/Ld8o0l15AymjOTlPqpN8Cr4ByUEA9GtR4x0yAh3TdtDzEg29zMjXCNPI7u6E5fOQdj/Cf9Tc7oVNw== - dependencies: - async "^2.1.2" - buffer-xor "^2.0.1" - ethereumjs-util "^7.0.2" - miller-rabin "^4.0.0" - -ethereum-bloom-filters@^1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.7.tgz#b7b80735e385dbb7f944ce6b4533e24511306060" - integrity sha512-cDcJJSJ9GMAcURiAWO3DxIEhTL/uWqlQnvgKpuYQzYPrt/izuGU+1ntQmHt0IRq6ADoSYHFnB+aCEFIldjhkMQ== - dependencies: - js-sha3 "^0.8.0" - -ethereum-common@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.2.0.tgz#13bf966131cce1eeade62a1b434249bb4cb120ca" - integrity sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA== - -ethereum-common@^0.0.18: - version "0.0.18" - resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.0.18.tgz#2fdc3576f232903358976eb39da783213ff9523f" - integrity sha1-L9w1dvIykDNYl26znaeDIT/5Uj8= - -ethereum-cryptography@^0.1.2, 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-waffle@^3.0.2: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ethereum-waffle/-/ethereum-waffle-3.2.1.tgz#9d6d6b93484c5e1b77dfdeb646c050ed877e836e" - integrity sha512-Fhg7BaBuV+Xo5XT+NEC3UTKGunvpq+iQPglZbIAJF6ZcwQwkiKfJUDuB0ZSkg5ntbRS4gpahfoXj1nTzdtx8UA== - dependencies: - "@ethereum-waffle/chai" "^3.2.1" - "@ethereum-waffle/compiler" "^3.2.1" - "@ethereum-waffle/mock-contract" "^3.2.1" - "@ethereum-waffle/provider" "^3.2.1" - ethers "^5.0.1" - -ethereumjs-abi@0.6.5: - version "0.6.5" - resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.5.tgz#5a637ef16ab43473fa72a29ad90871405b3f5241" - integrity sha1-WmN+8Wq0NHP6cqKa2QhxQFs/UkE= - dependencies: - bn.js "^4.10.0" - ethereumjs-util "^4.3.0" - -ethereumjs-abi@0.6.8, ethereumjs-abi@^0.6.8: - version "0.6.8" - resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz#71bc152db099f70e62f108b7cdfca1b362c6fcae" - integrity sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA== - dependencies: - bn.js "^4.11.8" - ethereumjs-util "^6.0.0" - -"ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git": - version "0.6.8" - resolved "git+https://github.com/ethereumjs/ethereumjs-abi.git#1ce6a1d64235fabe2aaf827fd606def55693508f" - dependencies: - bn.js "^4.11.8" - ethereumjs-util "^6.0.0" - -ethereumjs-account@3.0.0, ethereumjs-account@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ethereumjs-account/-/ethereumjs-account-3.0.0.tgz#728f060c8e0c6e87f1e987f751d3da25422570a9" - integrity sha512-WP6BdscjiiPkQfF9PVfMcwx/rDvfZTjFKY0Uwc09zSQr9JfIVH87dYIJu0gNhBhpmovV4yq295fdllS925fnBA== - dependencies: - ethereumjs-util "^6.0.0" - rlp "^2.2.1" - safe-buffer "^5.1.1" - -ethereumjs-account@^2.0.3: - version "2.0.5" - resolved "https://registry.yarnpkg.com/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz#eeafc62de544cb07b0ee44b10f572c9c49e00a84" - integrity sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA== - dependencies: - ethereumjs-util "^5.0.0" - rlp "^2.0.0" - safe-buffer "^5.1.1" - -ethereumjs-block@2.2.2, ethereumjs-block@^2.2.2, ethereumjs-block@~2.2.0, ethereumjs-block@~2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz#c7654be7e22df489fda206139ecd63e2e9c04965" - integrity sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg== - dependencies: - async "^2.0.1" - ethereumjs-common "^1.5.0" - ethereumjs-tx "^2.1.1" - ethereumjs-util "^5.0.0" - merkle-patricia-tree "^2.1.2" - -ethereumjs-block@^1.2.2, ethereumjs-block@^1.4.1, ethereumjs-block@^1.6.0: - version "1.7.1" - resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz#78b88e6cc56de29a6b4884ee75379b6860333c3f" - integrity sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg== - dependencies: - async "^2.0.1" - ethereum-common "0.2.0" - ethereumjs-tx "^1.2.2" - ethereumjs-util "^5.0.0" - merkle-patricia-tree "^2.1.2" - -ethereumjs-blockchain@^4.0.3: - version "4.0.4" - resolved "https://registry.yarnpkg.com/ethereumjs-blockchain/-/ethereumjs-blockchain-4.0.4.tgz#30f2228dc35f6dcf94423692a6902604ae34960f" - integrity sha512-zCxaRMUOzzjvX78DTGiKjA+4h2/sF0OYL1QuPux0DHpyq8XiNoF5GYHtb++GUxVlMsMfZV7AVyzbtgcRdIcEPQ== - dependencies: - async "^2.6.1" - ethashjs "~0.0.7" - ethereumjs-block "~2.2.2" - ethereumjs-common "^1.5.0" - ethereumjs-util "^6.1.0" - flow-stoplight "^1.0.0" - level-mem "^3.0.1" - lru-cache "^5.1.1" - rlp "^2.2.2" - semaphore "^1.1.0" - -ethereumjs-common@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/ethereumjs-common/-/ethereumjs-common-1.5.0.tgz#d3e82fc7c47c0cef95047f431a99485abc9bb1cd" - integrity sha512-SZOjgK1356hIY7MRj3/ma5qtfr/4B5BL+G4rP/XSMYr2z1H5el4RX5GReYCKmQmYI/nSBmRnwrZ17IfHuG0viQ== - -ethereumjs-common@^1.1.0, ethereumjs-common@^1.3.2, ethereumjs-common@^1.5.0: - version "1.5.2" - resolved "https://registry.yarnpkg.com/ethereumjs-common/-/ethereumjs-common-1.5.2.tgz#2065dbe9214e850f2e955a80e650cb6999066979" - integrity sha512-hTfZjwGX52GS2jcVO6E2sx4YuFnf0Fhp5ylo4pEPhEffNln7vS59Hr5sLnp3/QCazFLluuBZ+FZ6J5HTp0EqCA== - -ethereumjs-tx@2.1.2, ethereumjs-tx@^2.1.1, ethereumjs-tx@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz#5dfe7688bf177b45c9a23f86cf9104d47ea35fed" - integrity sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw== - dependencies: - ethereumjs-common "^1.5.0" - ethereumjs-util "^6.0.0" - -ethereumjs-tx@^1.1.1, ethereumjs-tx@^1.2.0, ethereumjs-tx@^1.2.2, ethereumjs-tx@^1.3.3: - version "1.3.7" - resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz#88323a2d875b10549b8347e09f4862b546f3d89a" - integrity sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA== - dependencies: - ethereum-common "^0.0.18" - ethereumjs-util "^5.0.0" - -ethereumjs-util@6.2.1, ethereumjs-util@^6.0.0, ethereumjs-util@^6.1.0, ethereumjs-util@^6.2.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz#fcb4e4dd5ceacb9d2305426ab1a5cd93e3163b69" - integrity sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw== - dependencies: - "@types/bn.js" "^4.11.3" - bn.js "^4.11.0" - create-hash "^1.1.2" - elliptic "^6.5.2" - ethereum-cryptography "^0.1.3" - ethjs-util "0.1.6" - rlp "^2.2.3" - -ethereumjs-util@^4.3.0: - version "4.5.1" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-4.5.1.tgz#f4bf9b3b515a484e3cc8781d61d9d980f7c83bd0" - integrity sha512-WrckOZ7uBnei4+AKimpuF1B3Fv25OmoRgmYCpGsP7u8PFxXAmAgiJSYT2kRWnt6fVIlKaQlZvuwXp7PIrmn3/w== - dependencies: - bn.js "^4.8.0" - create-hash "^1.1.2" - elliptic "^6.5.2" - ethereum-cryptography "^0.1.3" - rlp "^2.0.0" - -ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.2, ethereumjs-util@^5.1.3, ethereumjs-util@^5.1.5, ethereumjs-util@^5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz#a833f0e5fca7e5b361384dc76301a721f537bf65" - integrity sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ== - dependencies: - bn.js "^4.11.0" - create-hash "^1.1.2" - elliptic "^6.5.2" - ethereum-cryptography "^0.1.3" - ethjs-util "^0.1.3" - rlp "^2.0.0" - safe-buffer "^5.1.1" - -ethereumjs-util@^7.0.10, ethereumjs-util@^7.0.7, ethereumjs-util@^7.0.8, ethereumjs-util@^7.0.9: - version "7.0.10" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.0.10.tgz#5fb7b69fa1fda0acc59634cf39d6b0291180fc1f" - integrity sha512-c/xThw6A+EAnej5Xk5kOzFzyoSnw0WX0tSlZ6pAsfGVvQj3TItaDg9b1+Fz1RJXA+y2YksKwQnuzgt1eY6LKzw== - dependencies: - "@types/bn.js" "^5.1.0" - bn.js "^5.1.2" - create-hash "^1.1.2" - ethereum-cryptography "^0.1.3" - ethjs-util "0.1.6" - rlp "^2.2.4" - -ethereumjs-util@^7.0.2: - version "7.0.7" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.0.7.tgz#484fb9c03b766b2ee64821281070616562fb5a59" - integrity sha512-vU5rtZBlZsgkTw3o6PDKyB8li2EgLavnAbsKcfsH2YhHH1Le+PP8vEiMnAnvgc1B6uMoaM5GDCrVztBw0Q5K9g== - 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" - -ethereumjs-vm@4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-4.2.0.tgz#e885e861424e373dbc556278f7259ff3fca5edab" - integrity sha512-X6qqZbsY33p5FTuZqCnQ4+lo957iUJMM6Mpa6bL4UW0dxM6WmDSHuI4j/zOp1E2TDKImBGCJA9QPfc08PaNubA== - dependencies: - async "^2.1.2" - async-eventemitter "^0.2.2" - core-js-pure "^3.0.1" - ethereumjs-account "^3.0.0" - ethereumjs-block "^2.2.2" - ethereumjs-blockchain "^4.0.3" - ethereumjs-common "^1.5.0" - ethereumjs-tx "^2.1.2" - ethereumjs-util "^6.2.0" - fake-merkle-patricia-tree "^1.0.1" - functional-red-black-tree "^1.0.1" - merkle-patricia-tree "^2.3.2" - rustbn.js "~0.2.0" - safe-buffer "^5.1.1" - util.promisify "^1.0.0" - -ethereumjs-vm@^2.1.0, ethereumjs-vm@^2.3.4, ethereumjs-vm@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz#76243ed8de031b408793ac33907fb3407fe400c6" - integrity sha512-r/XIUik/ynGbxS3y+mvGnbOKnuLo40V5Mj1J25+HEO63aWYREIqvWeRO/hnROlMBE5WoniQmPmhiaN0ctiHaXw== - dependencies: - async "^2.1.2" - async-eventemitter "^0.2.2" - ethereumjs-account "^2.0.3" - ethereumjs-block "~2.2.0" - ethereumjs-common "^1.1.0" - ethereumjs-util "^6.0.0" - fake-merkle-patricia-tree "^1.0.1" - functional-red-black-tree "^1.0.1" - merkle-patricia-tree "^2.3.2" - rustbn.js "~0.2.0" - safe-buffer "^5.1.1" - -ethereumjs-wallet@0.6.5: - version "0.6.5" - resolved "https://registry.yarnpkg.com/ethereumjs-wallet/-/ethereumjs-wallet-0.6.5.tgz#685e9091645cee230ad125c007658833991ed474" - integrity sha512-MDwjwB9VQVnpp/Dc1XzA6J1a3wgHQ4hSvA1uWNatdpOrtCbPVuQSKSyRnjLvS0a+KKMw2pvQ9Ybqpb3+eW8oNA== - dependencies: - aes-js "^3.1.1" - bs58check "^2.1.2" - ethereum-cryptography "^0.1.3" - ethereumjs-util "^6.0.0" - randombytes "^2.0.6" - safe-buffer "^5.1.2" - scryptsy "^1.2.1" - utf8 "^3.0.0" - uuid "^3.3.2" - -ethers@^5.0.0, ethers@^5.0.1, ethers@^5.0.8: - version "5.0.24" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.0.24.tgz#fbb8e4d35070d134f2eb846c07500b8c0eaef6d3" - integrity sha512-77CEtVC88fJGEhxGXRvQqAEH6e2A+ZFiv2FBT6ikXndlty5sw6vMatAhg1v+w3CaaGZOf1CP81jl4Mc8Zrj08A== - dependencies: - "@ethersproject/abi" "5.0.9" - "@ethersproject/abstract-provider" "5.0.7" - "@ethersproject/abstract-signer" "5.0.9" - "@ethersproject/address" "5.0.8" - "@ethersproject/base64" "5.0.6" - "@ethersproject/basex" "5.0.6" - "@ethersproject/bignumber" "5.0.12" - "@ethersproject/bytes" "5.0.8" - "@ethersproject/constants" "5.0.7" - "@ethersproject/contracts" "5.0.8" - "@ethersproject/hash" "5.0.9" - "@ethersproject/hdnode" "5.0.7" - "@ethersproject/json-wallets" "5.0.9" - "@ethersproject/keccak256" "5.0.6" - "@ethersproject/logger" "5.0.8" - "@ethersproject/networks" "5.0.6" - "@ethersproject/pbkdf2" "5.0.6" - "@ethersproject/properties" "5.0.6" - "@ethersproject/providers" "5.0.17" - "@ethersproject/random" "5.0.6" - "@ethersproject/rlp" "5.0.6" - "@ethersproject/sha2" "5.0.6" - "@ethersproject/signing-key" "5.0.7" - "@ethersproject/solidity" "5.0.7" - "@ethersproject/strings" "5.0.7" - "@ethersproject/transactions" "5.0.8" - "@ethersproject/units" "5.0.8" - "@ethersproject/wallet" "5.0.9" - "@ethersproject/web" "5.0.11" - "@ethersproject/wordlists" "5.0.7" - -ethjs-unit@0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" - integrity sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk= - dependencies: - bn.js "4.11.6" - number-to-bn "1.7.0" - -ethjs-util@0.1.6, ethjs-util@^0.1.3: - version "0.1.6" - resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536" - integrity sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w== - dependencies: - is-hex-prefixed "1.0.0" - strip-hex-prefix "1.0.0" - -event-target-shim@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" - integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== - -eventemitter3@4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" - integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== - -events@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379" - integrity sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg== - -evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" - integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== - dependencies: - md5.js "^1.3.4" - safe-buffer "^5.1.1" - -exec-sh@^0.3.2: - version "0.3.4" - resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.4.tgz#3a018ceb526cc6f6df2bb504b2bfe8e3a4934ec5" - integrity sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A== - -execa@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== - 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" - -exit-on-epipe@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692" - integrity sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw== - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= - 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" - -expect@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/expect/-/expect-26.6.2.tgz#c6b996bf26bf3fe18b67b2d0f51fc981ba934417" - integrity sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA== - dependencies: - "@jest/types" "^26.6.2" - ansi-styles "^4.0.0" - jest-get-type "^26.3.0" - jest-matcher-utils "^26.6.2" - jest-message-util "^26.6.2" - jest-regex-util "^26.0.0" - -express@^4.14.0: - version "4.17.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" - integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== - 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" - -ext@^1.1.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244" - integrity sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A== - dependencies: - type "^2.0.0" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -external-editor@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" - integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - -fake-merkle-patricia-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz#4b8c3acfb520afadf9860b1f14cd8ce3402cddd3" - integrity sha1-S4w6z7Ugr635hgsfFM2M40As3dM= - dependencies: - checkpoint-store "^1.1.0" - -fast-deep-equal@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-diff@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" - integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== - -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 sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - -fb-watchman@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" - integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== - dependencies: - bser "2.1.1" - -fetch-ponyfill@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz#ae3ce5f732c645eab87e4ae8793414709b239893" - integrity sha1-rjzl9zLGReq4fkroeTQUcJsjmJM= - dependencies: - node-fetch "~1.7.1" - -figures@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" - integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= - dependencies: - escape-string-regexp "^1.0.5" - -file-entry-cache@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" - integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== - dependencies: - flat-cache "^2.0.1" - -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -finalhandler@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" - integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== - 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" - -find-package-json@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/find-package-json/-/find-package-json-1.2.0.tgz#4057d1b943f82d8445fe52dc9cf456f6b8b58083" - integrity sha512-+SOGcLGYDJHtyqHd87ysBhmaeQ95oWspDKnMXBrnQ9Eq4OkLNqejgoaD8xVWu6GPa0B6roa6KinCMEMcVeqONw== - -find-replace@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-1.0.3.tgz#b88e7364d2d9c959559f388c66670d6130441fa0" - integrity sha1-uI5zZNLZyVlVnziMZmcNYTBEH6A= - dependencies: - array-back "^1.0.4" - test-value "^2.1.0" - -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@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - -find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= - 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" - -find-yarn-workspace-root@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-1.2.1.tgz#40eb8e6e7c2502ddfaa2577c176f221422f860db" - integrity sha512-dVtfb0WuQG+8Ag2uWkbG79hOUzEsRrhBzgfn86g2sJPkzmcpGdghbNTfUKGTxymFrY/tLIodDzLoW9nOJ4FY8Q== - dependencies: - fs-extra "^4.0.3" - micromatch "^3.1.4" - -flat-cache@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" - integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== - dependencies: - flatted "^2.0.0" - rimraf "2.6.3" - write "1.0.3" - -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" - -flatted@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" - integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== - -flow-stoplight@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/flow-stoplight/-/flow-stoplight-1.0.0.tgz#4a292c5bcff8b39fa6cc0cb1a853d86f27eeff7b" - integrity sha1-SiksW8/4s5+mzAyxqFPYbyfu/3s= - -follow-redirects@^1.12.1: - version "1.13.1" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.1.tgz#5f69b813376cee4fd0474a3aba835df04ab763b7" - integrity sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg== - -for-each@^0.3.3, for-each@~0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" - integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== - dependencies: - is-callable "^1.1.3" - -for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - -form-data@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682" - integrity sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -forwarded@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" - integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= - -fp-ts@1.19.3: - version "1.19.3" - resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.3.tgz#261a60d1088fbff01f91256f91d21d0caaaaa96f" - integrity sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg== - -fp-ts@^1.0.0: - version "1.19.5" - resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.5.tgz#3da865e585dfa1fdfd51785417357ac50afc520a" - integrity sha512-wDNqTimnzs8QqpldiId9OavWK2NptormjXnRJTQecNjzwfyp6P/8s/zG8e4h3ja3oqkKaY72UlTjQYt/1yXf9A== - -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= - dependencies: - map-cache "^0.2.2" - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= - -fs-extra@^0.30.0: - version "0.30.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" - integrity sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A= - dependencies: - graceful-fs "^4.1.2" - jsonfile "^2.1.0" - klaw "^1.0.0" - path-is-absolute "^1.0.0" - rimraf "^2.2.8" - -fs-extra@^4.0.2, fs-extra@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" - integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-extra@^7.0.0, fs-extra@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" - integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-minipass@^1.2.5: - version "1.2.7" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" - integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== - dependencies: - minipass "^2.6.0" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@^2.1.2: - version "2.2.1" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.2.1.tgz#1fb02ded2036a8ac288d507a65962bd87b97628d" - integrity sha512-bTLYHSeC0UH/EFXS9KqWnXuOl/wHK5Z/d+ghd5AsFMYN7wIGkUCOJyzy88+wJKkZPGON8u4Z9f6U4FdgURE9qA== - -fsevents@~2.1.1, fsevents@~2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" - integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== - -function-bind@^1.1.1, 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== - -functional-red-black-tree@^1.0.1, functional-red-black-tree@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - -ganache-core@^2.10.2: - version "2.13.1" - resolved "https://registry.yarnpkg.com/ganache-core/-/ganache-core-2.13.1.tgz#bf60399a2dd084e1090db91cbbc7ed3885dc01e4" - integrity sha512-Ewg+kNcDqXtOohe7jCcP+ZUv9EMzOx2MoqOYYP3BCfxrDh3KjBXXaKK+Let7li0TghAs9lxmBgevZku35j5YzA== - 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 "^2.0.0" - ethereumjs-abi "0.6.8" - ethereumjs-account "3.0.0" - ethereumjs-block "2.2.2" - ethereumjs-common "1.5.0" - ethereumjs-tx "2.1.2" - ethereumjs-util "6.2.1" - ethereumjs-vm "4.2.0" - heap "0.2.6" - keccak "3.0.1" - level-sublevel "6.6.4" - levelup "3.1.1" - lodash "4.17.20" - lru-cache "5.1.1" - merkle-patricia-tree "3.0.0" - patch-package "6.2.2" - seedrandom "3.0.1" - source-map-support "0.5.12" - tmp "0.1.0" - web3-provider-engine "14.2.1" - websocket "1.0.32" - optionalDependencies: - ethereumjs-wallet "0.6.5" - web3 "1.2.11" - -get-caller-file@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" - integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== - -get-caller-file@^2.0.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 sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= - -get-intrinsic@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.2.tgz#6820da226e50b24894e08859469dc68361545d49" - integrity sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" - integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - -get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= - -get-stream@^4.0.0, get-stream@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - -get-stream@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" - integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== - dependencies: - pump "^3.0.0" - -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - -glob-parent@~5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" - integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== - 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.2, glob@^7.1.3, glob@~7.1.6: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - 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" - -global@~4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" - integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== - dependencies: - min-document "^2.19.0" - process "^0.11.10" - -globals@^11.7.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== - -globals@^9.18.0: - version "9.18.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" - integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== - -got@9.6.0: - version "9.6.0" - resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" - integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== - dependencies: - "@sindresorhus/is" "^0.14.0" - "@szmarczak/http-timer" "^1.1.2" - cacheable-request "^6.0.0" - decompress-response "^3.3.0" - duplexer3 "^0.1.4" - get-stream "^4.1.0" - lowercase-keys "^1.0.1" - mimic-response "^1.0.1" - p-cancelable "^1.0.0" - to-readable-stream "^1.0.0" - url-parse-lax "^3.0.0" - -got@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" - integrity sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw== - 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" - -graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.4: - version "4.2.4" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" - integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== - -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== - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" - -hardhat-typechain@^0.3.5: - version "0.3.5" - resolved "https://registry.yarnpkg.com/hardhat-typechain/-/hardhat-typechain-0.3.5.tgz#8e50616a9da348b33bd001168c8fda9c66b7b4af" - integrity sha512-w9lm8sxqTJACY+V7vijiH+NkPExnmtiQEjsV9JKD1KgMdVk2q8y+RhvU/c4B7+7b1+HylRUCxpOIvFuB3rE4+w== - -hardhat@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.2.0.tgz#7d569d29678e5f786a228390b4c0b0cc9fd8ae32" - integrity sha512-3g0qFoQTkR4gfcHDZr59vPfbSH2PiAyxzYblkAAHUNTPBadO5W26z5RWzDv6/lRu8SqZZ9/8AdGZX4IZEa8EDg== - dependencies: - "@ethereumjs/block" "^3.2.1" - "@ethereumjs/blockchain" "^5.2.1" - "@ethereumjs/common" "^2.2.0" - "@ethereumjs/tx" "^3.1.3" - "@ethereumjs/vm" "^5.3.2" - "@sentry/node" "^5.18.1" - "@solidity-parser/parser" "^0.11.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.0.10" - find-up "^2.1.0" - fp-ts "1.19.3" - fs-extra "^7.0.1" - glob "^7.1.3" - immutable "^4.0.0-rc.12" - io-ts "1.10.4" - lodash "^4.17.11" - merkle-patricia-tree "^4.1.0" - mnemonist "^0.38.0" - mocha "^7.1.2" - 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 "^3.3.2" - ws "^7.2.1" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= - dependencies: - ansi-regex "^2.0.0" - -has-bigints@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" - integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -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-symbol-support-x@^1.4.1: - version "1.4.2" - resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" - integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== - -has-symbols@^1.0.0, has-symbols@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" - integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== - -has-symbols@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" - integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== - -has-to-string-tag-x@^1.2.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" - integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw== - dependencies: - has-symbol-support-x "^1.4.1" - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -has@^1.0.3, has@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hash-base@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" - integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== - dependencies: - inherits "^2.0.4" - readable-stream "^3.6.0" - safe-buffer "^5.2.0" - -hash.js@1.1.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.6: - version "0.2.6" - resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.6.tgz#087e1f10b046932fc8594dd9e6d378afc9d1e5ac" - integrity sha1-CH4fELBGky/IWU3Z5tN4r8nR5aw= - -hmac-drbg@^1.0.0, hmac-drbg@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - -home-or-tmp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" - integrity sha1-42w/LSyufXRqhX440Y1fMqeILbg= - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.1" - -hosted-git-info@^2.1.4, hosted-git-info@^2.6.0: - version "2.8.8" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" - integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== - -http-cache-semantics@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" - integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== - -http-errors@1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" - integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -http-errors@1.7.3, http-errors@~1.7.2: - version "1.7.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" - integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -http-https@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/http-https/-/http-https-1.0.0.tgz#2f908dd5f1db4068c058cd6e6d4ce392c913389b" - integrity sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs= - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -https-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" - integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== - dependencies: - agent-base "6" - debug "4" - -iconv-lite@0.4.24, iconv-lite@^0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -iconv-lite@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.2.tgz#ce13d1875b0c3a674bd6a04b7f76b01b1b6ded01" - integrity sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - -idna-uts46-hx@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz#a1dc5c4df37eee522bf66d969cc980e00e8711f9" - integrity sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA== - dependencies: - punycode "2.1.0" - -ieee754@^1.1.13: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - -immediate@^3.2.3: - version "3.3.0" - resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.3.0.tgz#1aef225517836bcdf7f2a2de2600c79ff0269266" - integrity sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q== - -immediate@~3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c" - integrity sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw= - -immutable@^4.0.0-rc.12: - version "4.0.0-rc.12" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.0.0-rc.12.tgz#ca59a7e4c19ae8d9bf74a97bdf0f6e2f2a5d0217" - integrity sha512-0M2XxkZLx/mi3t8NVwIm1g8nHoEmM9p9UBl/G9k4+hm0kBgOVdMV/B3CY5dQ8qG8qc80NN4gDV4HQv6FTJ5q7A== - -import-fresh@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" - integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= - dependencies: - caller-path "^2.0.0" - resolve-from "^3.0.0" - -import-fresh@^3.0.0: - 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" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - -inquirer@^6.2.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" - integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== - 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" - -invariant@^2.2.2: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== - dependencies: - loose-envify "^1.0.0" - -invert-kv@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" - integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= - -io-ts@1.10.4: - version "1.10.4" - resolved "https://registry.yarnpkg.com/io-ts/-/io-ts-1.10.4.tgz#cd5401b138de88e4f920adbcb7026e2d1967e6e2" - integrity sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g== - dependencies: - fp-ts "^1.0.0" - -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== - dependencies: - kind-of "^6.0.0" - -is-arguments@^1.0.4: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9" - integrity sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg== - dependencies: - call-bind "^1.0.0" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-bigint@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.1.tgz#6923051dfcbc764278540b9ce0e6b3213aa5ebc2" - integrity sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg== - -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.0" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.0.tgz#e2aaad3a3a8fca34c28f6eee135b156ed2587ff0" - integrity sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA== - dependencies: - call-bind "^1.0.0" - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - -is-buffer@~2.0.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.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.2.tgz#c7c6715cd22d4ddb48d3e19970223aceabb080d9" - integrity sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA== - -is-callable@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" - integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== - -is-ci@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" - integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== - dependencies: - ci-info "^2.0.0" - -is-core-module@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" - integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== - dependencies: - has "^1.0.3" - -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== - dependencies: - kind-of "^6.0.0" - -is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== - -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -is-directory@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" - integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-finite@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" - integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== - -is-fn@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fn/-/is-fn-1.0.0.tgz#9543d5de7bcf5b08a22ec8a20bae6e286d510d8c" - integrity sha1-lUPV3nvPWwiiLsiiC65uKG1RDYw= - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-function@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08" - integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ== - -is-glob@^4.0.1, is-glob@~4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== - dependencies: - is-extglob "^2.1.1" - -is-hex-prefixed@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554" - integrity sha1-fY035q135dEnFIkTxXPggtd39VQ= - -is-negative-zero@^2.0.0, is-negative-zero@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" - integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== - -is-number-object@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197" - integrity sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw== - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= - dependencies: - kind-of "^3.0.2" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" - integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA== - -is-plain-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= - -is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-regex@^1.0.4, is-regex@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.1.tgz#c6f98aacc546f6cec5468a07b7b153ab564a57b9" - integrity sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg== - dependencies: - has-symbols "^1.0.1" - -is-regex@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.2.tgz#81c8ebde4db142f2cf1c53fc86d6a45788266251" - integrity sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg== - dependencies: - call-bind "^1.0.2" - has-symbols "^1.0.1" - -is-regex@~1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" - integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== - dependencies: - has "^1.0.3" - -is-retry-allowed@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" - integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== - -is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - -is-string@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" - integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" - integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== - dependencies: - has-symbols "^1.0.1" - -is-typedarray@^1.0.0, is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -is-url@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" - integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww== - -is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= - -is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= - -isarray@1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - -isurl@^1.0.0-alpha5: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" - integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w== - dependencies: - has-to-string-tag-x "^1.2.0" - is-object "^1.0.1" - -jest-diff@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.6.2.tgz#1aa7468b52c3a68d7d5c5fdcdfcd5e49bd164394" - integrity sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA== - dependencies: - chalk "^4.0.0" - diff-sequences "^26.6.2" - jest-get-type "^26.3.0" - pretty-format "^26.6.2" - -jest-get-type@^26.3.0: - version "26.3.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" - integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig== - -jest-haste-map@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.2.tgz#dd7e60fe7dc0e9f911a23d79c5ff7fb5c2cafeaa" - integrity sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w== - dependencies: - "@jest/types" "^26.6.2" - "@types/graceful-fs" "^4.1.2" - "@types/node" "*" - anymatch "^3.0.3" - fb-watchman "^2.0.0" - graceful-fs "^4.2.4" - jest-regex-util "^26.0.0" - jest-serializer "^26.6.2" - jest-util "^26.6.2" - jest-worker "^26.6.2" - micromatch "^4.0.2" - sane "^4.0.3" - walker "^1.0.7" - optionalDependencies: - fsevents "^2.1.2" - -jest-matcher-utils@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz#8e6fd6e863c8b2d31ac6472eeb237bc595e53e7a" - integrity sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw== - dependencies: - chalk "^4.0.0" - jest-diff "^26.6.2" - jest-get-type "^26.3.0" - pretty-format "^26.6.2" - -jest-message-util@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-26.6.2.tgz#58173744ad6fc0506b5d21150b9be56ef001ca07" - integrity sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA== - dependencies: - "@babel/code-frame" "^7.0.0" - "@jest/types" "^26.6.2" - "@types/stack-utils" "^2.0.0" - chalk "^4.0.0" - graceful-fs "^4.2.4" - micromatch "^4.0.2" - pretty-format "^26.6.2" - slash "^3.0.0" - stack-utils "^2.0.2" - -jest-pnp-resolver@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" - integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== - -jest-regex-util@^26.0.0: - version "26.0.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" - integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== - -jest-resolve@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-26.6.2.tgz#a3ab1517217f469b504f1b56603c5bb541fbb507" - integrity sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ== - dependencies: - "@jest/types" "^26.6.2" - chalk "^4.0.0" - graceful-fs "^4.2.4" - jest-pnp-resolver "^1.2.2" - jest-util "^26.6.2" - read-pkg-up "^7.0.1" - resolve "^1.18.1" - slash "^3.0.0" - -jest-serializer@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-26.6.2.tgz#d139aafd46957d3a448f3a6cdabe2919ba0742d1" - integrity sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g== - dependencies: - "@types/node" "*" - graceful-fs "^4.2.4" - -jest-snapshot@^26.5.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-26.6.2.tgz#f3b0af1acb223316850bd14e1beea9837fb39c84" - integrity sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og== - dependencies: - "@babel/types" "^7.0.0" - "@jest/types" "^26.6.2" - "@types/babel__traverse" "^7.0.4" - "@types/prettier" "^2.0.0" - chalk "^4.0.0" - expect "^26.6.2" - graceful-fs "^4.2.4" - jest-diff "^26.6.2" - jest-get-type "^26.3.0" - jest-haste-map "^26.6.2" - jest-matcher-utils "^26.6.2" - jest-message-util "^26.6.2" - jest-resolve "^26.6.2" - natural-compare "^1.4.0" - pretty-format "^26.6.2" - semver "^7.3.2" - -jest-util@^26.5.2, jest-util@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1" - integrity sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q== - dependencies: - "@jest/types" "^26.6.2" - "@types/node" "*" - chalk "^4.0.0" - graceful-fs "^4.2.4" - is-ci "^2.0.0" - micromatch "^4.0.2" - -jest-worker@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" - integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^7.0.0" - -js-sha3@0.5.7, js-sha3@^0.5.7: - version "0.5.7" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" - integrity sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc= - -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@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-tokens@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" - integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= - -js-yaml@3.13.1: - version "3.13.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" - integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -js-yaml@^3.12.0, js-yaml@^3.13.0, js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -jsesc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" - integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s= - -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= - -json-buffer@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" - integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= - -json-parse-better-errors@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -json-parse-even-better-errors@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json-rpc-engine@^3.4.0, json-rpc-engine@^3.6.0: - version "3.8.0" - resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-3.8.0.tgz#9d4ff447241792e1d0a232f6ef927302bb0c62a9" - integrity sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA== - dependencies: - async "^2.0.1" - babel-preset-env "^1.7.0" - babelify "^7.3.0" - json-rpc-error "^2.0.0" - promise-to-callback "^1.0.0" - safe-event-emitter "^1.0.1" - -json-rpc-error@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/json-rpc-error/-/json-rpc-error-2.0.0.tgz#a7af9c202838b5e905c7250e547f1aff77258a02" - integrity sha1-p6+cICg4tekFxyUOVH8a/3cligI= - dependencies: - inherits "^2.0.1" - -json-rpc-random-id@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz#ba49d96aded1444dbb8da3d203748acbbcdec8c8" - integrity sha1-uknZat7RRE27jaPSA3SKy7zeyMg= - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= - -json-stable-stringify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= - dependencies: - jsonify "~0.0.0" - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - -json5@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" - integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= - -jsonfile@^2.1.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" - integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug= - 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 sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= - optionalDependencies: - graceful-fs "^4.1.6" - -jsonify@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -keccak@3.0.1, keccak@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.1.tgz#ae30a0e94dbe43414f741375cff6d64c8bea0bff" - integrity sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA== - dependencies: - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - -keyv@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" - integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== - dependencies: - json-buffer "3.0.0" - -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== - -kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -klaw-sync@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/klaw-sync/-/klaw-sync-6.0.0.tgz#1fd2cfd56ebb6250181114f0a581167099c2b28c" - integrity sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ== - dependencies: - graceful-fs "^4.1.11" - -klaw@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" - integrity sha1-QIhDO0azsbolnXh4XY6W9zugJDk= - optionalDependencies: - graceful-fs "^4.1.9" - -lcid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= - dependencies: - invert-kv "^1.0.0" - -level-codec@^9.0.0: - version "9.0.2" - resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-9.0.2.tgz#fd60df8c64786a80d44e63423096ffead63d8cbc" - integrity sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ== - dependencies: - buffer "^5.6.0" - -level-codec@~7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-7.0.1.tgz#341f22f907ce0f16763f24bddd681e395a0fb8a7" - integrity sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ== - -level-concat-iterator@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz#1d1009cf108340252cb38c51f9727311193e6263" - integrity sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw== - -level-errors@^1.0.3: - version "1.1.2" - resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.1.2.tgz#4399c2f3d3ab87d0625f7e3676e2d807deff404d" - integrity sha512-Sw/IJwWbPKF5Ai4Wz60B52yj0zYeqzObLh8k1Tk88jVmD51cJSKWSYpRyhVIvFzZdvsPqlH5wfhp/yxdsaQH4w== - dependencies: - errno "~0.1.1" - -level-errors@^2.0.0, level-errors@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-2.0.1.tgz#2132a677bf4e679ce029f517c2f17432800c05c8" - integrity sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw== - dependencies: - errno "~0.1.1" - -level-errors@~1.0.3: - version "1.0.5" - resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.0.5.tgz#83dbfb12f0b8a2516bdc9a31c4876038e227b859" - integrity sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig== - dependencies: - errno "~0.1.1" - -level-iterator-stream@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-2.0.3.tgz#ccfff7c046dcf47955ae9a86f46dfa06a31688b4" - integrity sha512-I6Heg70nfF+e5Y3/qfthJFexhRw/Gi3bIymCoXAlijZdAcLaPuWSJs3KXyTYf23ID6g0o2QF62Yh+grOXY3Rig== - dependencies: - inherits "^2.0.1" - readable-stream "^2.0.5" - xtend "^4.0.0" - -level-iterator-stream@~1.3.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz#e43b78b1a8143e6fa97a4f485eb8ea530352f2ed" - integrity sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0= - dependencies: - inherits "^2.0.1" - level-errors "^1.0.3" - readable-stream "^1.0.33" - xtend "^4.0.0" - -level-iterator-stream@~3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-3.0.1.tgz#2c98a4f8820d87cdacab3132506815419077c730" - integrity sha512-nEIQvxEED9yRThxvOrq8Aqziy4EGzrxSZK+QzEFAVuJvQ8glfyZ96GB6BoI4sBbLfjMXm2w4vu3Tkcm9obcY0g== - dependencies: - inherits "^2.0.1" - readable-stream "^2.3.6" - xtend "^4.0.0" - -level-iterator-stream@~4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz#7ceba69b713b0d7e22fcc0d1f128ccdc8a24f79c" - integrity sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q== - dependencies: - inherits "^2.0.4" - readable-stream "^3.4.0" - xtend "^4.0.2" - -level-mem@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/level-mem/-/level-mem-3.0.1.tgz#7ce8cf256eac40f716eb6489654726247f5a89e5" - integrity sha512-LbtfK9+3Ug1UmvvhR2DqLqXiPW1OJ5jEh0a3m9ZgAipiwpSxGj/qaVVy54RG5vAQN1nCuXqjvprCuKSCxcJHBg== - dependencies: - level-packager "~4.0.0" - memdown "~3.0.0" - -level-mem@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/level-mem/-/level-mem-5.0.1.tgz#c345126b74f5b8aa376dc77d36813a177ef8251d" - integrity sha512-qd+qUJHXsGSFoHTziptAKXoLX87QjR7v2KMbqncDXPxQuCdsQlzmyX+gwrEHhlzn08vkf8TyipYyMmiC6Gobzg== - dependencies: - level-packager "^5.0.3" - memdown "^5.0.0" - -level-packager@^5.0.3: - version "5.1.1" - resolved "https://registry.yarnpkg.com/level-packager/-/level-packager-5.1.1.tgz#323ec842d6babe7336f70299c14df2e329c18939" - integrity sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ== - dependencies: - encoding-down "^6.3.0" - levelup "^4.3.2" - -level-packager@~4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/level-packager/-/level-packager-4.0.1.tgz#7e7d3016af005be0869bc5fa8de93d2a7f56ffe6" - integrity sha512-svCRKfYLn9/4CoFfi+d8krOtrp6RoX8+xm0Na5cgXMqSyRru0AnDYdLl+YI8u1FyS6gGZ94ILLZDE5dh2but3Q== - dependencies: - encoding-down "~5.0.0" - levelup "^3.0.0" - -level-post@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/level-post/-/level-post-1.0.7.tgz#19ccca9441a7cc527879a0635000f06d5e8f27d0" - integrity sha512-PWYqG4Q00asOrLhX7BejSajByB4EmG2GaKHfj3h5UmmZ2duciXLPGYWIjBzLECFWUGOZWlm5B20h/n3Gs3HKew== - dependencies: - ltgt "^2.1.2" - -level-sublevel@6.6.4: - version "6.6.4" - resolved "https://registry.yarnpkg.com/level-sublevel/-/level-sublevel-6.6.4.tgz#f7844ae893919cd9d69ae19d7159499afd5352ba" - integrity sha512-pcCrTUOiO48+Kp6F1+UAzF/OtWqLcQVTVF39HLdZ3RO8XBoXt+XVPKZO1vVr1aUoxHZA9OtD2e1v7G+3S5KFDA== - dependencies: - bytewise "~1.1.0" - level-codec "^9.0.0" - level-errors "^2.0.0" - level-iterator-stream "^2.0.3" - ltgt "~2.1.1" - pull-defer "^0.2.2" - pull-level "^2.0.3" - pull-stream "^3.6.8" - typewiselite "~1.0.0" - xtend "~4.0.0" - -level-supports@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-1.0.1.tgz#2f530a596834c7301622521988e2c36bb77d122d" - integrity sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg== - dependencies: - xtend "^4.0.2" - -level-ws@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-0.0.0.tgz#372e512177924a00424b0b43aef2bb42496d228b" - integrity sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos= - dependencies: - readable-stream "~1.0.15" - xtend "~2.1.1" - -level-ws@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-1.0.0.tgz#19a22d2d4ac57b18cc7c6ecc4bd23d899d8f603b" - integrity sha512-RXEfCmkd6WWFlArh3X8ONvQPm8jNpfA0s/36M4QzLqrLEIt1iJE9WBHLZ5vZJK6haMjJPJGJCQWfjMNnRcq/9Q== - dependencies: - inherits "^2.0.3" - readable-stream "^2.2.8" - xtend "^4.0.1" - -level-ws@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-2.0.0.tgz#207a07bcd0164a0ec5d62c304b4615c54436d339" - integrity sha512-1iv7VXx0G9ec1isqQZ7y5LmoZo/ewAsyDHNA8EFDW5hqH2Kqovm33nSFkSdnLLAK+I5FlT+lo5Cw9itGe+CpQA== - dependencies: - inherits "^2.0.3" - readable-stream "^3.1.0" - xtend "^4.0.1" - -levelup@3.1.1, levelup@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/levelup/-/levelup-3.1.1.tgz#c2c0b3be2b4dc316647c53b42e2f559e232d2189" - integrity sha512-9N10xRkUU4dShSRRFTBdNaBxofz+PGaIZO962ckboJZiNmLuhVT6FZ6ZKAsICKfUBO76ySaYU6fJWX/jnj3Lcg== - dependencies: - deferred-leveldown "~4.0.0" - level-errors "~2.0.0" - level-iterator-stream "~3.0.0" - xtend "~4.0.0" - -levelup@^1.2.1: - version "1.3.9" - resolved "https://registry.yarnpkg.com/levelup/-/levelup-1.3.9.tgz#2dbcae845b2bb2b6bea84df334c475533bbd82ab" - integrity sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ== - dependencies: - deferred-leveldown "~1.2.1" - level-codec "~7.0.0" - level-errors "~1.0.3" - level-iterator-stream "~1.3.0" - prr "~1.0.1" - semver "~5.4.1" - xtend "~4.0.0" - -levelup@^4.3.2: - version "4.4.0" - resolved "https://registry.yarnpkg.com/levelup/-/levelup-4.4.0.tgz#f89da3a228c38deb49c48f88a70fb71f01cafed6" - 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" - -levn@^0.3.0, levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -lines-and-columns@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" - integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= - -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= - 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" - -lodash.assign@^4.0.3, lodash.assign@^4.0.6: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" - integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc= - -lodash@4.17.20, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.4: - version "4.17.20" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" - integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== - -log-symbols@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" - integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== - dependencies: - chalk "^2.0.1" - -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" - -looper@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/looper/-/looper-2.0.0.tgz#66cd0c774af3d4fedac53794f742db56da8f09ec" - integrity sha1-Zs0Md0rz1P7axTeU90LbVtqPCew= - -looper@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/looper/-/looper-3.0.0.tgz#2efa54c3b1cbaba9b94aee2e5914b0be57fbb749" - integrity sha1-LvpUw7HLq6m5Su4uWRSwvlf7t0k= - -loose-envify@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" - integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== - -lowercase-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" - integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== - -lru-cache@5.1.1, lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - -lru-cache@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-3.2.0.tgz#71789b3b7f5399bec8565dda38aa30d2a097efee" - integrity sha1-cXibO39Tmb7IVl3aOKow0qCX7+4= - dependencies: - pseudomap "^1.0.1" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -lru_map@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd" - integrity sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0= - -ltgt@^2.1.2, ltgt@~2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5" - integrity sha1-81ypHEk/e3PaDgdJUwTxezH4fuU= - -ltgt@~2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.1.3.tgz#10851a06d9964b971178441c23c9e52698eece34" - integrity sha1-EIUaBtmWS5cReEQcI8nlJpjuzjQ= - -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== - -makeerror@1.0.x: - version "1.0.11" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" - integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw= - dependencies: - tmpl "1.0.x" - -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= - -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= - dependencies: - object-visit "^1.0.0" - -mcl-wasm@^0.7.1: - version "0.7.6" - resolved "https://registry.yarnpkg.com/mcl-wasm/-/mcl-wasm-0.7.6.tgz#c1789ebda5565d49b77d2ee195ff3e4d282f1554" - integrity sha512-cbRl3sUOkBeRY2hsM4t1EIln2TIdQBkSiTOqNTv/4Hu5KOECnMWCgjIf+a9Ebunyn22VKqkMF3zj6ejRzz7YBw== - -md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= - -memdown@^1.0.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/memdown/-/memdown-1.4.1.tgz#b4e4e192174664ffbae41361aa500f3119efe215" - integrity sha1-tOThkhdGZP+65BNhqlAPMRnv4hU= - dependencies: - abstract-leveldown "~2.7.1" - functional-red-black-tree "^1.0.1" - immediate "^3.2.3" - inherits "~2.0.1" - ltgt "~2.2.0" - safe-buffer "~5.1.1" - -memdown@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/memdown/-/memdown-5.1.0.tgz#608e91a9f10f37f5b5fe767667a8674129a833cb" - 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" - -memdown@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/memdown/-/memdown-3.0.0.tgz#93aca055d743b20efc37492e9e399784f2958309" - integrity sha512-tbV02LfZMWLcHcq4tw++NuqMO+FZX8tNJEiD2aNRm48ZZusVg5N8NART+dmBkepJVye986oixErf7jfXboMGMA== - dependencies: - abstract-leveldown "~5.0.0" - functional-red-black-tree "~1.0.1" - immediate "~3.2.3" - inherits "~2.0.1" - ltgt "~2.2.0" - safe-buffer "~5.1.1" - -memorystream@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" - integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI= - -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -merkle-patricia-tree@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-3.0.0.tgz#448d85415565df72febc33ca362b8b614f5a58f8" - integrity sha512-soRaMuNf/ILmw3KWbybaCjhx86EYeBbD8ph0edQCTed0JN/rxDt1EBN52Ajre3VyGo+91f8+/rfPIRQnnGMqmQ== - dependencies: - async "^2.6.1" - ethereumjs-util "^5.2.0" - level-mem "^3.0.1" - level-ws "^1.0.0" - readable-stream "^3.0.6" - rlp "^2.0.0" - semaphore ">=1.0.1" - -merkle-patricia-tree@^2.1.2, merkle-patricia-tree@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz#982ca1b5a0fde00eed2f6aeed1f9152860b8208a" - integrity sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g== - dependencies: - async "^1.4.2" - ethereumjs-util "^5.0.0" - level-ws "0.0.0" - levelup "^1.2.1" - memdown "^1.0.0" - readable-stream "^2.0.0" - rlp "^2.0.0" - semaphore ">=1.0.1" - -merkle-patricia-tree@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-4.1.0.tgz#010636c4cfd68682df33a2e3186b7d0be7b98b9d" - integrity sha512-vmP1J7FwIpprFMVjjSMM1JAwFce85Q+tp0TYIedYv8qaMh2oLUZ3ETXn9wbgi9S6elySzKzGa+Ai6VNKGEwSlg== - dependencies: - "@types/levelup" "^4.3.0" - ethereumjs-util "^7.0.8" - level-mem "^5.0.1" - level-ws "^2.0.0" - readable-stream "^3.6.0" - rlp "^2.2.3" - semaphore-async-await "^1.5.1" - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= - -micromatch@^3.1.4: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - -micromatch@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" - integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== - dependencies: - braces "^3.0.1" - picomatch "^2.0.5" - -miller-rabin@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" - integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== - dependencies: - bn.js "^4.0.0" - brorand "^1.0.1" - -mime-db@1.44.0: - version "1.44.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" - integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== - -mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.19, mime-types@~2.1.24: - version "2.1.27" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" - integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== - dependencies: - mime-db "1.44.0" - -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -mimic-fn@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" - integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== - -mimic-response@^1.0.0, mimic-response@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" - integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== - -min-document@^2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" - integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= - dependencies: - dom-walk "^0.1.0" - -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= - -minimatch@3.0.4, 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" - -minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5, minimist@~1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - -minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" - integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - -minizlib@^1.2.1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" - integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== - dependencies: - minipass "^2.9.0" - -mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" - integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - -mkdirp-promise@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz#e9b8f68e552c68a9c1713b84883f7a1dd039b8a1" - integrity sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE= - dependencies: - mkdirp "*" - -mkdirp@*: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - -mkdirp@0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.4.tgz#fd01504a6797ec5c9be81ff43d204961ed64a512" - integrity sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw== - dependencies: - minimist "^1.2.5" - -mkdirp@0.5.5, mkdirp@^0.5.0, mkdirp@^0.5.1: - 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" - -mnemonist@^0.38.0: - version "0.38.3" - resolved "https://registry.yarnpkg.com/mnemonist/-/mnemonist-0.38.3.tgz#35ec79c1c1f4357cfda2fe264659c2775ccd7d9d" - integrity sha512-2K9QYubXx/NAjv4VLq1d1Ly8pWNC5L3BrixtdkyTegXWJIqY+zLNDhhX/A+ZwWt70tB1S8H4BE8FLYEFyNoOBw== - dependencies: - obliterator "^1.6.1" - -mocha-chai-jest-snapshot@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/mocha-chai-jest-snapshot/-/mocha-chai-jest-snapshot-1.1.1.tgz#7e49f20d0c12e6792d7f7da2e4ee0c38950571cc" - integrity sha512-52GyyqRD/cI8AIiMTQzizKmLeKQvZRBLwWOHwlwytUKPnWSNpRy1MkIcJIlgUrs5ocrjujOWwtKwyVkLWT/DFQ== - dependencies: - "@jest/test-result" "^26.5.2" - chalk "^4.1.0" - find-package-json "^1.2.0" - jest-snapshot "^26.5.2" - jest-util "^26.5.2" - slash "^3.0.0" - yargs "^16.0.3" - -mocha@^6.2.2: - version "6.2.3" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-6.2.3.tgz#e648432181d8b99393410212664450a4c1e31912" - integrity sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg== - dependencies: - ansi-colors "3.2.3" - browser-stdout "1.3.1" - 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 "2.2.0" - minimatch "3.0.4" - mkdirp "0.5.4" - ms "2.1.1" - node-environment-flags "1.0.5" - 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@^7.1.2: - 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" - -mock-fs@^4.1.0: - version "4.13.0" - resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.13.0.tgz#31c02263673ec3789f90eb7b6963676aa407a598" - integrity sha512-DD0vOdofJdoaRNtnWcrXe6RQbpHkPPmtqGq14uRX0F8ZKJ5nv89CVTYl/BZdppDxBDaV0hl75htg3abpEWlPZA== - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -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.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -multibase@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.7.0.tgz#1adfc1c50abe05eefeb5091ac0c2728d6b84581b" - integrity sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg== - dependencies: - base-x "^3.0.8" - buffer "^5.5.0" - -multibase@~0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.6.1.tgz#b76df6298536cc17b9f6a6db53ec88f85f8cc12b" - integrity sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw== - dependencies: - base-x "^3.0.8" - buffer "^5.5.0" - -multicodec@^0.5.5: - version "0.5.7" - resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-0.5.7.tgz#1fb3f9dd866a10a55d226e194abba2dcc1ee9ffd" - integrity sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA== - dependencies: - varint "^5.0.0" - -multicodec@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-1.0.4.tgz#46ac064657c40380c28367c90304d8ed175a714f" - integrity sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg== - dependencies: - buffer "^5.6.0" - varint "^5.0.0" - -multihashes@^0.4.15, multihashes@~0.4.15: - version "0.4.21" - resolved "https://registry.yarnpkg.com/multihashes/-/multihashes-0.4.21.tgz#dc02d525579f334a7909ade8a122dabb58ccfcb5" - integrity sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw== - dependencies: - buffer "^5.5.0" - multibase "^0.7.0" - varint "^5.0.0" - -mute-stream@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" - integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= - -nano-json-stream-parser@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f" - integrity sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18= - -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= - -negotiator@0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" - integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== - -next-tick@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" - integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= - -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - -node-addon-api@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" - integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== - -node-environment-flags@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.5.tgz#fa930275f5bf5dae188d6192b24b4c8bbac3d76a" - integrity sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ== - dependencies: - object.getownpropertydescriptors "^2.0.3" - semver "^5.7.0" - -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-fetch@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" - integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U= - -node-fetch@^2.6.0: - version "2.6.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" - integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== - -node-fetch@~1.7.1: - version "1.7.3" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" - integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== - dependencies: - encoding "^0.1.11" - is-stream "^1.0.1" - -node-gyp-build@^4.2.0: - version "4.2.3" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.2.3.tgz#ce6277f853835f718829efb47db20f3e4d9c4739" - integrity sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg== - -node-int64@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" - integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= - -nofilter@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-1.0.4.tgz#78d6f4b6a613e7ced8b015cec534625f7667006e" - integrity sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA== - -normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= - dependencies: - remove-trailing-separator "^1.0.1" - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -normalize-url@^4.1.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" - integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= - dependencies: - path-key "^2.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -number-to-bn@1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0" - integrity sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA= - dependencies: - bn.js "4.11.6" - strip-hex-prefix "1.0.0" - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -object-assign@^4, object-assign@^4.0.0, object-assign@^4.1.0, object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-inspect@^1.8.0, object-inspect@^1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a" - integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw== - -object-inspect@~1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" - integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== - -object-is@^1.0.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.4.tgz#63d6c83c00a43f4cbc9434eb9757c8a5b8565068" - integrity sha512-1ZvAZ4wlF7IyPVOcE1Omikt7UpaFlOQq0HlSti+ZvDH3UiD2brwGMwDbyV43jao2bKJ+4+WdPJHSd7kgzKYVqg== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - -object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object-keys@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" - integrity sha1-KKaq50KN0sOpLz2V8hM13SBOAzY= - -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= - dependencies: - isobject "^3.0.0" - -object.assign@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" - 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.1, object.assign@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" - 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" - -object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.1.tgz#0dfda8d108074d9c563e80490c883b6661091544" - integrity sha512-6DtXgZ/lIZ9hqx4GtZETobXLR/ZLaa0aqV0kzbn80Rf8Z2e/XFnhA0I7p07N2wH8bBBltr2xQPi6sbKWAY2Eng== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - es-abstract "^1.18.0-next.1" - -object.getownpropertydescriptors@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz#1bd63aeacf0d5d2d2f31b5e393b03a7c601a23f7" - integrity sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.18.0-next.2" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= - dependencies: - isobject "^3.0.1" - -obliterator@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-1.6.1.tgz#dea03e8ab821f6c4d96a299e17aef6a3af994ef3" - integrity sha512-9WXswnqINnnhOG/5SLimUlzuU1hFJUc8zkwyD59Sd+dPOMf05PmnYG/d6Q7HZ+KmgkZJa1PxRso6QdM3sTNHig== - -oboe@2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.4.tgz#20c88cdb0c15371bb04119257d4fdd34b0aa49f6" - integrity sha1-IMiM2wwVNxuwQRklfU/dNLCqSfY= - dependencies: - http-https "^1.0.0" - -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= - dependencies: - ee-first "1.1.1" - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -onetime@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" - integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= - dependencies: - mimic-fn "^1.0.0" - -optionator@^0.8.2: - 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" - -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - -os-locale@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" - integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= - dependencies: - lcid "^1.0.0" - -os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -p-cancelable@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" - integrity sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw== - -p-cancelable@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" - integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -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-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= - 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-timeout@^1.1.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386" - integrity sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y= - dependencies: - p-finally "^1.0.0" - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= - -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-asn1@^5.0.0, parse-asn1@^5.1.5: - version "5.1.6" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" - integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== - dependencies: - asn1.js "^5.2.0" - browserify-aes "^1.0.0" - evp_bytestokey "^1.0.0" - pbkdf2 "^3.0.3" - safe-buffer "^5.1.1" - -parse-headers@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.3.tgz#5e8e7512383d140ba02f0c7aa9f49b4399c92515" - integrity sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA== - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= - dependencies: - error-ex "^1.2.0" - -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -parse-json@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.1.0.tgz#f96088cdf24a8faa9aea9a009f2d9d942c999646" - integrity sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ== - 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" - -parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= - -patch-package@6.2.2, patch-package@^6.2.2: - version "6.2.2" - resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.2.2.tgz#71d170d650c65c26556f0d0fbbb48d92b6cc5f39" - integrity sha512-YqScVYkVcClUY0v8fF0kWOjDYopzIM8e3bj/RU1DPeEF14+dCGm6UeOYm4jvCyxqIEQ5/eJzmbWfDWnUleFNMg== - dependencies: - "@yarnpkg/lockfile" "^1.1.0" - chalk "^2.4.2" - cross-spawn "^6.0.5" - find-yarn-workspace-root "^1.2.1" - fs-extra "^7.0.1" - is-ci "^2.0.0" - klaw-sync "^6.0.0" - minimist "^1.2.0" - rimraf "^2.6.3" - semver "^5.6.0" - slash "^2.0.0" - tmp "^0.0.33" - -path-browserify@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" - integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= - dependencies: - pinkie-promise "^2.0.0" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-is-inside@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= - -path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - -path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== - -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= - -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -pathval@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" - integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA= - -pbkdf2@^3.0.17, pbkdf2@^3.0.3, pbkdf2@^3.0.9: - version "3.1.1" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" - integrity sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg== - 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 sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - -picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: - version "2.2.2" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" - integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== - -pify@^2.0.0, pify@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= - -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= - -postinstall-postinstall@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz#4f7f77441ef539d1512c40bd04c71b06a4704ca3" - integrity sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ== - -precond@0.2: - version "0.2.3" - resolved "https://registry.yarnpkg.com/precond/-/precond-0.2.3.tgz#aa9591bcaa24923f1e0f4849d240f47efc1075ac" - integrity sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw= - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= - -prepend-http@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= - -prepend-http@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" - integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= - -prettier-linter-helpers@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" - integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== - dependencies: - fast-diff "^1.1.2" - -prettier-plugin-solidity@^1.0.0-alpha.59: - version "1.0.0-beta.2" - resolved "https://registry.yarnpkg.com/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-beta.2.tgz#312a429cd0026b2cbdbe0ad8ef30c4f8db1f74b2" - integrity sha512-afn8Q0E0fY2I26fbagiBo1XRe7Cv/vs3t/N5Xbndzjgln+TXrtNxgWzhdZcFoZLN92WrFbxqqDoP6Lk5L80Fmw== - dependencies: - "@solidity-parser/parser" "^0.10.1" - dir-to-object "^2.0.0" - emoji-regex "^9.0.0" - escape-string-regexp "^4.0.0" - prettier "^2.0.5" - semver "^7.3.2" - solidity-comments-extractor "^0.0.4" - string-width "^4.2.0" - -prettier@^1.14.3: - version "1.19.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" - integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== - -prettier@^2.0.5, prettier@^2.1.2: - version "2.2.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" - integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== - -pretty-format@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93" - integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg== - dependencies: - "@jest/types" "^26.6.2" - ansi-regex "^5.0.0" - ansi-styles "^4.0.0" - react-is "^17.0.1" - -printj@~1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222" - integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ== - -private@^0.1.6, private@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" - integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -process@^0.11.10: - version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" - integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= - -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - -promise-to-callback@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/promise-to-callback/-/promise-to-callback-1.0.0.tgz#5d2a749010bfb67d963598fcd3960746a68feef7" - integrity sha1-XSp0kBC/tn2WNZj805YHRqaP7vc= - dependencies: - is-fn "^1.0.0" - set-immediate-shim "^1.0.1" - -proxy-addr@~2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" - integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== - dependencies: - forwarded "~0.1.2" - ipaddr.js "1.9.1" - -prr@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" - integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= - -pseudomap@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= - -psl@^1.1.28: - version "1.8.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== - -public-encrypt@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" - integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== - dependencies: - bn.js "^4.1.0" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - parse-asn1 "^5.0.0" - randombytes "^2.0.1" - safe-buffer "^5.1.2" - -pull-cat@^1.1.9: - version "1.1.11" - resolved "https://registry.yarnpkg.com/pull-cat/-/pull-cat-1.1.11.tgz#b642dd1255da376a706b6db4fa962f5fdb74c31b" - integrity sha1-tkLdElXaN2pwa220+pYvX9t0wxs= - -pull-defer@^0.2.2: - version "0.2.3" - resolved "https://registry.yarnpkg.com/pull-defer/-/pull-defer-0.2.3.tgz#4ee09c6d9e227bede9938db80391c3dac489d113" - integrity sha512-/An3KE7mVjZCqNhZsr22k1Tx8MACnUnHZZNPSJ0S62td8JtYr/AiRG42Vz7Syu31SoTLUzVIe61jtT/pNdjVYA== - -pull-level@^2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pull-level/-/pull-level-2.0.4.tgz#4822e61757c10bdcc7cf4a03af04c92734c9afac" - integrity sha512-fW6pljDeUThpq5KXwKbRG3X7Ogk3vc75d5OQU/TvXXui65ykm+Bn+fiktg+MOx2jJ85cd+sheufPL+rw9QSVZg== - dependencies: - level-post "^1.0.7" - pull-cat "^1.1.9" - pull-live "^1.0.1" - pull-pushable "^2.0.0" - pull-stream "^3.4.0" - pull-window "^2.1.4" - stream-to-pull-stream "^1.7.1" - -pull-live@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/pull-live/-/pull-live-1.0.1.tgz#a4ecee01e330155e9124bbbcf4761f21b38f51f5" - integrity sha1-pOzuAeMwFV6RJLu89HYfIbOPUfU= - dependencies: - pull-cat "^1.1.9" - pull-stream "^3.4.0" - -pull-pushable@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/pull-pushable/-/pull-pushable-2.2.0.tgz#5f2f3aed47ad86919f01b12a2e99d6f1bd776581" - integrity sha1-Xy867UethpGfAbEqLpnW8b13ZYE= - -pull-stream@^3.2.3, pull-stream@^3.4.0, pull-stream@^3.6.8: - version "3.6.14" - resolved "https://registry.yarnpkg.com/pull-stream/-/pull-stream-3.6.14.tgz#529dbd5b86131f4a5ed636fdf7f6af00781357ee" - integrity sha512-KIqdvpqHHaTUA2mCYcLG1ibEbu/LCKoJZsBWyv9lSYtPkJPBq8m3Hxa103xHi6D2thj5YXa0TqK3L3GUkwgnew== - -pull-window@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/pull-window/-/pull-window-2.1.4.tgz#fc3b86feebd1920c7ae297691e23f705f88552f0" - integrity sha1-/DuG/uvRkgx64pdpHiP3BfiFUvA= - dependencies: - looper "^2.0.0" - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= - -punycode@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" - integrity sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0= - -punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -qs@6.7.0: - version "6.7.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" - integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== - -qs@^6.7.0: - version "6.9.4" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.4.tgz#9090b290d1f91728d3c22e54843ca44aea5ab687" - integrity sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ== - -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== - -query-string@^5.0.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" - integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== - dependencies: - decode-uri-component "^0.2.0" - object-assign "^4.1.0" - strict-uri-encode "^1.0.0" - -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= - -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.0.6, randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -randomfill@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" - integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== - dependencies: - randombytes "^2.0.5" - safe-buffer "^5.1.0" - -range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -raw-body@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" - integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== - dependencies: - bytes "3.1.0" - http-errors "1.7.2" - iconv-lite "0.4.24" - unpipe "1.0.0" - -raw-body@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" - integrity sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA== - dependencies: - bytes "3.1.0" - http-errors "1.7.3" - iconv-lite "0.4.24" - unpipe "1.0.0" - -react-is@^17.0.1: - version "17.0.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.1.tgz#5b3531bd76a645a4c9fb6e693ed36419e3301339" - integrity sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA== - -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= - dependencies: - find-up "^1.0.0" - read-pkg "^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@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - -read-pkg@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" - 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@^1.0.33: - version "1.1.14" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" - integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.2.2, readable-stream@^2.2.8, readable-stream@^2.2.9, readable-stream@^2.3.6, readable-stream@~2.3.6: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.0.6, readable-stream@^3.1.0, readable-stream@^3.4.0, readable-stream@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readable-stream@~1.0.15: - version "1.0.34" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" - integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -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.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" - integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== - dependencies: - picomatch "^2.2.1" - -regenerate@^1.2.1: - version "1.4.2" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" - integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== - -regenerator-runtime@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" - integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== - -regenerator-transform@^0.10.0: - version "0.10.1" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" - integrity sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q== - dependencies: - babel-runtime "^6.18.0" - babel-types "^6.19.0" - private "^0.1.6" - -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - -regexp.prototype.flags@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75" - integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - -regexpp@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" - integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== - -regexpu-core@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" - integrity sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA= - dependencies: - regenerate "^1.2.1" - regjsgen "^0.2.0" - regjsparser "^0.1.4" - -regjsgen@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" - integrity sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc= - -regjsparser@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" - integrity sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw= - dependencies: - jsesc "~0.5.0" - -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= - -repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== - -repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= - -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= - dependencies: - is-finite "^1.0.0" - -request@^2.79.0, request@^2.85.0: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -require-from-string@^1.1.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418" - integrity sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg= - -require-from-string@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= - -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@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - integrity sha1-six699nWiBvItuZTM17rywoYh0g= - -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-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= - -resolve@1.17.0, resolve@~1.17.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" - integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== - dependencies: - path-parse "^1.0.6" - -resolve@^1.10.0, resolve@^1.18.1, resolve@^1.8.1: - version "1.19.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c" - integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg== - dependencies: - is-core-module "^2.1.0" - path-parse "^1.0.6" - -responselike@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" - integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= - dependencies: - lowercase-keys "^1.0.0" - -restore-cursor@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" - integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= - dependencies: - onetime "^2.0.0" - signal-exit "^3.0.2" - -resumer@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/resumer/-/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759" - integrity sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k= - dependencies: - through "~2.3.4" - -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== - -rimraf@2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== - dependencies: - glob "^7.1.3" - -rimraf@^2.2.8, rimraf@^2.6.3: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - -ripemd160@^2.0.0, ripemd160@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - -rlp@^2.0.0, rlp@^2.2.1, rlp@^2.2.2, rlp@^2.2.3, rlp@^2.2.4: - version "2.2.6" - resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.6.tgz#c80ba6266ac7a483ef1e69e8e2f056656de2fb2c" - integrity sha512-HAfAmL6SDYNWPUOJNrM500x4Thn4PZsEy5pijPh40U9WfNk0z15hUYzO9xVIMAdIHdFtD8CBDHd75Td1g36Mjg== - dependencies: - bn.js "^4.11.1" - -rsvp@^4.8.4: - version "4.8.5" - resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" - integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== - -run-async@^2.2.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" - integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== - -rustbn.js@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca" - integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA== - -rxjs@^6.4.0: - version "6.6.3" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.3.tgz#8ca84635c4daa900c0d3967a6ee7ac60271ee552" - integrity sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ== - dependencies: - tslib "^1.9.0" - -safe-buffer@5.1.2, 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-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-event-emitter@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/safe-event-emitter/-/safe-event-emitter-1.0.1.tgz#5b692ef22329ed8f69fdce607e50ca734f6f20af" - integrity sha512-e1wFe99A91XYYxoQbcq2ZJUWurxEyP8vfz7A7vuUe1s95q8r5ebraVaA1BukYJcpM6V16ugWoD9vngi8Ccu5fg== - dependencies: - events "^3.0.0" - -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= - dependencies: - ret "~0.1.10" - -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sane@^4.0.3: - version "4.1.0" - resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" - integrity sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA== - dependencies: - "@cnakazawa/watch" "^1.0.3" - anymatch "^2.0.0" - capture-exit "^2.0.0" - exec-sh "^0.3.2" - execa "^1.0.0" - fb-watchman "^2.0.0" - micromatch "^3.1.4" - minimist "^1.1.1" - walker "~1.0.5" - -scrypt-js@3.0.1, scrypt-js@^3.0.0, scrypt-js@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" - integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== - -scryptsy@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/scryptsy/-/scryptsy-1.2.1.tgz#a3225fa4b2524f802700761e2855bdf3b2d92163" - integrity sha1-oyJfpLJST4AnAHYeKFW987LZIWM= - dependencies: - pbkdf2 "^3.0.3" - -secp256k1@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.2.tgz#15dd57d0f0b9fdb54ac1fa1694f40e5e9a54f4a1" - integrity sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg== - dependencies: - elliptic "^6.5.2" - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - -seedrandom@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.1.tgz#eb3dde015bcf55df05a233514e5df44ef9dce083" - integrity sha512-1/02Y/rUeU1CJBAGLebiC5Lbo5FnB22gQbIFFYTLkwvp1xdABZJH1sn4ZT1MzXmPpzv+Rf/Lu2NcsLJiK4rcDg== - -semaphore-async-await@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/semaphore-async-await/-/semaphore-async-await-1.5.1.tgz#857bef5e3644601ca4b9570b87e9df5ca12974fa" - integrity sha1-hXvvXjZEYBykuVcLh+nfXKEpdPo= - -semaphore@>=1.0.1, semaphore@^1.0.3, semaphore@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/semaphore/-/semaphore-1.1.0.tgz#aaad8b86b20fe8e9b32b16dc2ee682a8cd26a8aa" - integrity sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA== - -"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -semver@^7.3.2: - version "7.3.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97" - integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw== - dependencies: - lru-cache "^6.0.0" - -semver@~5.4.1: - version "5.4.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" - integrity sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg== - -send@0.17.1: - version "0.17.1" - resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" - integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== - 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" - -serve-static@1.14.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" - integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.17.1" - -servify@^0.1.12: - version "0.1.12" - resolved "https://registry.yarnpkg.com/servify/-/servify-0.1.12.tgz#142ab7bee1f1d033b66d0707086085b17c06db95" - integrity sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw== - dependencies: - body-parser "^1.16.0" - cors "^2.8.1" - express "^4.14.0" - request "^2.79.0" - xhr "^2.3.3" - -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -set-immediate-shim@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" - integrity sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E= - -set-value@^2.0.0, set-value@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" - integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - -setimmediate@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= - -setprototypeof@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" - integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== - -sha.js@^2.4.0, sha.js@^2.4.8: - version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= - dependencies: - shebang-regex "^1.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= - -signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" - integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== - -simple-concat@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" - integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== - -simple-get@^2.7.0: - version "2.8.1" - resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.1.tgz#0e22e91d4575d87620620bc91308d57a77f44b5d" - integrity sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw== - dependencies: - decompress-response "^3.3.0" - once "^1.3.1" - simple-concat "^1.0.0" - -slash@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= - -slash@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" - integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== - -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@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" - integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== - dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" - -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - -solc@0.7.3: - version "0.7.3" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.7.3.tgz#04646961bd867a744f63d2b4e3c0701ffdc7d78a" - integrity sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA== - dependencies: - command-exists "^1.2.8" - commander "3.0.2" - follow-redirects "^1.12.1" - fs-extra "^0.30.0" - js-sha3 "0.8.0" - memorystream "^0.3.1" - require-from-string "^2.0.0" - semver "^5.5.0" - tmp "0.0.33" - -solc@^0.4.20: - version "0.4.26" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.26.tgz#5390a62a99f40806b86258c737c1cf653cc35cb5" - integrity sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA== - dependencies: - fs-extra "^0.30.0" - memorystream "^0.3.1" - require-from-string "^1.1.0" - semver "^5.3.0" - yargs "^4.7.1" - -solc@^0.6.3: - version "0.6.12" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.6.12.tgz#48ac854e0c729361b22a7483645077f58cba080e" - integrity sha512-Lm0Ql2G9Qc7yPP2Ba+WNmzw2jwsrd3u4PobHYlSOxaut3TtUbj9+5ZrT6f4DUpNPEoBaFUOEg9Op9C0mk7ge9g== - dependencies: - command-exists "^1.2.8" - commander "3.0.2" - fs-extra "^0.30.0" - js-sha3 "0.8.0" - memorystream "^0.3.1" - require-from-string "^2.0.0" - semver "^5.5.0" - tmp "0.0.33" - -solhint-plugin-prettier@^0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/solhint-plugin-prettier/-/solhint-plugin-prettier-0.0.5.tgz#e3b22800ba435cd640a9eca805a7f8bc3e3e6a6b" - integrity sha512-7jmWcnVshIrO2FFinIvDQmhQpfpS2rRRn3RejiYgnjIE68xO2bvrYvjqVNfrio4xH9ghOqn83tKuTzLjEbmGIA== - dependencies: - prettier-linter-helpers "^1.0.0" - -solhint@^3.2.1: - version "3.3.2" - resolved "https://registry.yarnpkg.com/solhint/-/solhint-3.3.2.tgz#ebd7270bb50fd378b427d7a6fc9f2a7fd00216c0" - integrity sha512-8tHCkIAk1axLLG6Qu2WIH3GgNABonj9eAWejJbov3o3ujkZQRNHeHU1cC4/Dmjsh3Om7UzFFeADUHu2i7ZJeiw== - dependencies: - "@solidity-parser/parser" "^0.8.2" - 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" - optionalDependencies: - prettier "^1.14.3" - -solidity-comments-extractor@^0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/solidity-comments-extractor/-/solidity-comments-extractor-0.0.4.tgz#ce420aef23641ffd0131c7d80ba85b6e1e42147e" - integrity sha512-58glBODwXIKMaQ7rfcJOrWtFQMMOK28tJ0/LcB5Xhu7WtAxk4UX2fpgKPuaL41XjMp/y0gAa1MTLqk018wuSzA== - -source-map-resolve@^0.5.0: - version "0.5.3" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" - integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== - dependencies: - atob "^2.1.2" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-support@0.5.12: - version "0.5.12" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599" - integrity sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-support@^0.4.15: - version "0.4.18" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" - integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== - dependencies: - source-map "^0.5.6" - -source-map-support@^0.5.13, source-map-support@^0.5.17: - version "0.5.19" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" - integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= - -source-map@^0.5.6, source-map@^0.5.7: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - -source-map@^0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.7" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz#e9c18a410e5ed7e12442a549fbd8afa767038d65" - integrity sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ== - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== - dependencies: - extend-shallow "^3.0.0" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - 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" - -stack-utils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.3.tgz#cd5f030126ff116b78ccb3c027fe302713b61277" - integrity sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw== - dependencies: - escape-string-regexp "^2.0.0" - -stacktrace-parser@^0.1.10: - version "0.1.10" - resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" - integrity sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg== - dependencies: - type-fest "^0.7.1" - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -"statuses@>= 1.5.0 < 2", statuses@~1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= - -stream-to-pull-stream@^1.7.1: - version "1.7.3" - resolved "https://registry.yarnpkg.com/stream-to-pull-stream/-/stream-to-pull-stream-1.7.3.tgz#4161aa2d2eb9964de60bfa1af7feaf917e874ece" - integrity sha512-6sNyqJpr5dIOQdgNy/xcDWwDuzAsAwVzhzrWlAPAQ7Lkjx/rv0wgvxEyKwTq6FmNd5rjTrELt/CLmaSw7crMGg== - dependencies: - looper "^3.0.0" - pull-stream "^3.2.3" - -strict-uri-encode@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" - integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2", string-width@^2.1.0: - 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: - version "4.2.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" - integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.0" - -string.prototype.trim@~1.2.1: - version "1.2.3" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.3.tgz#d23a22fde01c1e6571a7fadcb9be11decd8061a7" - integrity sha512-16IL9pIBA5asNOSukPfxX2W68BaBvxyiRK16H3RA/lWW9BDosh+w7f+LhomPHpXJ82QEe7w7/rY/S1CV97raLg== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - es-abstract "^1.18.0-next.1" - -string.prototype.trimend@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz#a22bd53cca5c7cf44d7c9d5c732118873d6cd18b" - integrity sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - -string.prototype.trimend@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" - integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -string.prototype.trimstart@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz#9b4cb590e123bb36564401d59824298de50fd5aa" - integrity sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - -string.prototype.trimstart@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" - integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - 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: - version "6.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" - integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== - dependencies: - ansi-regex "^5.0.0" - -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= - dependencies: - is-utf8 "^0.2.0" - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= - -strip-hex-prefix@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f" - integrity sha1-DF8VX+8RUTczd96du1iNoFUA428= - dependencies: - is-hex-prefixed "1.0.0" - -strip-json-comments@2.0.1, strip-json-comments@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - -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@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= - -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.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" - -swarm-js@^0.1.40: - version "0.1.40" - resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.40.tgz#b1bc7b6dcc76061f6c772203e004c11997e06b99" - integrity sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA== - 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" - -table@^5.2.3: - version "5.4.6" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" - integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== - dependencies: - ajv "^6.10.2" - lodash "^4.17.14" - slice-ansi "^2.1.0" - string-width "^3.0.0" - -tape@^4.6.3: - version "4.13.3" - resolved "https://registry.yarnpkg.com/tape/-/tape-4.13.3.tgz#51b3d91c83668c7a45b1a594b607dee0a0b46278" - integrity sha512-0/Y20PwRIUkQcTCSi4AASs+OANZZwqPKaipGCEwp10dQMipVvSZwUUCi01Y/OklIGyHKFhIcjock+DKnBfLAFw== - 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" - -tar@^4.0.2: - version "4.4.13" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" - integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== - 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" - -test-value@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/test-value/-/test-value-2.1.0.tgz#11da6ff670f3471a73b625ca4f3fdcf7bb748291" - integrity sha1-Edpv9nDzRxpztiXKTz/c97t0gpE= - dependencies: - array-back "^1.0.3" - typical "^2.6.0" - -testrpc@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/testrpc/-/testrpc-0.0.1.tgz#83e2195b1f5873aec7be1af8cbe6dcf39edb7aed" - integrity sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA== - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - -through2@^2.0.3: - version "2.0.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" - integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== - dependencies: - readable-stream "~2.3.6" - xtend "~4.0.1" - -through@^2.3.6, through@~2.3.4, through@~2.3.8: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - -timed-out@^4.0.0, timed-out@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" - integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= - -tmp@0.0.33, tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - -tmp@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877" - integrity sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw== - dependencies: - rimraf "^2.6.3" - -tmpl@1.0.x: - version "1.0.4" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" - integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= - -to-fast-properties@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" - integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= - -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 sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= - -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= - dependencies: - kind-of "^3.0.2" - -to-readable-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" - integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - -toidentifier@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" - integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== - -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-right@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" - integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= - -"true-case-path@^2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-2.2.1.tgz#c5bf04a5bbec3fd118be4084461b3a27c4d796bf" - integrity sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q== - -ts-essentials@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-1.0.4.tgz#ce3b5dade5f5d97cf69889c11bf7d2da8555b15a" - integrity sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ== - -ts-essentials@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-7.0.1.tgz#d205508cae0cdadfb73c89503140cf2228389e2d" - integrity sha512-8lwh3QJtIc1UWhkQtr9XuksXu3O0YQdEE5g79guDfhCaU1FWTDIEDZ1ZSx4HTHUmlJZ8L812j3BZQ4a0aOUkSA== - -ts-generator@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ts-generator/-/ts-generator-0.1.1.tgz#af46f2fb88a6db1f9785977e9590e7bcd79220ab" - integrity sha512-N+ahhZxTLYu1HNTQetwWcx3so8hcYbkKBHTr4b4/YgObFTIKkOSSsaa+nal12w8mfrJAyzJfETXawbNjSfP2gQ== - dependencies: - "@types/mkdirp" "^0.5.2" - "@types/prettier" "^2.1.1" - "@types/resolve" "^0.0.8" - chalk "^2.4.1" - glob "^7.1.2" - mkdirp "^0.5.1" - prettier "^2.1.2" - resolve "^1.8.1" - ts-essentials "^1.0.0" - -ts-node@^8.5.4: - version "8.10.2" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.10.2.tgz#eee03764633b1234ddd37f8db9ec10b75ec7fb8d" - integrity sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA== - dependencies: - arg "^4.1.0" - diff "^4.0.1" - make-error "^1.1.1" - source-map-support "^0.5.17" - yn "3.1.1" - -tslib@^1.9.0, tslib@^1.9.3: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - 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 sha1-4igPXoF/i/QnVlf9D5rr1E9aJ4Y= - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -tweetnacl-util@^0.15.0: - 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 sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - -tweetnacl@^1.0.0: - 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 sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= - 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.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" - integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ== - -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-is@~1.6.17, type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -type@^1.0.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" - integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== - -type@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/type/-/type-2.1.0.tgz#9bdc22c648cf8cf86dd23d32336a41cfb6475e3f" - integrity sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA== - -typechain@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/typechain/-/typechain-4.0.1.tgz#b40eaf5ede15588d97a4b9a5f85120f7ea1cf262" - integrity sha512-H/1VpRmplp1qhCTVLU9PCgzyVCQ7Lth7YvaaI1hTvT31IpWnLLNpDpQD4vXJGr26T9BsZ0ZIceOwieAbcoywXw== - 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 "^7.0.1" - ts-generator "^0.1.1" - -typedarray-to-buffer@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" - integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== - dependencies: - is-typedarray "^1.0.0" - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= - -typescript@^3.7.3: - version "3.9.7" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.7.tgz#98d600a5ebdc38f40cb277522f12dc800e9e25fa" - integrity sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw== - -typewise-core@^1.2, typewise-core@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/typewise-core/-/typewise-core-1.2.0.tgz#97eb91805c7f55d2f941748fa50d315d991ef195" - integrity sha1-l+uRgFx/VdL5QXSPpQ0xXZke8ZU= - -typewise@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/typewise/-/typewise-1.0.3.tgz#1067936540af97937cc5dcf9922486e9fa284651" - integrity sha1-EGeTZUCvl5N8xdz5kiSG6fooRlE= - dependencies: - typewise-core "^1.2.0" - -typewiselite@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typewiselite/-/typewiselite-1.0.0.tgz#c8882fa1bb1092c06005a97f34ef5c8508e3664e" - integrity sha1-yIgvobsQksBgBal/NO9chQjjZk4= - -typical@^2.6.0, typical@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/typical/-/typical-2.6.1.tgz#5c080e5d661cbbe38259d2e70a3c7253e873881d" - integrity sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0= - -ultron@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" - integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== - -unbox-primitive@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" - 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" - -underscore@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961" - integrity sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg== - -union-value@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" - integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^2.0.1" - -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - -unorm@^1.3.3: - version "1.6.0" - resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.6.0.tgz#029b289661fba714f1a9af439eb51d9b16c205af" - integrity sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA== - -unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= - -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -uri-js@^4.2.2: - version "4.4.0" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.0.tgz#aa714261de793e8a82347a7bcc9ce74e86f28602" - integrity sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g== - dependencies: - punycode "^2.1.0" - -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= - -url-parse-lax@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" - integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= - dependencies: - prepend-http "^1.0.1" - -url-parse-lax@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" - integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= - dependencies: - prepend-http "^2.0.0" - -url-set-query@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339" - integrity sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk= - -url-to-options@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" - integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k= - -url@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" - integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= - dependencies: - punycode "1.3.2" - querystring "0.2.0" - -use@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== - -utf-8-validate@^5.0.2: - version "5.0.3" - resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.3.tgz#3b64e418ad2ff829809025fdfef595eab2f03a27" - integrity sha512-jtJM6fpGv8C1SoH4PtG22pGto6x+Y8uPprW0tw3//gGFhDDTiuksgradgFN6yRayDP4SyZZa6ZMGHLIa17+M8A== - dependencies: - node-gyp-build "^4.2.0" - -utf8@3.0.0, utf8@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" - integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== - -util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -util.promisify@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" - integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.2" - has-symbols "^1.0.1" - object.getownpropertydescriptors "^2.1.0" - -util.promisify@^1.0.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.1.1.tgz#77832f57ced2c9478174149cae9b96e9918cd54b" - integrity sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - for-each "^0.3.3" - has-symbols "^1.0.1" - object.getownpropertydescriptors "^2.1.1" - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= - -uuid@3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" - integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== - -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -varint@^5.0.0: - version "5.0.2" - resolved "https://registry.yarnpkg.com/varint/-/varint-5.0.2.tgz#5b47f8a947eb668b848e034dcfa87d0ff8a7f7a4" - integrity sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow== - -vary@^1, vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -walker@^1.0.7, walker@~1.0.5: - version "1.0.7" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" - integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs= - dependencies: - makeerror "1.0.x" - -web3-bzz@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.2.11.tgz#41bc19a77444bd5365744596d778b811880f707f" - integrity sha512-XGpWUEElGypBjeFyUhTkiPXFbDVD6Nr/S5jznE3t8cWUA0FxRf1n3n/NuIZeb0H9RkN2Ctd/jNma/k8XGa3YKg== - dependencies: - "@types/node" "^12.12.6" - got "9.6.0" - swarm-js "^0.1.40" - underscore "1.9.1" - -web3-core-helpers@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.2.11.tgz#84c681ed0b942c0203f3b324a245a127e8c67a99" - integrity sha512-PEPoAoZd5ME7UfbnCZBdzIerpe74GEvlwT4AjOmHeCVZoIFk7EqvOZDejJHt+feJA6kMVTdd0xzRNN295UhC1A== - dependencies: - underscore "1.9.1" - web3-eth-iban "1.2.11" - web3-utils "1.2.11" - -web3-core-method@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.2.11.tgz#f880137d1507a0124912bf052534f168b8d8fbb6" - integrity sha512-ff0q76Cde94HAxLDZ6DbdmKniYCQVtvuaYh+rtOUMB6kssa5FX0q3vPmixi7NPooFnbKmmZCM6NvXg4IreTPIw== - dependencies: - "@ethersproject/transactions" "^5.0.0-beta.135" - underscore "1.9.1" - web3-core-helpers "1.2.11" - web3-core-promievent "1.2.11" - web3-core-subscriptions "1.2.11" - web3-utils "1.2.11" - -web3-core-promievent@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.2.11.tgz#51fe97ca0ddec2f99bf8c3306a7a8e4b094ea3cf" - integrity sha512-il4McoDa/Ox9Agh4kyfQ8Ak/9ABYpnF8poBLL33R/EnxLsJOGQG2nZhkJa3I067hocrPSjEdlPt/0bHXsln4qA== - dependencies: - eventemitter3 "4.0.4" - -web3-core-requestmanager@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.2.11.tgz#fe6eb603fbaee18530293a91f8cf26d8ae28c45a" - integrity sha512-oFhBtLfOiIbmfl6T6gYjjj9igOvtyxJ+fjS+byRxiwFJyJ5BQOz4/9/17gWR1Cq74paTlI7vDGxYfuvfE/mKvA== - dependencies: - underscore "1.9.1" - web3-core-helpers "1.2.11" - web3-providers-http "1.2.11" - web3-providers-ipc "1.2.11" - web3-providers-ws "1.2.11" - -web3-core-subscriptions@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.2.11.tgz#beca908fbfcb050c16f45f3f0f4c205e8505accd" - integrity sha512-qEF/OVqkCvQ7MPs1JylIZCZkin0aKK9lDxpAtQ1F8niEDGFqn7DT8E/vzbIa0GsOjL2fZjDhWJsaW+BSoAW1gg== - dependencies: - eventemitter3 "4.0.4" - underscore "1.9.1" - web3-core-helpers "1.2.11" - -web3-core@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.2.11.tgz#1043cacc1becb80638453cc5b2a14be9050288a7" - integrity sha512-CN7MEYOY5ryo5iVleIWRE3a3cZqVaLlIbIzDPsvQRUfzYnvzZQRZBm9Mq+ttDi2STOOzc1MKylspz/o3yq/LjQ== - dependencies: - "@types/bn.js" "^4.11.5" - "@types/node" "^12.12.6" - bignumber.js "^9.0.0" - web3-core-helpers "1.2.11" - web3-core-method "1.2.11" - web3-core-requestmanager "1.2.11" - web3-utils "1.2.11" - -web3-eth-abi@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.2.11.tgz#a887494e5d447c2926d557a3834edd66e17af9b0" - integrity sha512-PkRYc0+MjuLSgg03QVWqWlQivJqRwKItKtEpRUaxUAeLE7i/uU39gmzm2keHGcQXo3POXAbOnMqkDvOep89Crg== - dependencies: - "@ethersproject/abi" "5.0.0-beta.153" - underscore "1.9.1" - web3-utils "1.2.11" - -web3-eth-accounts@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.2.11.tgz#a9e3044da442d31903a7ce035a86d8fa33f90520" - integrity sha512-6FwPqEpCfKIh3nSSGeo3uBm2iFSnFJDfwL3oS9pyegRBXNsGRVpgiW63yhNzL0796StsvjHWwQnQHsZNxWAkGw== - dependencies: - crypto-browserify "3.12.0" - eth-lib "0.2.8" - ethereumjs-common "^1.3.2" - ethereumjs-tx "^2.1.1" - scrypt-js "^3.0.1" - underscore "1.9.1" - uuid "3.3.2" - web3-core "1.2.11" - web3-core-helpers "1.2.11" - web3-core-method "1.2.11" - web3-utils "1.2.11" - -web3-eth-contract@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.2.11.tgz#917065902bc27ce89da9a1da26e62ef663663b90" - integrity sha512-MzYuI/Rq2o6gn7vCGcnQgco63isPNK5lMAan2E51AJLknjSLnOxwNY3gM8BcKoy4Z+v5Dv00a03Xuk78JowFow== - dependencies: - "@types/bn.js" "^4.11.5" - underscore "1.9.1" - web3-core "1.2.11" - web3-core-helpers "1.2.11" - web3-core-method "1.2.11" - web3-core-promievent "1.2.11" - web3-core-subscriptions "1.2.11" - web3-eth-abi "1.2.11" - web3-utils "1.2.11" - -web3-eth-ens@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.2.11.tgz#26d4d7f16d6cbcfff918e39832b939edc3162532" - integrity sha512-dbW7dXP6HqT1EAPvnniZVnmw6TmQEKF6/1KgAxbo8iBBYrVTMDGFQUUnZ+C4VETGrwwaqtX4L9d/FrQhZ6SUiA== - dependencies: - content-hash "^2.5.2" - eth-ens-namehash "2.0.8" - underscore "1.9.1" - web3-core "1.2.11" - web3-core-helpers "1.2.11" - web3-core-promievent "1.2.11" - web3-eth-abi "1.2.11" - web3-eth-contract "1.2.11" - web3-utils "1.2.11" - -web3-eth-iban@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.2.11.tgz#f5f73298305bc7392e2f188bf38a7362b42144ef" - integrity sha512-ozuVlZ5jwFC2hJY4+fH9pIcuH1xP0HEFhtWsR69u9uDIANHLPQQtWYmdj7xQ3p2YT4bQLq/axKhZi7EZVetmxQ== - dependencies: - bn.js "^4.11.9" - web3-utils "1.2.11" - -web3-eth-personal@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.2.11.tgz#a38b3942a1d87a62070ce0622a941553c3d5aa70" - integrity sha512-42IzUtKq9iHZ8K9VN0vAI50iSU9tOA1V7XU2BhF/tb7We2iKBVdkley2fg26TxlOcKNEHm7o6HRtiiFsVK4Ifw== - dependencies: - "@types/node" "^12.12.6" - web3-core "1.2.11" - web3-core-helpers "1.2.11" - web3-core-method "1.2.11" - web3-net "1.2.11" - web3-utils "1.2.11" - -web3-eth@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.2.11.tgz#4c81fcb6285b8caf544058fba3ae802968fdc793" - integrity sha512-REvxW1wJ58AgHPcXPJOL49d1K/dPmuw4LjPLBPStOVkQjzDTVmJEIsiLwn2YeuNDd4pfakBwT8L3bz1G1/wVsQ== - dependencies: - underscore "1.9.1" - web3-core "1.2.11" - web3-core-helpers "1.2.11" - web3-core-method "1.2.11" - web3-core-subscriptions "1.2.11" - web3-eth-abi "1.2.11" - web3-eth-accounts "1.2.11" - web3-eth-contract "1.2.11" - web3-eth-ens "1.2.11" - web3-eth-iban "1.2.11" - web3-eth-personal "1.2.11" - web3-net "1.2.11" - web3-utils "1.2.11" - -web3-net@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.2.11.tgz#eda68ef25e5cdb64c96c39085cdb74669aabbe1b" - integrity sha512-sjrSDj0pTfZouR5BSTItCuZ5K/oZPVdVciPQ6981PPPIwJJkCMeVjD7I4zO3qDPCnBjBSbWvVnLdwqUBPtHxyg== - dependencies: - web3-core "1.2.11" - web3-core-method "1.2.11" - web3-utils "1.2.11" - -web3-provider-engine@14.2.1: - version "14.2.1" - resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-14.2.1.tgz#ef351578797bf170e08d529cb5b02f8751329b95" - integrity sha512-iSv31h2qXkr9vrL6UZDm4leZMc32SjWJFGOp/D92JXfcEboCqraZyuExDkpxKw8ziTufXieNM7LSXNHzszYdJw== - dependencies: - async "^2.5.0" - backoff "^2.5.0" - clone "^2.0.0" - cross-fetch "^2.1.0" - eth-block-tracker "^3.0.0" - eth-json-rpc-infura "^3.1.0" - eth-sig-util "^1.4.2" - ethereumjs-block "^1.2.2" - ethereumjs-tx "^1.2.0" - ethereumjs-util "^5.1.5" - ethereumjs-vm "^2.3.4" - json-rpc-error "^2.0.0" - json-stable-stringify "^1.0.1" - promise-to-callback "^1.0.0" - readable-stream "^2.2.9" - request "^2.85.0" - semaphore "^1.0.3" - ws "^5.1.1" - xhr "^2.2.0" - xtend "^4.0.1" - -web3-providers-http@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.2.11.tgz#1cd03442c61670572d40e4dcdf1faff8bd91e7c6" - integrity sha512-psh4hYGb1+ijWywfwpB2cvvOIMISlR44F/rJtYkRmQ5jMvG4FOCPlQJPiHQZo+2cc3HbktvvSJzIhkWQJdmvrA== - dependencies: - web3-core-helpers "1.2.11" - xhr2-cookies "1.1.0" - -web3-providers-ipc@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.2.11.tgz#d16d6c9be1be6e0b4f4536c4acc16b0f4f27ef21" - integrity sha512-yhc7Y/k8hBV/KlELxynWjJDzmgDEDjIjBzXK+e0rHBsYEhdCNdIH5Psa456c+l0qTEU2YzycF8VAjYpWfPnBpQ== - dependencies: - oboe "2.1.4" - underscore "1.9.1" - web3-core-helpers "1.2.11" - -web3-providers-ws@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.2.11.tgz#a1dfd6d9778d840561d9ec13dd453046451a96bb" - integrity sha512-ZxnjIY1Er8Ty+cE4migzr43zA/+72AF1myzsLaU5eVgdsfV7Jqx7Dix1hbevNZDKFlSoEyq/3j/jYalh3So1Zg== - dependencies: - eventemitter3 "4.0.4" - underscore "1.9.1" - web3-core-helpers "1.2.11" - websocket "^1.0.31" - -web3-shh@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.2.11.tgz#f5d086f9621c9a47e98d438010385b5f059fd88f" - integrity sha512-B3OrO3oG1L+bv3E1sTwCx66injW1A8hhwpknDUbV+sw3fehFazA06z9SGXUefuFI1kVs4q2vRi0n4oCcI4dZDg== - dependencies: - web3-core "1.2.11" - web3-core-method "1.2.11" - web3-core-subscriptions "1.2.11" - web3-net "1.2.11" - -web3-utils@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.2.11.tgz#af1942aead3fb166ae851a985bed8ef2c2d95a82" - integrity sha512-3Tq09izhD+ThqHEaWYX4VOT7dNPdZiO+c/1QMA0s5X2lDFKK/xHJb7cyTRRVzN2LvlHbR7baS1tmQhSua51TcQ== - dependencies: - bn.js "^4.11.9" - eth-lib "0.2.8" - ethereum-bloom-filters "^1.0.6" - ethjs-unit "0.1.6" - number-to-bn "1.7.0" - randombytes "^2.1.0" - underscore "1.9.1" - utf8 "3.0.0" - -web3-utils@^1.0.0-beta.31: - version "1.3.1" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.3.1.tgz#9aa880dd8c9463fe5c099107889f86a085370c2e" - integrity sha512-9gPwFm8SXtIJuzdrZ37PRlalu40fufXxo+H2PiCwaO6RpKGAvlUlWU0qQbyToFNXg7W2H8djEgoAVac8NLMCKQ== - dependencies: - bn.js "^4.11.9" - eth-lib "0.2.8" - ethereum-bloom-filters "^1.0.6" - ethjs-unit "0.1.6" - number-to-bn "1.7.0" - randombytes "^2.1.0" - underscore "1.9.1" - utf8 "3.0.0" - -web3@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3/-/web3-1.2.11.tgz#50f458b2e8b11aa37302071c170ed61cff332975" - integrity sha512-mjQ8HeU41G6hgOYm1pmeH0mRAeNKJGnJEUzDMoerkpw7QUQT4exVREgF1MYPvL/z6vAshOXei25LE/t/Bxl8yQ== - dependencies: - web3-bzz "1.2.11" - web3-core "1.2.11" - web3-eth "1.2.11" - web3-eth-personal "1.2.11" - web3-net "1.2.11" - web3-shh "1.2.11" - web3-utils "1.2.11" - -websocket@1.0.32: - version "1.0.32" - resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.32.tgz#1f16ddab3a21a2d929dec1687ab21cfdc6d3dbb1" - integrity sha512-i4yhcllSP4wrpoPMU2N0TQ/q0O94LRG/eUQjEAamRltjQ1oT1PFFKOG4i877OlJgCG8rw6LrrowJp+TYCEWF7Q== - dependencies: - bufferutil "^4.0.1" - debug "^2.2.0" - es5-ext "^0.10.50" - typedarray-to-buffer "^3.1.5" - utf-8-validate "^5.0.2" - yaeti "^0.0.6" - -websocket@^1.0.31: - version "1.0.33" - resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.33.tgz#407f763fc58e74a3fa41ca3ae5d78d3f5e3b82a5" - integrity sha512-XwNqM2rN5eh3G2CUQE3OHZj+0xfdH42+OFK6LdC2yqiC0YU8e5UK0nYre220T0IyyN031V/XOvtHvXozvJYFWA== - dependencies: - bufferutil "^4.0.1" - debug "^2.2.0" - es5-ext "^0.10.50" - typedarray-to-buffer "^3.1.5" - utf-8-validate "^5.0.2" - yaeti "^0.0.6" - -whatwg-fetch@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" - integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== - -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - -which-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" - integrity sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8= - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= - -which@1.3.1, which@^1.2.9: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -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" - -window-size@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" - integrity sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU= - -word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - 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" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -write@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" - integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== - dependencies: - mkdirp "^0.5.1" - -ws@7.2.3: - version "7.2.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.3.tgz#a5411e1fb04d5ed0efee76d26d5c46d830c39b46" - integrity sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ== - -ws@^3.0.0: - version "3.3.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" - integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== - dependencies: - async-limiter "~1.0.0" - safe-buffer "~5.1.0" - ultron "~1.1.0" - -ws@^5.1.1: - version "5.2.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" - integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== - dependencies: - async-limiter "~1.0.0" - -ws@^7.2.1: - version "7.4.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.1.tgz#a333be02696bd0e54cea0434e21dcc8a9ac294bb" - integrity sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ== - -xhr-request-promise@^0.1.2: - version "0.1.3" - resolved "https://registry.yarnpkg.com/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz#2d5f4b16d8c6c893be97f1a62b0ed4cf3ca5f96c" - integrity sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg== - dependencies: - xhr-request "^1.1.0" - -xhr-request@^1.0.1, xhr-request@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/xhr-request/-/xhr-request-1.1.0.tgz#f4a7c1868b9f198723444d82dcae317643f2e2ed" - integrity sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA== - dependencies: - buffer-to-arraybuffer "^0.0.5" - object-assign "^4.1.1" - query-string "^5.0.1" - simple-get "^2.7.0" - timed-out "^4.0.1" - url-set-query "^1.0.0" - xhr "^2.0.4" - -xhr2-cookies@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz#7d77449d0999197f155cb73b23df72505ed89d48" - integrity sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg= - dependencies: - cookiejar "^2.1.1" - -xhr@^2.0.4, xhr@^2.2.0, xhr@^2.3.3: - version "2.6.0" - resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.6.0.tgz#b69d4395e792b4173d6b7df077f0fc5e4e2b249d" - integrity sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA== - dependencies: - global "~4.4.0" - is-function "^1.0.1" - parse-headers "^2.0.0" - xtend "^4.0.0" - -xtend@^4.0.0, xtend@^4.0.1, xtend@^4.0.2, xtend@~4.0.0, xtend@~4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -xtend@~2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b" - integrity sha1-bv7MKk2tjmlixJAbM3znuoe10os= - dependencies: - object-keys "~0.4.0" - -y18n@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" - integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= - -y18n@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" - integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== - -y18n@^5.0.5: - version "5.0.5" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.5.tgz#8769ec08d03b1ea2df2500acef561743bbb9ab18" - integrity sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg== - -yaeti@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" - integrity sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc= - -yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: - 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== - -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@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4" - integrity sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ= - dependencies: - camelcase "^3.0.0" - lodash.assign "^4.0.6" - -yargs-parser@^20.2.2: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -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@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.0.3: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yargs@^4.7.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0" - integrity sha1-wMQpJMpKqmsObaFznfshZDn53cA= - dependencies: - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - lodash.assign "^4.0.3" - os-locale "^1.4.0" - read-pkg-up "^1.0.1" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^1.0.1" - which-module "^1.0.0" - window-size "^0.2.0" - y18n "^3.2.1" - yargs-parser "^2.4.1" - -yn@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== diff --git a/lib/v3-periphery/.gitattributes b/lib/v3-periphery/.gitattributes deleted file mode 100644 index 7cc88f0..0000000 --- a/lib/v3-periphery/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -*.sol linguist-language=Solidity \ No newline at end of file diff --git a/lib/v3-periphery/.github/stale.yml b/lib/v3-periphery/.github/stale.yml deleted file mode 100644 index 91b9bf5..0000000 --- a/lib/v3-periphery/.github/stale.yml +++ /dev/null @@ -1,25 +0,0 @@ -# Configuration for probot-stale - https://github.com/probot/stale - -issues: - # Number of days of inactivity before an Issue or Pull Request becomes stale - daysUntilStale: 7 - - # Number of days of inactivity before an Issue or Pull Request with the stale label is closed. - # Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. - daysUntilClose: 7 - - # Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) - onlyLabels: - - question - - autoclose - - # Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable - exemptLabels: - - p0 - - bug - - # Comment to post when marking as stale. Set to `false` to disable - markComment: > - This issue has been automatically marked as stale because it has not had - recent activity. It will be closed if no further activity occurs. Thank you - for your contributions. diff --git a/lib/v3-periphery/.github/workflows/lint.yml b/lib/v3-periphery/.github/workflows/lint.yml deleted file mode 100644 index 2f78834..0000000 --- a/lib/v3-periphery/.github/workflows/lint.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Lint - -on: - push: - branches: - - main - pull_request: - -jobs: - run-linters: - name: Run linters - runs-on: ubuntu-latest - - steps: - - name: Check out Git repository - uses: actions/checkout@v2 - - - name: Set up node - uses: actions/setup-node@v1 - with: - node-version: 12.x - registry-url: https://registry.npmjs.org - - - name: Install dependencies - run: yarn install --frozen-lockfile - - - name: Run linters - uses: wearerequired/lint-action@a8497ddb33fb1205941fd40452ca9fff07e0770d - with: - github_token: ${{ secrets.github_token }} - prettier: true - auto_fix: true - prettier_extensions: 'css,html,js,json,jsx,md,sass,scss,ts,tsx,vue,yaml,yml,sol' diff --git a/lib/v3-periphery/.github/workflows/tests.yml b/lib/v3-periphery/.github/workflows/tests.yml deleted file mode 100644 index ba7a04b..0000000 --- a/lib/v3-periphery/.github/workflows/tests.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: Tests - -on: - push: - branches: - - main - pull_request: - -jobs: - unit-tests: - name: Unit Tests - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v1 - - uses: actions/setup-node@v1 - with: - node-version: 12.x - registry-url: https://registry.npmjs.org - - - id: yarn-cache - run: echo "::set-output name=dir::$(yarn cache dir)" - - - uses: actions/cache@v1 - with: - path: ${{ steps.yarn-cache.outputs.dir }} - key: yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - yarn- - - - name: Install dependencies - run: yarn install --frozen-lockfile - - # This is required separately from yarn test because it generates the typechain definitions - - name: Compile - run: yarn compile - - - name: Run unit tests - run: yarn test diff --git a/lib/v3-periphery/.gitignore b/lib/v3-periphery/.gitignore deleted file mode 100644 index 2be090a..0000000 --- a/lib/v3-periphery/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -artifacts/ -cache/ -crytic-export/ -node_modules/ -typechain/ \ No newline at end of file diff --git a/lib/v3-periphery/.prettierignore b/lib/v3-periphery/.prettierignore deleted file mode 100644 index 821c19d..0000000 --- a/lib/v3-periphery/.prettierignore +++ /dev/null @@ -1 +0,0 @@ -.github \ No newline at end of file diff --git a/lib/v3-periphery/.prettierrc b/lib/v3-periphery/.prettierrc deleted file mode 100644 index 31ba22d..0000000 --- a/lib/v3-periphery/.prettierrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "semi": false, - "singleQuote": true, - "printWidth": 120 -} diff --git a/lib/v3-periphery/.solhint.json b/lib/v3-periphery/.solhint.json deleted file mode 100644 index 11b3647..0000000 --- a/lib/v3-periphery/.solhint.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "plugins": ["prettier"], - "rules": { - "prettier/prettier": "error" - } -} diff --git a/lib/v3-periphery/.yarnrc b/lib/v3-periphery/.yarnrc deleted file mode 100644 index 5455c6c..0000000 --- a/lib/v3-periphery/.yarnrc +++ /dev/null @@ -1 +0,0 @@ -ignore-scripts true diff --git a/lib/v3-periphery/LICENSE b/lib/v3-periphery/LICENSE deleted file mode 100644 index ecbc059..0000000 --- a/lib/v3-periphery/LICENSE +++ /dev/null @@ -1,339 +0,0 @@ - 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 - - 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 -convey 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 2 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, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision 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, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This 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. \ No newline at end of file diff --git a/lib/v3-periphery/README.md b/lib/v3-periphery/README.md deleted file mode 100644 index 8d7345b..0000000 --- a/lib/v3-periphery/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# Uniswap V3 Periphery - -[![Tests](https://github.com/Uniswap/uniswap-v3-periphery/workflows/Tests/badge.svg)](https://github.com/Uniswap/uniswap-v3-periphery/actions?query=workflow%3ATests) -[![Lint](https://github.com/Uniswap/uniswap-v3-periphery/workflows/Lint/badge.svg)](https://github.com/Uniswap/uniswap-v3-periphery/actions?query=workflow%3ALint) - -This repository contains the periphery smart contracts for the Uniswap V3 Protocol. -For the lower level core contracts, see the [uniswap-v3-core](https://github.com/Uniswap/uniswap-v3-core) -repository. - -## Bug bounty - -This repository is subject to the Uniswap V3 bug bounty program, -per the terms defined [here](./bug-bounty.md). - -## Local deployment - -In order to deploy this code to a local testnet, you should install the npm package -`@uniswap/v3-periphery` -and import bytecode imported from artifacts located at -`@uniswap/v3-periphery/artifacts/contracts/*/*.json`. -For example: - -```typescript -import { - abi as SWAP_ROUTER_ABI, - bytecode as SWAP_ROUTER_BYTECODE, -} from '@uniswap/v3-periphery/artifacts/contracts/SwapRouter.sol/SwapRouter.json' - -// deploy the bytecode -``` - -This will ensure that you are testing against the same bytecode that is deployed to -mainnet and public testnets, and all Uniswap code will correctly interoperate with -your local deployment. - -## Using solidity interfaces - -The Uniswap v3 periphery interfaces are available for import into solidity smart contracts -via the npm artifact `@uniswap/v3-periphery`, e.g.: - -```solidity -import '@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol'; - -contract MyContract { - ISwapRouter router; - - function doSomethingWithSwapRouter() { - // router.exactInput(...); - } -} - -``` diff --git a/lib/v3-periphery/audits/abdk/audit.pdf b/lib/v3-periphery/audits/abdk/audit.pdf deleted file mode 100644 index 3608934a6a5ee53b463b58aff5d1c45239ea261c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 990570 zcmeF2WmH^Ex91^9umpF41=nsYK+wi5xNGC??(Po36P)1g1Pku2jk^;?&uIM~Tq#mKq2KJaj{ zk+XgxXM+|~A?M-d=H}ug7Z5-(u{Hj4SMvWy8wwi-;J>_xiif=kIje?}i7E6oOl-}Z z&B=jm(B~Aluy!_agzl}u&L*NJMs~)~Vt?-yz>YRfa? za<+4XR)@Y7IjcHU2_QK;^bab7l&!Ie`yXkbBC>tp{QHur9XaQpM^PeYRkE{lhAIX8 z`%D?CD>)~SPf0u_!~E`=(FAOR;+|z> zXl$@yW?*Pwz>Q4FBOf5yFAgAt!K;E#U@{?3JbV?uBgOYRg%crR7)YMzL8DQCSB_Y& z*M%X9Vi`C#i*cVYj1{%-~Tt-!w(__qT8R^b0@1)wDJ2N?c^ zWS_t`CQuXsvi}Vc^7baS!bZ*(cDCdkY=6)ViW%}Q&el+Hb0TNwpuvK zjf4AthYkY+C~<5knHnIlkpjX2La=FLudqxEEX)mr{6}OF_SOkj(EMe4-bA|*W)P?C zv5V>%@Q-X<_=_cUKfo!&2W=yA$s>M#RYZjNf*u{EA;Qb6R&j7(&T99}y>Kzmg5WnD zyf=LF{RdSonRWw{Tj$mG3TUis{hF}qCqqS##10wb?r#M8HCB%RXERt;OSYfB?g#}T z{u)FlZPNBgfF~1-3MnL$4S}5BX~Gc!2_eG%0e-LFe}EgH5l@HNC6;Z4^`=1^BIe#9 zV8aK%18{h%joB-W;`dBbuznhw@f*M(Gl

Uq2;4@wUZzJ3j3p=Q$cet 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

#6Td55hoT?p#S!w1*!q1`di^A*0Vm_P9 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

)ZX+Y*qovU6{pQ_jGk#iLK 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

W(6c~ZG(8=8rnALs==I{C; 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%0DHnAUKeka5`&oyc( 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 z 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 - 1, i.e. `type(uint128).max`. -- The `transfer` and `transferFrom` methods of any token strictly decrease the balance of the token sender by the transfer amount and increases the balance of token recipient by the transfer amount, i.e. fee on transfer tokens are excluded. -- The token balance of an address can only change due to a call to `transfer` by the sender or `transferFrom` by an approved address, i.e. rebase tokens and interest bearing tokens are excluded. - -## Rewards - -Rewards will be allocated based on the severity of the bug disclosed and will be evaluated and rewarded at the discretion of the Uniswap Labs team. -For critical bugs that lead to loss of user funds (more than 1% or user specified slippage tolerance), -rewards of up to $500,000 will be granted. Lower severity bugs will be rewarded at the discretion of the team. -In addition, all vulnerabilities disclosed prior to the mainnet launch date will be subject to receive higher rewards. - -## Disclosure - -Any vulnerability or bug discovered must be reported only to the following email: [security@uniswap.org](mailto:security@uniswap.org). - -The vulnerability must not be disclosed publicly or to any other person, entity or email address before Uniswap Labs has been notified, has fixed the issue, and has granted permission for public disclosure. In addition, disclosure must be made within 24 hours following discovery of the vulnerability. - -A detailed report of a vulnerability increases the likelihood of a reward and may increase the reward amount. Please provide as much information about the vulnerability as possible, including: - -- The conditions on which reproducing the bug is contingent. -- The steps needed to reproduce the bug or, preferably, a proof of concept. -- The potential implications of the vulnerability being abused. - -Anyone who reports a unique, previously-unreported vulnerability that results in a change to the code or a configuration change and who keeps such vulnerability confidential until it has been resolved by our engineers will be recognized publicly for their contribution if they so choose. - -## Eligibility - -To be eligible for a reward under this Program, you must: - -- Discover a previously unreported, non-public vulnerability that would result in a loss of and/or lock on any ERC-20 token on Uniswap V3 (but not on any third party platform interacting with Uniswap V3) and that is within the scope of this Program. Vulnerabilities must be distinct from the issues covered in the Trail of Bits or ABDK audits. -- Be the first to disclose the unique vulnerability to [security@uniswap.org](mailto:security@uniswap.org), in compliance with the disclosure requirements above. If similar vulnerabilities are reported within the same 24 hour period, rewards will be split at the discretion of Uniswap Labs. -- Provide sufficient information to enable our engineers to reproduce and fix the vulnerability. -- Not engage in any unlawful conduct when disclosing the bug, including through threats, demands, or any other coercive tactics. -- Not exploit the vulnerability in any way, including through making it public or by obtaining a profit (other than a reward under this Program). -- Make a good faith effort to avoid privacy violations, destruction of data, interruption or degradation of Uniswap V3. -- Submit only one vulnerability per submission, unless you need to chain vulnerabilities to provide impact regarding any of the vulnerabilities. -- Not submit a vulnerability caused by an underlying issue that is the same as an issue on which a reward has been paid under this Program. -- Not be one of our current or former employees, vendors, or contractors or an employee of any of those vendors or contractors. -- Not be subject to US sanctions or reside in a US-embargoed country. -- Be at least 18 years of age or, if younger, submit your vulnerability with the consent of your parent or guardian. - -## Other Terms - -By submitting your report, you grant Uniswap Labs any and all rights, including intellectual property rights, needed to validate, mitigate, and disclose the vulnerability. All reward decisions, including eligibility for and amounts of the rewards and the manner in which such rewards will be paid, are made at our sole discretion. - -The terms and conditions of this Program may be altered at any time. diff --git a/lib/v3-periphery/contracts/NonfungiblePositionManager.sol b/lib/v3-periphery/contracts/NonfungiblePositionManager.sol deleted file mode 100644 index 68532a0..0000000 --- a/lib/v3-periphery/contracts/NonfungiblePositionManager.sol +++ /dev/null @@ -1,400 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity =0.7.6; -pragma abicoder v2; - -import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol'; -import '@uniswap/v3-core/contracts/libraries/FixedPoint128.sol'; -import '@uniswap/v3-core/contracts/libraries/FullMath.sol'; - -import './interfaces/INonfungiblePositionManager.sol'; -import './interfaces/INonfungibleTokenPositionDescriptor.sol'; -import './libraries/PositionKey.sol'; -import './libraries/PoolAddress.sol'; -import './base/LiquidityManagement.sol'; -import './base/PeripheryImmutableState.sol'; -import './base/Multicall.sol'; -import './base/ERC721Permit.sol'; -import './base/PeripheryValidation.sol'; -import './base/SelfPermit.sol'; -import './base/PoolInitializer.sol'; - -/// @title NFT positions -/// @notice Wraps Uniswap V3 positions in the ERC721 non-fungible token interface -contract NonfungiblePositionManager is - INonfungiblePositionManager, - Multicall, - ERC721Permit, - PeripheryImmutableState, - PoolInitializer, - LiquidityManagement, - PeripheryValidation, - SelfPermit -{ - // details about the uniswap position - struct Position { - // the nonce for permits - uint96 nonce; - // the address that is approved for spending this token - address operator; - // the ID of the pool with which this token is connected - uint80 poolId; - // the tick range of the position - int24 tickLower; - int24 tickUpper; - // the liquidity of the position - uint128 liquidity; - // the fee growth of the aggregate position as of the last action on the individual position - uint256 feeGrowthInside0LastX128; - uint256 feeGrowthInside1LastX128; - // how many uncollected tokens are owed to the position, as of the last computation - uint128 tokensOwed0; - uint128 tokensOwed1; - } - - /// @dev IDs of pools assigned by this contract - mapping(address => uint80) private _poolIds; - - /// @dev Pool keys by pool ID, to save on SSTOREs for position data - mapping(uint80 => PoolAddress.PoolKey) private _poolIdToPoolKey; - - /// @dev The token ID position data - mapping(uint256 => Position) private _positions; - - /// @dev The ID of the next token that will be minted. Skips 0 - uint176 private _nextId = 1; - /// @dev The ID of the next pool that is used for the first time. Skips 0 - uint80 private _nextPoolId = 1; - - /// @dev The address of the token descriptor contract, which handles generating token URIs for position tokens - address private immutable _tokenDescriptor; - - constructor( - address _factory, - address _WETH9, - address _tokenDescriptor_ - ) ERC721Permit('Uniswap V3 Positions NFT-V1', 'UNI-V3-POS', '1') PeripheryImmutableState(_factory, _WETH9) { - _tokenDescriptor = _tokenDescriptor_; - } - - /// @inheritdoc INonfungiblePositionManager - function positions(uint256 tokenId) - external - view - override - returns ( - uint96 nonce, - address operator, - address token0, - address token1, - uint24 fee, - int24 tickLower, - int24 tickUpper, - uint128 liquidity, - uint256 feeGrowthInside0LastX128, - uint256 feeGrowthInside1LastX128, - uint128 tokensOwed0, - uint128 tokensOwed1 - ) - { - Position memory position = _positions[tokenId]; - require(position.poolId != 0, 'Invalid token ID'); - PoolAddress.PoolKey memory poolKey = _poolIdToPoolKey[position.poolId]; - return ( - position.nonce, - position.operator, - poolKey.token0, - poolKey.token1, - poolKey.fee, - position.tickLower, - position.tickUpper, - position.liquidity, - position.feeGrowthInside0LastX128, - position.feeGrowthInside1LastX128, - position.tokensOwed0, - position.tokensOwed1 - ); - } - - /// @dev Caches a pool key - function cachePoolKey(address pool, PoolAddress.PoolKey memory poolKey) private returns (uint80 poolId) { - poolId = _poolIds[pool]; - if (poolId == 0) { - _poolIds[pool] = (poolId = _nextPoolId++); - _poolIdToPoolKey[poolId] = poolKey; - } - } - - /// @inheritdoc INonfungiblePositionManager - function mint(MintParams calldata params) - external - payable - override - checkDeadline(params.deadline) - returns ( - uint256 tokenId, - uint128 liquidity, - uint256 amount0, - uint256 amount1 - ) - { - IUniswapV3Pool pool; - (liquidity, amount0, amount1, pool) = addLiquidity( - AddLiquidityParams({ - token0: params.token0, - token1: params.token1, - fee: params.fee, - recipient: address(this), - tickLower: params.tickLower, - tickUpper: params.tickUpper, - amount0Desired: params.amount0Desired, - amount1Desired: params.amount1Desired, - amount0Min: params.amount0Min, - amount1Min: params.amount1Min - }) - ); - - _mint(params.recipient, (tokenId = _nextId++)); - - bytes32 positionKey = PositionKey.compute(address(this), params.tickLower, params.tickUpper); - (, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128, , ) = pool.positions(positionKey); - - // idempotent set - uint80 poolId = - cachePoolKey( - address(pool), - PoolAddress.PoolKey({token0: params.token0, token1: params.token1, fee: params.fee}) - ); - - _positions[tokenId] = Position({ - nonce: 0, - operator: address(0), - poolId: poolId, - tickLower: params.tickLower, - tickUpper: params.tickUpper, - liquidity: liquidity, - feeGrowthInside0LastX128: feeGrowthInside0LastX128, - feeGrowthInside1LastX128: feeGrowthInside1LastX128, - tokensOwed0: 0, - tokensOwed1: 0 - }); - - emit IncreaseLiquidity(tokenId, liquidity, amount0, amount1); - } - - modifier isAuthorizedForToken(uint256 tokenId) { - require(_isApprovedOrOwner(msg.sender, tokenId), 'Not approved'); - _; - } - - function tokenURI(uint256 tokenId) public view override(ERC721, IERC721Metadata) returns (string memory) { - require(_exists(tokenId)); - return INonfungibleTokenPositionDescriptor(_tokenDescriptor).tokenURI(this, tokenId); - } - - // save bytecode by removing implementation of unused method - function baseURI() public pure override returns (string memory) {} - - /// @inheritdoc INonfungiblePositionManager - function increaseLiquidity(IncreaseLiquidityParams calldata params) - external - payable - override - checkDeadline(params.deadline) - returns ( - uint128 liquidity, - uint256 amount0, - uint256 amount1 - ) - { - Position storage position = _positions[params.tokenId]; - - PoolAddress.PoolKey memory poolKey = _poolIdToPoolKey[position.poolId]; - - IUniswapV3Pool pool; - (liquidity, amount0, amount1, pool) = addLiquidity( - AddLiquidityParams({ - token0: poolKey.token0, - token1: poolKey.token1, - fee: poolKey.fee, - tickLower: position.tickLower, - tickUpper: position.tickUpper, - amount0Desired: params.amount0Desired, - amount1Desired: params.amount1Desired, - amount0Min: params.amount0Min, - amount1Min: params.amount1Min, - recipient: address(this) - }) - ); - - bytes32 positionKey = PositionKey.compute(address(this), position.tickLower, position.tickUpper); - - // this is now updated to the current transaction - (, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128, , ) = pool.positions(positionKey); - - position.tokensOwed0 += uint128( - FullMath.mulDiv( - feeGrowthInside0LastX128 - position.feeGrowthInside0LastX128, - position.liquidity, - FixedPoint128.Q128 - ) - ); - position.tokensOwed1 += uint128( - FullMath.mulDiv( - feeGrowthInside1LastX128 - position.feeGrowthInside1LastX128, - position.liquidity, - FixedPoint128.Q128 - ) - ); - - position.feeGrowthInside0LastX128 = feeGrowthInside0LastX128; - position.feeGrowthInside1LastX128 = feeGrowthInside1LastX128; - position.liquidity += liquidity; - - emit IncreaseLiquidity(params.tokenId, liquidity, amount0, amount1); - } - - /// @inheritdoc INonfungiblePositionManager - function decreaseLiquidity(DecreaseLiquidityParams calldata params) - external - payable - override - isAuthorizedForToken(params.tokenId) - checkDeadline(params.deadline) - returns (uint256 amount0, uint256 amount1) - { - require(params.liquidity > 0); - Position storage position = _positions[params.tokenId]; - - uint128 positionLiquidity = position.liquidity; - require(positionLiquidity >= params.liquidity); - - PoolAddress.PoolKey memory poolKey = _poolIdToPoolKey[position.poolId]; - IUniswapV3Pool pool = IUniswapV3Pool(PoolAddress.computeAddress(factory, poolKey)); - (amount0, amount1) = pool.burn(position.tickLower, position.tickUpper, params.liquidity); - - require(amount0 >= params.amount0Min && amount1 >= params.amount1Min, 'Price slippage check'); - - bytes32 positionKey = PositionKey.compute(address(this), position.tickLower, position.tickUpper); - // this is now updated to the current transaction - (, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128, , ) = pool.positions(positionKey); - - position.tokensOwed0 += - uint128(amount0) + - uint128( - FullMath.mulDiv( - feeGrowthInside0LastX128 - position.feeGrowthInside0LastX128, - positionLiquidity, - FixedPoint128.Q128 - ) - ); - position.tokensOwed1 += - uint128(amount1) + - uint128( - FullMath.mulDiv( - feeGrowthInside1LastX128 - position.feeGrowthInside1LastX128, - positionLiquidity, - FixedPoint128.Q128 - ) - ); - - position.feeGrowthInside0LastX128 = feeGrowthInside0LastX128; - position.feeGrowthInside1LastX128 = feeGrowthInside1LastX128; - // subtraction is safe because we checked positionLiquidity is gte params.liquidity - position.liquidity = positionLiquidity - params.liquidity; - - emit DecreaseLiquidity(params.tokenId, params.liquidity, amount0, amount1); - } - - /// @inheritdoc INonfungiblePositionManager - function collect(CollectParams calldata params) - external - payable - override - isAuthorizedForToken(params.tokenId) - returns (uint256 amount0, uint256 amount1) - { - require(params.amount0Max > 0 || params.amount1Max > 0); - // allow collecting to the nft position manager address with address 0 - address recipient = params.recipient == address(0) ? address(this) : params.recipient; - - Position storage position = _positions[params.tokenId]; - - PoolAddress.PoolKey memory poolKey = _poolIdToPoolKey[position.poolId]; - - IUniswapV3Pool pool = IUniswapV3Pool(PoolAddress.computeAddress(factory, poolKey)); - - (uint128 tokensOwed0, uint128 tokensOwed1) = (position.tokensOwed0, position.tokensOwed1); - - // trigger an update of the position fees owed and fee growth snapshots if it has any liquidity - if (position.liquidity > 0) { - pool.burn(position.tickLower, position.tickUpper, 0); - (, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128, , ) = - pool.positions(PositionKey.compute(address(this), position.tickLower, position.tickUpper)); - - tokensOwed0 += uint128( - FullMath.mulDiv( - feeGrowthInside0LastX128 - position.feeGrowthInside0LastX128, - position.liquidity, - FixedPoint128.Q128 - ) - ); - tokensOwed1 += uint128( - FullMath.mulDiv( - feeGrowthInside1LastX128 - position.feeGrowthInside1LastX128, - position.liquidity, - FixedPoint128.Q128 - ) - ); - - position.feeGrowthInside0LastX128 = feeGrowthInside0LastX128; - position.feeGrowthInside1LastX128 = feeGrowthInside1LastX128; - } - - // compute the arguments to give to the pool#collect method - (uint128 amount0Collect, uint128 amount1Collect) = - ( - params.amount0Max > tokensOwed0 ? tokensOwed0 : params.amount0Max, - params.amount1Max > tokensOwed1 ? tokensOwed1 : params.amount1Max - ); - - // the actual amounts collected are returned - (amount0, amount1) = pool.collect( - recipient, - position.tickLower, - position.tickUpper, - amount0Collect, - amount1Collect - ); - - // sometimes there will be a few less wei than expected due to rounding down in core, but we just subtract the full amount expected - // instead of the actual amount so we can burn the token - (position.tokensOwed0, position.tokensOwed1) = (tokensOwed0 - amount0Collect, tokensOwed1 - amount1Collect); - - emit Collect(params.tokenId, recipient, amount0Collect, amount1Collect); - } - - /// @inheritdoc INonfungiblePositionManager - function burn(uint256 tokenId) external payable override isAuthorizedForToken(tokenId) { - Position storage position = _positions[tokenId]; - require(position.liquidity == 0 && position.tokensOwed0 == 0 && position.tokensOwed1 == 0, 'Not cleared'); - delete _positions[tokenId]; - _burn(tokenId); - } - - function _getAndIncrementNonce(uint256 tokenId) internal override returns (uint256) { - return uint256(_positions[tokenId].nonce++); - } - - /// @inheritdoc IERC721 - function getApproved(uint256 tokenId) public view override(ERC721, IERC721) returns (address) { - require(_exists(tokenId), 'ERC721: approved query for nonexistent token'); - - return _positions[tokenId].operator; - } - - /// @dev Overrides _approve to use the operator in the position, which is packed with the position permit nonce - function _approve(address to, uint256 tokenId) internal override(ERC721) { - _positions[tokenId].operator = to; - emit Approval(ownerOf(tokenId), to, tokenId); - } -} diff --git a/lib/v3-periphery/contracts/NonfungibleTokenPositionDescriptor.sol b/lib/v3-periphery/contracts/NonfungibleTokenPositionDescriptor.sol deleted file mode 100644 index a8c1628..0000000 --- a/lib/v3-periphery/contracts/NonfungibleTokenPositionDescriptor.sol +++ /dev/null @@ -1,124 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity =0.7.6; -pragma abicoder v2; - -import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol'; -import '@uniswap/lib/contracts/libraries/SafeERC20Namer.sol'; - -import './libraries/ChainId.sol'; -import './interfaces/INonfungiblePositionManager.sol'; -import './interfaces/INonfungibleTokenPositionDescriptor.sol'; -import './interfaces/IERC20Metadata.sol'; -import './libraries/PoolAddress.sol'; -import './libraries/NFTDescriptor.sol'; -import './libraries/TokenRatioSortOrder.sol'; - -/// @title Describes NFT token positions -/// @notice Produces a string containing the data URI for a JSON metadata string -contract NonfungibleTokenPositionDescriptor is INonfungibleTokenPositionDescriptor { - address private constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F; - address private constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; - address private constant USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7; - address private constant TBTC = 0x8dAEBADE922dF735c38C80C7eBD708Af50815fAa; - address private constant WBTC = 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599; - - address public immutable WETH9; - /// @dev A null-terminated string - bytes32 public immutable nativeCurrencyLabelBytes; - - constructor(address _WETH9, bytes32 _nativeCurrencyLabelBytes) { - WETH9 = _WETH9; - nativeCurrencyLabelBytes = _nativeCurrencyLabelBytes; - } - - /// @notice Returns the native currency label as a string - function nativeCurrencyLabel() public view returns (string memory) { - uint256 len = 0; - while (len < 32 && nativeCurrencyLabelBytes[len] != 0) { - len++; - } - bytes memory b = new bytes(len); - for (uint256 i = 0; i < len; i++) { - b[i] = nativeCurrencyLabelBytes[i]; - } - return string(b); - } - - /// @inheritdoc INonfungibleTokenPositionDescriptor - function tokenURI(INonfungiblePositionManager positionManager, uint256 tokenId) - external - view - override - returns (string memory) - { - (, , address token0, address token1, uint24 fee, int24 tickLower, int24 tickUpper, , , , , ) = - positionManager.positions(tokenId); - - IUniswapV3Pool pool = - IUniswapV3Pool( - PoolAddress.computeAddress( - positionManager.factory(), - PoolAddress.PoolKey({token0: token0, token1: token1, fee: fee}) - ) - ); - - bool _flipRatio = flipRatio(token0, token1, ChainId.get()); - address quoteTokenAddress = !_flipRatio ? token1 : token0; - address baseTokenAddress = !_flipRatio ? token0 : token1; - (, int24 tick, , , , , ) = pool.slot0(); - - return - NFTDescriptor.constructTokenURI( - NFTDescriptor.ConstructTokenURIParams({ - tokenId: tokenId, - quoteTokenAddress: quoteTokenAddress, - baseTokenAddress: baseTokenAddress, - quoteTokenSymbol: quoteTokenAddress == WETH9 - ? nativeCurrencyLabel() - : SafeERC20Namer.tokenSymbol(quoteTokenAddress), - baseTokenSymbol: baseTokenAddress == WETH9 - ? nativeCurrencyLabel() - : SafeERC20Namer.tokenSymbol(baseTokenAddress), - quoteTokenDecimals: IERC20Metadata(quoteTokenAddress).decimals(), - baseTokenDecimals: IERC20Metadata(baseTokenAddress).decimals(), - flipRatio: _flipRatio, - tickLower: tickLower, - tickUpper: tickUpper, - tickCurrent: tick, - tickSpacing: pool.tickSpacing(), - fee: fee, - poolAddress: address(pool) - }) - ); - } - - function flipRatio( - address token0, - address token1, - uint256 chainId - ) public view returns (bool) { - return tokenRatioPriority(token0, chainId) > tokenRatioPriority(token1, chainId); - } - - function tokenRatioPriority(address token, uint256 chainId) public view returns (int256) { - if (token == WETH9) { - return TokenRatioSortOrder.DENOMINATOR; - } - if (chainId == 1) { - if (token == USDC) { - return TokenRatioSortOrder.NUMERATOR_MOST; - } else if (token == USDT) { - return TokenRatioSortOrder.NUMERATOR_MORE; - } else if (token == DAI) { - return TokenRatioSortOrder.NUMERATOR; - } else if (token == TBTC) { - return TokenRatioSortOrder.DENOMINATOR_MORE; - } else if (token == WBTC) { - return TokenRatioSortOrder.DENOMINATOR_MOST; - } else { - return 0; - } - } - return 0; - } -} diff --git a/lib/v3-periphery/contracts/SwapRouter.sol b/lib/v3-periphery/contracts/SwapRouter.sol deleted file mode 100644 index 0b14d56..0000000 --- a/lib/v3-periphery/contracts/SwapRouter.sol +++ /dev/null @@ -1,244 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity =0.7.6; -pragma abicoder v2; - -import '@uniswap/v3-core/contracts/libraries/SafeCast.sol'; -import '@uniswap/v3-core/contracts/libraries/TickMath.sol'; -import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol'; - -import './interfaces/ISwapRouter.sol'; -import './base/PeripheryImmutableState.sol'; -import './base/PeripheryValidation.sol'; -import './base/PeripheryPaymentsWithFee.sol'; -import './base/Multicall.sol'; -import './base/SelfPermit.sol'; -import './libraries/Path.sol'; -import './libraries/PoolAddress.sol'; -import './libraries/CallbackValidation.sol'; -import './interfaces/external/IWETH9.sol'; - -/// @title Uniswap V3 Swap Router -/// @notice Router for stateless execution of swaps against Uniswap V3 -contract SwapRouter is - ISwapRouter, - PeripheryImmutableState, - PeripheryValidation, - PeripheryPaymentsWithFee, - Multicall, - SelfPermit -{ - using Path for bytes; - using SafeCast for uint256; - - /// @dev Used as the placeholder value for amountInCached, because the computed amount in for an exact output swap - /// can never actually be this value - uint256 private constant DEFAULT_AMOUNT_IN_CACHED = type(uint256).max; - - /// @dev Transient storage variable used for returning the computed amount in for an exact output swap. - uint256 private amountInCached = DEFAULT_AMOUNT_IN_CACHED; - - constructor(address _factory, address _WETH9) PeripheryImmutableState(_factory, _WETH9) {} - - /// @dev Returns the pool for the given token pair and fee. The pool contract may or may not exist. - function getPool( - address tokenA, - address tokenB, - uint24 fee - ) private view returns (IUniswapV3Pool) { - return IUniswapV3Pool(PoolAddress.computeAddress(factory, PoolAddress.getPoolKey(tokenA, tokenB, fee))); - } - - struct SwapCallbackData { - bytes path; - address payer; - } - - /// @inheritdoc IUniswapV3SwapCallback - function uniswapV3SwapCallback( - int256 amount0Delta, - int256 amount1Delta, - bytes calldata _data - ) external override { - require(amount0Delta > 0 || amount1Delta > 0); // swaps entirely within 0-liquidity regions are not supported - SwapCallbackData memory data = abi.decode(_data, (SwapCallbackData)); - (address tokenIn, address tokenOut, uint24 fee) = data.path.decodeFirstPool(); - CallbackValidation.verifyCallback(factory, tokenIn, tokenOut, fee); - - (bool isExactInput, uint256 amountToPay) = - amount0Delta > 0 - ? (tokenIn < tokenOut, uint256(amount0Delta)) - : (tokenOut < tokenIn, uint256(amount1Delta)); - if (isExactInput) { - pay(tokenIn, data.payer, msg.sender, amountToPay); - } else { - // either initiate the next swap or pay - if (data.path.hasMultiplePools()) { - data.path = data.path.skipToken(); - exactOutputInternal(amountToPay, msg.sender, 0, data); - } else { - amountInCached = amountToPay; - tokenIn = tokenOut; // swap in/out because exact output swaps are reversed - pay(tokenIn, data.payer, msg.sender, amountToPay); - } - } - } - - /// @dev Performs a single exact input swap - function exactInputInternal( - uint256 amountIn, - address recipient, - uint160 sqrtPriceLimitX96, - SwapCallbackData memory data - ) private returns (uint256 amountOut) { - // allow swapping to the router address with address 0 - if (recipient == address(0)) recipient = address(this); - - (address tokenIn, address tokenOut, uint24 fee) = data.path.decodeFirstPool(); - - bool zeroForOne = tokenIn < tokenOut; - - (int256 amount0, int256 amount1) = - getPool(tokenIn, tokenOut, fee).swap( - recipient, - zeroForOne, - amountIn.toInt256(), - sqrtPriceLimitX96 == 0 - ? (zeroForOne ? TickMath.MIN_SQRT_RATIO + 1 : TickMath.MAX_SQRT_RATIO - 1) - : sqrtPriceLimitX96, - abi.encode(data) - ); - - return uint256(-(zeroForOne ? amount1 : amount0)); - } - - /// @inheritdoc ISwapRouter - function exactInputSingle(ExactInputSingleParams calldata params) - external - payable - override - checkDeadline(params.deadline) - returns (uint256 amountOut) - { - amountOut = exactInputInternal( - params.amountIn, - params.recipient, - params.sqrtPriceLimitX96, - SwapCallbackData({path: abi.encodePacked(params.tokenIn, params.fee, params.tokenOut), payer: msg.sender}) - ); - require(amountOut >= params.amountOutMinimum, 'Too little received'); - } - - /// @inheritdoc ISwapRouter - function exactInput(ExactInputParams memory params) - external - payable - override - checkDeadline(params.deadline) - returns (uint256 amountOut) - { - address payer = msg.sender; // msg.sender pays for the first hop - - while (true) { - bool hasMultiplePools = params.path.hasMultiplePools(); - - // the outputs of prior swaps become the inputs to subsequent ones - params.amountIn = exactInputInternal( - params.amountIn, - hasMultiplePools ? address(this) : params.recipient, // for intermediate swaps, this contract custodies - 0, - SwapCallbackData({ - path: params.path.getFirstPool(), // only the first pool in the path is necessary - payer: payer - }) - ); - - // decide whether to continue or terminate - if (hasMultiplePools) { - payer = address(this); // at this point, the caller has paid - params.path = params.path.skipToken(); - } else { - amountOut = params.amountIn; - break; - } - } - - require(amountOut >= params.amountOutMinimum, 'Too little received'); - } - - /// @dev Performs a single exact output swap - function exactOutputInternal( - uint256 amountOut, - address recipient, - uint160 sqrtPriceLimitX96, - SwapCallbackData memory data - ) private returns (uint256 amountIn) { - // allow swapping to the router address with address 0 - if (recipient == address(0)) recipient = address(this); - - (address tokenOut, address tokenIn, uint24 fee) = data.path.decodeFirstPool(); - - bool zeroForOne = tokenIn < tokenOut; - - (int256 amount0Delta, int256 amount1Delta) = - getPool(tokenIn, tokenOut, fee).swap( - recipient, - zeroForOne, - -amountOut.toInt256(), - sqrtPriceLimitX96 == 0 - ? (zeroForOne ? TickMath.MIN_SQRT_RATIO + 1 : TickMath.MAX_SQRT_RATIO - 1) - : sqrtPriceLimitX96, - abi.encode(data) - ); - - uint256 amountOutReceived; - (amountIn, amountOutReceived) = zeroForOne - ? (uint256(amount0Delta), uint256(-amount1Delta)) - : (uint256(amount1Delta), uint256(-amount0Delta)); - // it's technically possible to not receive the full output amount, - // so if no price limit has been specified, require this possibility away - if (sqrtPriceLimitX96 == 0) require(amountOutReceived == amountOut); - } - - /// @inheritdoc ISwapRouter - function exactOutputSingle(ExactOutputSingleParams calldata params) - external - payable - override - checkDeadline(params.deadline) - returns (uint256 amountIn) - { - // avoid an SLOAD by using the swap return data - amountIn = exactOutputInternal( - params.amountOut, - params.recipient, - params.sqrtPriceLimitX96, - SwapCallbackData({path: abi.encodePacked(params.tokenOut, params.fee, params.tokenIn), payer: msg.sender}) - ); - - require(amountIn <= params.amountInMaximum, 'Too much requested'); - // has to be reset even though we don't use it in the single hop case - amountInCached = DEFAULT_AMOUNT_IN_CACHED; - } - - /// @inheritdoc ISwapRouter - function exactOutput(ExactOutputParams calldata params) - external - payable - override - checkDeadline(params.deadline) - returns (uint256 amountIn) - { - // it's okay that the payer is fixed to msg.sender here, as they're only paying for the "final" exact output - // swap, which happens first, and subsequent swaps are paid for within nested callback frames - exactOutputInternal( - params.amountOut, - params.recipient, - 0, - SwapCallbackData({path: params.path, payer: msg.sender}) - ); - - amountIn = amountInCached; - require(amountIn <= params.amountInMaximum, 'Too much requested'); - amountInCached = DEFAULT_AMOUNT_IN_CACHED; - } -} diff --git a/lib/v3-periphery/contracts/V3Migrator.sol b/lib/v3-periphery/contracts/V3Migrator.sol deleted file mode 100644 index e0376e2..0000000 --- a/lib/v3-periphery/contracts/V3Migrator.sol +++ /dev/null @@ -1,99 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity =0.7.6; -pragma abicoder v2; - -import '@uniswap/v3-core/contracts/libraries/LowGasSafeMath.sol'; -import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol'; - -import './interfaces/INonfungiblePositionManager.sol'; - -import './libraries/TransferHelper.sol'; - -import './interfaces/IV3Migrator.sol'; -import './base/PeripheryImmutableState.sol'; -import './base/Multicall.sol'; -import './base/SelfPermit.sol'; -import './interfaces/external/IWETH9.sol'; -import './base/PoolInitializer.sol'; - -/// @title Uniswap V3 Migrator -contract V3Migrator is IV3Migrator, PeripheryImmutableState, PoolInitializer, Multicall, SelfPermit { - using LowGasSafeMath for uint256; - - address public immutable nonfungiblePositionManager; - - constructor( - address _factory, - address _WETH9, - address _nonfungiblePositionManager - ) PeripheryImmutableState(_factory, _WETH9) { - nonfungiblePositionManager = _nonfungiblePositionManager; - } - - receive() external payable { - require(msg.sender == WETH9, 'Not WETH9'); - } - - function migrate(MigrateParams calldata params) external override { - require(params.percentageToMigrate > 0, 'Percentage too small'); - require(params.percentageToMigrate <= 100, 'Percentage too large'); - - // burn v2 liquidity to this address - IUniswapV2Pair(params.pair).transferFrom(msg.sender, params.pair, params.liquidityToMigrate); - (uint256 amount0V2, uint256 amount1V2) = IUniswapV2Pair(params.pair).burn(address(this)); - - // calculate the amounts to migrate to v3 - uint256 amount0V2ToMigrate = amount0V2.mul(params.percentageToMigrate) / 100; - uint256 amount1V2ToMigrate = amount1V2.mul(params.percentageToMigrate) / 100; - - // approve the position manager up to the maximum token amounts - TransferHelper.safeApprove(params.token0, nonfungiblePositionManager, amount0V2ToMigrate); - TransferHelper.safeApprove(params.token1, nonfungiblePositionManager, amount1V2ToMigrate); - - // mint v3 position - (, , uint256 amount0V3, uint256 amount1V3) = - INonfungiblePositionManager(nonfungiblePositionManager).mint( - INonfungiblePositionManager.MintParams({ - token0: params.token0, - token1: params.token1, - fee: params.fee, - tickLower: params.tickLower, - tickUpper: params.tickUpper, - amount0Desired: amount0V2ToMigrate, - amount1Desired: amount1V2ToMigrate, - amount0Min: params.amount0Min, - amount1Min: params.amount1Min, - recipient: params.recipient, - deadline: params.deadline - }) - ); - - // if necessary, clear allowance and refund dust - if (amount0V3 < amount0V2) { - if (amount0V3 < amount0V2ToMigrate) { - TransferHelper.safeApprove(params.token0, nonfungiblePositionManager, 0); - } - - uint256 refund0 = amount0V2 - amount0V3; - if (params.refundAsETH && params.token0 == WETH9) { - IWETH9(WETH9).withdraw(refund0); - TransferHelper.safeTransferETH(msg.sender, refund0); - } else { - TransferHelper.safeTransfer(params.token0, msg.sender, refund0); - } - } - if (amount1V3 < amount1V2) { - if (amount1V3 < amount1V2ToMigrate) { - TransferHelper.safeApprove(params.token1, nonfungiblePositionManager, 0); - } - - uint256 refund1 = amount1V2 - amount1V3; - if (params.refundAsETH && params.token1 == WETH9) { - IWETH9(WETH9).withdraw(refund1); - TransferHelper.safeTransferETH(msg.sender, refund1); - } else { - TransferHelper.safeTransfer(params.token1, msg.sender, refund1); - } - } - } -} diff --git a/lib/v3-periphery/contracts/base/BlockTimestamp.sol b/lib/v3-periphery/contracts/base/BlockTimestamp.sol deleted file mode 100644 index ac05cac..0000000 --- a/lib/v3-periphery/contracts/base/BlockTimestamp.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity =0.7.6; - -/// @title Function for getting block timestamp -/// @dev Base contract that is overridden for tests -abstract contract BlockTimestamp { - /// @dev Method that exists purely to be overridden for tests - /// @return The current block timestamp - function _blockTimestamp() internal view virtual returns (uint256) { - return block.timestamp; - } -} diff --git a/lib/v3-periphery/contracts/base/ERC721Permit.sol b/lib/v3-periphery/contracts/base/ERC721Permit.sol deleted file mode 100644 index efe0f54..0000000 --- a/lib/v3-periphery/contracts/base/ERC721Permit.sol +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity =0.7.6; - -import '@openzeppelin/contracts/token/ERC721/ERC721.sol'; -import '@openzeppelin/contracts/utils/Address.sol'; - -import '../libraries/ChainId.sol'; -import '../interfaces/external/IERC1271.sol'; -import '../interfaces/IERC721Permit.sol'; -import './BlockTimestamp.sol'; - -/// @title ERC721 with permit -/// @notice Nonfungible tokens that support an approve via signature, i.e. permit -abstract contract ERC721Permit is BlockTimestamp, ERC721, IERC721Permit { - /// @dev Gets the current nonce for a token ID and then increments it, returning the original value - function _getAndIncrementNonce(uint256 tokenId) internal virtual returns (uint256); - - /// @dev The hash of the name used in the permit signature verification - bytes32 private immutable nameHash; - - /// @dev The hash of the version string used in the permit signature verification - bytes32 private immutable versionHash; - - /// @notice Computes the nameHash and versionHash - constructor( - string memory name_, - string memory symbol_, - string memory version_ - ) ERC721(name_, symbol_) { - nameHash = keccak256(bytes(name_)); - versionHash = keccak256(bytes(version_)); - } - - /// @inheritdoc IERC721Permit - function DOMAIN_SEPARATOR() public view override returns (bytes32) { - return - keccak256( - abi.encode( - // keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)') - 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f, - nameHash, - versionHash, - ChainId.get(), - address(this) - ) - ); - } - - /// @inheritdoc IERC721Permit - /// @dev Value is equal to keccak256("Permit(address spender,uint256 tokenId,uint256 nonce,uint256 deadline)"); - bytes32 public constant override PERMIT_TYPEHASH = - 0x49ecf333e5b8c95c40fdafc95c1ad136e8914a8fb55e9dc8bb01eaa83a2df9ad; - - /// @inheritdoc IERC721Permit - function permit( - address spender, - uint256 tokenId, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) external payable override { - require(_blockTimestamp() <= deadline, 'Permit expired'); - - bytes32 digest = - keccak256( - abi.encodePacked( - '\x19\x01', - DOMAIN_SEPARATOR(), - keccak256(abi.encode(PERMIT_TYPEHASH, spender, tokenId, _getAndIncrementNonce(tokenId), deadline)) - ) - ); - address owner = ownerOf(tokenId); - require(spender != owner, 'ERC721Permit: approval to current owner'); - - if (Address.isContract(owner)) { - require(IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) == 0x1626ba7e, 'Unauthorized'); - } else { - address recoveredAddress = ecrecover(digest, v, r, s); - require(recoveredAddress != address(0), 'Invalid signature'); - require(recoveredAddress == owner, 'Unauthorized'); - } - - _approve(spender, tokenId); - } -} diff --git a/lib/v3-periphery/contracts/base/LiquidityManagement.sol b/lib/v3-periphery/contracts/base/LiquidityManagement.sol deleted file mode 100644 index 0301b39..0000000 --- a/lib/v3-periphery/contracts/base/LiquidityManagement.sol +++ /dev/null @@ -1,90 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity =0.7.6; -pragma abicoder v2; - -import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol'; -import '@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3MintCallback.sol'; -import '@uniswap/v3-core/contracts/libraries/TickMath.sol'; - -import '../libraries/PoolAddress.sol'; -import '../libraries/CallbackValidation.sol'; -import '../libraries/LiquidityAmounts.sol'; - -import './PeripheryPayments.sol'; -import './PeripheryImmutableState.sol'; - -/// @title Liquidity management functions -/// @notice Internal functions for safely managing liquidity in Uniswap V3 -abstract contract LiquidityManagement is IUniswapV3MintCallback, PeripheryImmutableState, PeripheryPayments { - struct MintCallbackData { - PoolAddress.PoolKey poolKey; - address payer; - } - - /// @inheritdoc IUniswapV3MintCallback - function uniswapV3MintCallback( - uint256 amount0Owed, - uint256 amount1Owed, - bytes calldata data - ) external override { - MintCallbackData memory decoded = abi.decode(data, (MintCallbackData)); - CallbackValidation.verifyCallback(factory, decoded.poolKey); - - if (amount0Owed > 0) pay(decoded.poolKey.token0, decoded.payer, msg.sender, amount0Owed); - if (amount1Owed > 0) pay(decoded.poolKey.token1, decoded.payer, msg.sender, amount1Owed); - } - - struct AddLiquidityParams { - address token0; - address token1; - uint24 fee; - address recipient; - int24 tickLower; - int24 tickUpper; - uint256 amount0Desired; - uint256 amount1Desired; - uint256 amount0Min; - uint256 amount1Min; - } - - /// @notice Add liquidity to an initialized pool - function addLiquidity(AddLiquidityParams memory params) - internal - returns ( - uint128 liquidity, - uint256 amount0, - uint256 amount1, - IUniswapV3Pool pool - ) - { - PoolAddress.PoolKey memory poolKey = - PoolAddress.PoolKey({token0: params.token0, token1: params.token1, fee: params.fee}); - - pool = IUniswapV3Pool(PoolAddress.computeAddress(factory, poolKey)); - - // compute the liquidity amount - { - (uint160 sqrtPriceX96, , , , , , ) = pool.slot0(); - uint160 sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(params.tickLower); - uint160 sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(params.tickUpper); - - liquidity = LiquidityAmounts.getLiquidityForAmounts( - sqrtPriceX96, - sqrtRatioAX96, - sqrtRatioBX96, - params.amount0Desired, - params.amount1Desired - ); - } - - (amount0, amount1) = pool.mint( - params.recipient, - params.tickLower, - params.tickUpper, - liquidity, - abi.encode(MintCallbackData({poolKey: poolKey, payer: msg.sender})) - ); - - require(amount0 >= params.amount0Min && amount1 >= params.amount1Min, 'Price slippage check'); - } -} diff --git a/lib/v3-periphery/contracts/base/Multicall.sol b/lib/v3-periphery/contracts/base/Multicall.sol deleted file mode 100644 index 5a6384d..0000000 --- a/lib/v3-periphery/contracts/base/Multicall.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity =0.7.6; -pragma abicoder v2; - -import '../interfaces/IMulticall.sol'; - -/// @title Multicall -/// @notice Enables calling multiple methods in a single call to the contract -abstract contract Multicall is IMulticall { - /// @inheritdoc IMulticall - function multicall(bytes[] calldata data) public payable override returns (bytes[] memory results) { - results = new bytes[](data.length); - for (uint256 i = 0; i < data.length; i++) { - (bool success, bytes memory result) = address(this).delegatecall(data[i]); - - if (!success) { - // Next 5 lines from https://ethereum.stackexchange.com/a/83577 - if (result.length < 68) revert(); - assembly { - result := add(result, 0x04) - } - revert(abi.decode(result, (string))); - } - - results[i] = result; - } - } -} diff --git a/lib/v3-periphery/contracts/base/PeripheryImmutableState.sol b/lib/v3-periphery/contracts/base/PeripheryImmutableState.sol deleted file mode 100644 index 75267a4..0000000 --- a/lib/v3-periphery/contracts/base/PeripheryImmutableState.sol +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity =0.7.6; - -import '../interfaces/IPeripheryImmutableState.sol'; - -/// @title Immutable state -/// @notice Immutable state used by periphery contracts -abstract contract PeripheryImmutableState is IPeripheryImmutableState { - /// @inheritdoc IPeripheryImmutableState - address public immutable override factory; - /// @inheritdoc IPeripheryImmutableState - address public immutable override WETH9; - - constructor(address _factory, address _WETH9) { - factory = _factory; - WETH9 = _WETH9; - } -} diff --git a/lib/v3-periphery/contracts/base/PeripheryPayments.sol b/lib/v3-periphery/contracts/base/PeripheryPayments.sol deleted file mode 100644 index 8651e3e..0000000 --- a/lib/v3-periphery/contracts/base/PeripheryPayments.sol +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.7.5; - -import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; - -import '../interfaces/IPeripheryPayments.sol'; -import '../interfaces/external/IWETH9.sol'; - -import '../libraries/TransferHelper.sol'; - -import './PeripheryImmutableState.sol'; - -abstract contract PeripheryPayments is IPeripheryPayments, PeripheryImmutableState { - receive() external payable { - require(msg.sender == WETH9, 'Not WETH9'); - } - - /// @inheritdoc IPeripheryPayments - function unwrapWETH9(uint256 amountMinimum, address recipient) public payable override { - uint256 balanceWETH9 = IWETH9(WETH9).balanceOf(address(this)); - require(balanceWETH9 >= amountMinimum, 'Insufficient WETH9'); - - if (balanceWETH9 > 0) { - IWETH9(WETH9).withdraw(balanceWETH9); - TransferHelper.safeTransferETH(recipient, balanceWETH9); - } - } - - /// @inheritdoc IPeripheryPayments - function sweepToken( - address token, - uint256 amountMinimum, - address recipient - ) public payable override { - uint256 balanceToken = IERC20(token).balanceOf(address(this)); - require(balanceToken >= amountMinimum, 'Insufficient token'); - - if (balanceToken > 0) { - TransferHelper.safeTransfer(token, recipient, balanceToken); - } - } - - /// @inheritdoc IPeripheryPayments - function refundETH() external payable override { - if (address(this).balance > 0) TransferHelper.safeTransferETH(msg.sender, address(this).balance); - } - - /// @param token The token to pay - /// @param payer The entity that must pay - /// @param recipient The entity that will receive payment - /// @param value The amount to pay - function pay( - address token, - address payer, - address recipient, - uint256 value - ) internal { - if (token == WETH9 && address(this).balance >= value) { - // pay with WETH9 - IWETH9(WETH9).deposit{value: value}(); // wrap only what is needed to pay - IWETH9(WETH9).transfer(recipient, value); - } else if (payer == address(this)) { - // pay with tokens already in the contract (for the exact input multihop case) - TransferHelper.safeTransfer(token, recipient, value); - } else { - // pull payment - TransferHelper.safeTransferFrom(token, payer, recipient, value); - } - } -} diff --git a/lib/v3-periphery/contracts/base/PeripheryPaymentsWithFee.sol b/lib/v3-periphery/contracts/base/PeripheryPaymentsWithFee.sol deleted file mode 100644 index b7b1a31..0000000 --- a/lib/v3-periphery/contracts/base/PeripheryPaymentsWithFee.sol +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.7.5; - -import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import '@uniswap/v3-core/contracts/libraries/LowGasSafeMath.sol'; - -import './PeripheryPayments.sol'; -import '../interfaces/IPeripheryPaymentsWithFee.sol'; - -import '../interfaces/external/IWETH9.sol'; -import '../libraries/TransferHelper.sol'; - -abstract contract PeripheryPaymentsWithFee is PeripheryPayments, IPeripheryPaymentsWithFee { - using LowGasSafeMath for uint256; - - /// @inheritdoc IPeripheryPaymentsWithFee - function unwrapWETH9WithFee( - uint256 amountMinimum, - address recipient, - uint256 feeBips, - address feeRecipient - ) public payable override { - require(feeBips > 0 && feeBips <= 100); - - uint256 balanceWETH9 = IWETH9(WETH9).balanceOf(address(this)); - require(balanceWETH9 >= amountMinimum, 'Insufficient WETH9'); - - if (balanceWETH9 > 0) { - IWETH9(WETH9).withdraw(balanceWETH9); - uint256 feeAmount = balanceWETH9.mul(feeBips) / 10_000; - if (feeAmount > 0) TransferHelper.safeTransferETH(feeRecipient, feeAmount); - TransferHelper.safeTransferETH(recipient, balanceWETH9 - feeAmount); - } - } - - /// @inheritdoc IPeripheryPaymentsWithFee - function sweepTokenWithFee( - address token, - uint256 amountMinimum, - address recipient, - uint256 feeBips, - address feeRecipient - ) public payable override { - require(feeBips > 0 && feeBips <= 100); - - uint256 balanceToken = IERC20(token).balanceOf(address(this)); - require(balanceToken >= amountMinimum, 'Insufficient token'); - - if (balanceToken > 0) { - uint256 feeAmount = balanceToken.mul(feeBips) / 10_000; - if (feeAmount > 0) TransferHelper.safeTransfer(token, feeRecipient, feeAmount); - TransferHelper.safeTransfer(token, recipient, balanceToken - feeAmount); - } - } -} diff --git a/lib/v3-periphery/contracts/base/PeripheryValidation.sol b/lib/v3-periphery/contracts/base/PeripheryValidation.sol deleted file mode 100644 index 40fadd7..0000000 --- a/lib/v3-periphery/contracts/base/PeripheryValidation.sol +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity =0.7.6; - -import './BlockTimestamp.sol'; - -abstract contract PeripheryValidation is BlockTimestamp { - modifier checkDeadline(uint256 deadline) { - require(_blockTimestamp() <= deadline, 'Transaction too old'); - _; - } -} diff --git a/lib/v3-periphery/contracts/base/PoolInitializer.sol b/lib/v3-periphery/contracts/base/PoolInitializer.sol deleted file mode 100644 index af8e43e..0000000 --- a/lib/v3-periphery/contracts/base/PoolInitializer.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity =0.7.6; - -import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol'; -import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol'; - -import './PeripheryImmutableState.sol'; -import '../interfaces/IPoolInitializer.sol'; - -/// @title Creates and initializes V3 Pools -abstract contract PoolInitializer is IPoolInitializer, PeripheryImmutableState { - /// @inheritdoc IPoolInitializer - function createAndInitializePoolIfNecessary( - address token0, - address token1, - uint24 fee, - uint160 sqrtPriceX96 - ) external payable override returns (address pool) { - require(token0 < token1); - pool = IUniswapV3Factory(factory).getPool(token0, token1, fee); - - if (pool == address(0)) { - pool = IUniswapV3Factory(factory).createPool(token0, token1, fee); - IUniswapV3Pool(pool).initialize(sqrtPriceX96); - } else { - (uint160 sqrtPriceX96Existing, , , , , , ) = IUniswapV3Pool(pool).slot0(); - if (sqrtPriceX96Existing == 0) { - IUniswapV3Pool(pool).initialize(sqrtPriceX96); - } - } - } -} diff --git a/lib/v3-periphery/contracts/base/SelfPermit.sol b/lib/v3-periphery/contracts/base/SelfPermit.sol deleted file mode 100644 index 691acb4..0000000 --- a/lib/v3-periphery/contracts/base/SelfPermit.sol +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import '@openzeppelin/contracts/drafts/IERC20Permit.sol'; - -import '../interfaces/ISelfPermit.sol'; -import '../interfaces/external/IERC20PermitAllowed.sol'; - -/// @title Self Permit -/// @notice Functionality to call permit on any EIP-2612-compliant token for use in the route -/// @dev These functions are expected to be embedded in multicalls to allow EOAs to approve a contract and call a function -/// that requires an approval in a single transaction. -abstract contract SelfPermit is ISelfPermit { - /// @inheritdoc ISelfPermit - function selfPermit( - address token, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) public payable override { - IERC20Permit(token).permit(msg.sender, address(this), value, deadline, v, r, s); - } - - /// @inheritdoc ISelfPermit - function selfPermitIfNecessary( - address token, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) external payable override { - if (IERC20(token).allowance(msg.sender, address(this)) < value) selfPermit(token, value, deadline, v, r, s); - } - - /// @inheritdoc ISelfPermit - function selfPermitAllowed( - address token, - uint256 nonce, - uint256 expiry, - uint8 v, - bytes32 r, - bytes32 s - ) public payable override { - IERC20PermitAllowed(token).permit(msg.sender, address(this), nonce, expiry, true, v, r, s); - } - - /// @inheritdoc ISelfPermit - function selfPermitAllowedIfNecessary( - address token, - uint256 nonce, - uint256 expiry, - uint8 v, - bytes32 r, - bytes32 s - ) external payable override { - if (IERC20(token).allowance(msg.sender, address(this)) < type(uint256).max) - selfPermitAllowed(token, nonce, expiry, v, r, s); - } -} diff --git a/lib/v3-periphery/contracts/examples/PairFlash.sol b/lib/v3-periphery/contracts/examples/PairFlash.sol deleted file mode 100644 index a538b41..0000000 --- a/lib/v3-periphery/contracts/examples/PairFlash.sol +++ /dev/null @@ -1,149 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity =0.7.6; -pragma abicoder v2; - -import '@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3FlashCallback.sol'; -import '@uniswap/v3-core/contracts/libraries/LowGasSafeMath.sol'; - -import '../base/PeripheryPayments.sol'; -import '../base/PeripheryImmutableState.sol'; -import '../libraries/PoolAddress.sol'; -import '../libraries/CallbackValidation.sol'; -import '../libraries/TransferHelper.sol'; -import '../interfaces/ISwapRouter.sol'; - -/// @title Flash contract implementation -/// @notice An example contract using the Uniswap V3 flash function -contract PairFlash is IUniswapV3FlashCallback, PeripheryPayments { - using LowGasSafeMath for uint256; - using LowGasSafeMath for int256; - - ISwapRouter public immutable swapRouter; - - constructor( - ISwapRouter _swapRouter, - address _factory, - address _WETH9 - ) PeripheryImmutableState(_factory, _WETH9) { - swapRouter = _swapRouter; - } - - // fee2 and fee3 are the two other fees associated with the two other pools of token0 and token1 - struct FlashCallbackData { - uint256 amount0; - uint256 amount1; - address payer; - PoolAddress.PoolKey poolKey; - uint24 poolFee2; - uint24 poolFee3; - } - - /// @param fee0 The fee from calling flash for token0 - /// @param fee1 The fee from calling flash for token1 - /// @param data The data needed in the callback passed as FlashCallbackData from `initFlash` - /// @notice implements the callback called from flash - /// @dev fails if the flash is not profitable, meaning the amountOut from the flash is less than the amount borrowed - function uniswapV3FlashCallback( - uint256 fee0, - uint256 fee1, - bytes calldata data - ) external override { - FlashCallbackData memory decoded = abi.decode(data, (FlashCallbackData)); - CallbackValidation.verifyCallback(factory, decoded.poolKey); - - address token0 = decoded.poolKey.token0; - address token1 = decoded.poolKey.token1; - - // profitability parameters - we must receive at least the required payment from the arbitrage swaps - // exactInputSingle will fail if this amount not met - uint256 amount0Min = LowGasSafeMath.add(decoded.amount0, fee0); - uint256 amount1Min = LowGasSafeMath.add(decoded.amount1, fee1); - - // call exactInputSingle for swapping token1 for token0 in pool with fee2 - TransferHelper.safeApprove(token1, address(swapRouter), decoded.amount1); - uint256 amountOut0 = - swapRouter.exactInputSingle( - ISwapRouter.ExactInputSingleParams({ - tokenIn: token1, - tokenOut: token0, - fee: decoded.poolFee2, - recipient: address(this), - deadline: block.timestamp, - amountIn: decoded.amount1, - amountOutMinimum: amount0Min, - sqrtPriceLimitX96: 0 - }) - ); - - // call exactInputSingle for swapping token0 for token 1 in pool with fee3 - TransferHelper.safeApprove(token0, address(swapRouter), decoded.amount0); - uint256 amountOut1 = - swapRouter.exactInputSingle( - ISwapRouter.ExactInputSingleParams({ - tokenIn: token0, - tokenOut: token1, - fee: decoded.poolFee3, - recipient: address(this), - deadline: block.timestamp, - amountIn: decoded.amount0, - amountOutMinimum: amount1Min, - sqrtPriceLimitX96: 0 - }) - ); - - // pay the required amounts back to the pair - if (amount0Min > 0) pay(token0, address(this), msg.sender, amount0Min); - if (amount1Min > 0) pay(token1, address(this), msg.sender, amount1Min); - - // if profitable pay profits to payer - if (amountOut0 > amount0Min) { - uint256 profit0 = amountOut0 - amount0Min; - pay(token0, address(this), decoded.payer, profit0); - } - if (amountOut1 > amount1Min) { - uint256 profit1 = amountOut1 - amount1Min; - pay(token1, address(this), decoded.payer, profit1); - } - } - - //fee1 is the fee of the pool from the initial borrow - //fee2 is the fee of the first pool to arb from - //fee3 is the fee of the second pool to arb from - struct FlashParams { - address token0; - address token1; - uint24 fee1; - uint256 amount0; - uint256 amount1; - uint24 fee2; - uint24 fee3; - } - - /// @param params The parameters necessary for flash and the callback, passed in as FlashParams - /// @notice Calls the pools flash function with data needed in `uniswapV3FlashCallback` - function initFlash(FlashParams memory params) external { - PoolAddress.PoolKey memory poolKey = - PoolAddress.PoolKey({token0: params.token0, token1: params.token1, fee: params.fee1}); - IUniswapV3Pool pool = IUniswapV3Pool(PoolAddress.computeAddress(factory, poolKey)); - // recipient of borrowed amounts - // amount of token0 requested to borrow - // amount of token1 requested to borrow - // need amount 0 and amount1 in callback to pay back pool - // recipient of flash should be THIS contract - pool.flash( - address(this), - params.amount0, - params.amount1, - abi.encode( - FlashCallbackData({ - amount0: params.amount0, - amount1: params.amount1, - payer: msg.sender, - poolKey: poolKey, - poolFee2: params.fee2, - poolFee3: params.fee3 - }) - ) - ); - } -} diff --git a/lib/v3-periphery/contracts/interfaces/IERC20Metadata.sol b/lib/v3-periphery/contracts/interfaces/IERC20Metadata.sol deleted file mode 100644 index d7bd3e9..0000000 --- a/lib/v3-periphery/contracts/interfaces/IERC20Metadata.sol +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.7.0; - -import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; - -/// @title IERC20Metadata -/// @title Interface for ERC20 Metadata -/// @notice Extension to IERC20 that includes token metadata -interface IERC20Metadata is IERC20 { - /// @return The name of the token - function name() external view returns (string memory); - - /// @return The symbol of the token - function symbol() external view returns (string memory); - - /// @return The number of decimal places the token has - function decimals() external view returns (uint8); -} diff --git a/lib/v3-periphery/contracts/interfaces/IERC721Permit.sol b/lib/v3-periphery/contracts/interfaces/IERC721Permit.sol deleted file mode 100644 index 744cd3a..0000000 --- a/lib/v3-periphery/contracts/interfaces/IERC721Permit.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.7.5; - -import '@openzeppelin/contracts/token/ERC721/IERC721.sol'; - -/// @title ERC721 with permit -/// @notice Extension to ERC721 that includes a permit function for signature based approvals -interface IERC721Permit is IERC721 { - /// @notice The permit typehash used in the permit signature - /// @return The typehash for the permit - function PERMIT_TYPEHASH() external pure returns (bytes32); - - /// @notice The domain separator used in the permit signature - /// @return The domain seperator used in encoding of permit signature - function DOMAIN_SEPARATOR() external view returns (bytes32); - - /// @notice Approve of a specific token ID for spending by spender via signature - /// @param spender The account that is being approved - /// @param tokenId The ID of the token that is being approved for spending - /// @param deadline The deadline timestamp by which the call must be mined for the approve to work - /// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s` - /// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s` - /// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v` - function permit( - address spender, - uint256 tokenId, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) external payable; -} diff --git a/lib/v3-periphery/contracts/interfaces/IMulticall.sol b/lib/v3-periphery/contracts/interfaces/IMulticall.sol deleted file mode 100644 index 1ea39c6..0000000 --- a/lib/v3-periphery/contracts/interfaces/IMulticall.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.7.5; -pragma abicoder v2; - -/// @title Multicall interface -/// @notice Enables calling multiple methods in a single call to the contract -interface IMulticall { - /// @notice Call multiple functions in the current contract and return the data from all of them if they all succeed - /// @dev The `msg.value` should not be trusted for any method callable from multicall. - /// @param data The encoded function data for each of the calls to make to this contract - /// @return results The results from each of the calls passed in via data - function multicall(bytes[] calldata data) external payable returns (bytes[] memory results); -} diff --git a/lib/v3-periphery/contracts/interfaces/INonfungiblePositionManager.sol b/lib/v3-periphery/contracts/interfaces/INonfungiblePositionManager.sol deleted file mode 100644 index 023b266..0000000 --- a/lib/v3-periphery/contracts/interfaces/INonfungiblePositionManager.sol +++ /dev/null @@ -1,180 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.7.5; -pragma abicoder v2; - -import '@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol'; -import '@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol'; - -import './IPoolInitializer.sol'; -import './IERC721Permit.sol'; -import './IPeripheryPayments.sol'; -import './IPeripheryImmutableState.sol'; -import '../libraries/PoolAddress.sol'; - -/// @title Non-fungible token for positions -/// @notice Wraps Uniswap V3 positions in a non-fungible token interface which allows for them to be transferred -/// and authorized. -interface INonfungiblePositionManager is - IPoolInitializer, - IPeripheryPayments, - IPeripheryImmutableState, - IERC721Metadata, - IERC721Enumerable, - IERC721Permit -{ - /// @notice Emitted when liquidity is increased for a position NFT - /// @dev Also emitted when a token is minted - /// @param tokenId The ID of the token for which liquidity was increased - /// @param liquidity The amount by which liquidity for the NFT position was increased - /// @param amount0 The amount of token0 that was paid for the increase in liquidity - /// @param amount1 The amount of token1 that was paid for the increase in liquidity - event IncreaseLiquidity(uint256 indexed tokenId, uint128 liquidity, uint256 amount0, uint256 amount1); - /// @notice Emitted when liquidity is decreased for a position NFT - /// @param tokenId The ID of the token for which liquidity was decreased - /// @param liquidity The amount by which liquidity for the NFT position was decreased - /// @param amount0 The amount of token0 that was accounted for the decrease in liquidity - /// @param amount1 The amount of token1 that was accounted for the decrease in liquidity - event DecreaseLiquidity(uint256 indexed tokenId, uint128 liquidity, uint256 amount0, uint256 amount1); - /// @notice Emitted when tokens are collected for a position NFT - /// @dev The amounts reported may not be exactly equivalent to the amounts transferred, due to rounding behavior - /// @param tokenId The ID of the token for which underlying tokens were collected - /// @param recipient The address of the account that received the collected tokens - /// @param amount0 The amount of token0 owed to the position that was collected - /// @param amount1 The amount of token1 owed to the position that was collected - event Collect(uint256 indexed tokenId, address recipient, uint256 amount0, uint256 amount1); - - /// @notice Returns the position information associated with a given token ID. - /// @dev Throws if the token ID is not valid. - /// @param tokenId The ID of the token that represents the position - /// @return nonce The nonce for permits - /// @return operator The address that is approved for spending - /// @return token0 The address of the token0 for a specific pool - /// @return token1 The address of the token1 for a specific pool - /// @return fee The fee associated with the pool - /// @return tickLower The lower end of the tick range for the position - /// @return tickUpper The higher end of the tick range for the position - /// @return liquidity The liquidity of the position - /// @return feeGrowthInside0LastX128 The fee growth of token0 as of the last action on the individual position - /// @return feeGrowthInside1LastX128 The fee growth of token1 as of the last action on the individual position - /// @return tokensOwed0 The uncollected amount of token0 owed to the position as of the last computation - /// @return tokensOwed1 The uncollected amount of token1 owed to the position as of the last computation - function positions(uint256 tokenId) - external - view - returns ( - uint96 nonce, - address operator, - address token0, - address token1, - uint24 fee, - int24 tickLower, - int24 tickUpper, - uint128 liquidity, - uint256 feeGrowthInside0LastX128, - uint256 feeGrowthInside1LastX128, - uint128 tokensOwed0, - uint128 tokensOwed1 - ); - - struct MintParams { - address token0; - address token1; - uint24 fee; - int24 tickLower; - int24 tickUpper; - uint256 amount0Desired; - uint256 amount1Desired; - uint256 amount0Min; - uint256 amount1Min; - address recipient; - uint256 deadline; - } - - /// @notice Creates a new position wrapped in a NFT - /// @dev Call this when the pool does exist and is initialized. Note that if the pool is created but not initialized - /// a method does not exist, i.e. the pool is assumed to be initialized. - /// @param params The params necessary to mint a position, encoded as `MintParams` in calldata - /// @return tokenId The ID of the token that represents the minted position - /// @return liquidity The amount of liquidity for this position - /// @return amount0 The amount of token0 - /// @return amount1 The amount of token1 - function mint(MintParams calldata params) - external - payable - returns ( - uint256 tokenId, - uint128 liquidity, - uint256 amount0, - uint256 amount1 - ); - - struct IncreaseLiquidityParams { - uint256 tokenId; - uint256 amount0Desired; - uint256 amount1Desired; - uint256 amount0Min; - uint256 amount1Min; - uint256 deadline; - } - - /// @notice Increases the amount of liquidity in a position, with tokens paid by the `msg.sender` - /// @param params tokenId The ID of the token for which liquidity is being increased, - /// amount0Desired The desired amount of token0 to be spent, - /// amount1Desired The desired amount of token1 to be spent, - /// amount0Min The minimum amount of token0 to spend, which serves as a slippage check, - /// amount1Min The minimum amount of token1 to spend, which serves as a slippage check, - /// deadline The time by which the transaction must be included to effect the change - /// @return liquidity The new liquidity amount as a result of the increase - /// @return amount0 The amount of token0 to acheive resulting liquidity - /// @return amount1 The amount of token1 to acheive resulting liquidity - function increaseLiquidity(IncreaseLiquidityParams calldata params) - external - payable - returns ( - uint128 liquidity, - uint256 amount0, - uint256 amount1 - ); - - struct DecreaseLiquidityParams { - uint256 tokenId; - uint128 liquidity; - uint256 amount0Min; - uint256 amount1Min; - uint256 deadline; - } - - /// @notice Decreases the amount of liquidity in a position and accounts it to the position - /// @param params tokenId The ID of the token for which liquidity is being decreased, - /// amount The amount by which liquidity will be decreased, - /// amount0Min The minimum amount of token0 that should be accounted for the burned liquidity, - /// amount1Min The minimum amount of token1 that should be accounted for the burned liquidity, - /// deadline The time by which the transaction must be included to effect the change - /// @return amount0 The amount of token0 accounted to the position's tokens owed - /// @return amount1 The amount of token1 accounted to the position's tokens owed - function decreaseLiquidity(DecreaseLiquidityParams calldata params) - external - payable - returns (uint256 amount0, uint256 amount1); - - struct CollectParams { - uint256 tokenId; - address recipient; - uint128 amount0Max; - uint128 amount1Max; - } - - /// @notice Collects up to a maximum amount of fees owed to a specific position to the recipient - /// @param params tokenId The ID of the NFT for which tokens are being collected, - /// recipient The account that should receive the tokens, - /// amount0Max The maximum amount of token0 to collect, - /// amount1Max The maximum amount of token1 to collect - /// @return amount0 The amount of fees collected in token0 - /// @return amount1 The amount of fees collected in token1 - function collect(CollectParams calldata params) external payable returns (uint256 amount0, uint256 amount1); - - /// @notice Burns a token ID, which deletes it from the NFT contract. The token must have 0 liquidity and all tokens - /// must be collected first. - /// @param tokenId The ID of the token that is being burned - function burn(uint256 tokenId) external payable; -} diff --git a/lib/v3-periphery/contracts/interfaces/INonfungibleTokenPositionDescriptor.sol b/lib/v3-periphery/contracts/interfaces/INonfungibleTokenPositionDescriptor.sol deleted file mode 100644 index b3f27b8..0000000 --- a/lib/v3-periphery/contracts/interfaces/INonfungibleTokenPositionDescriptor.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -import './INonfungiblePositionManager.sol'; - -/// @title Describes position NFT tokens via URI -interface INonfungibleTokenPositionDescriptor { - /// @notice Produces the URI describing a particular token ID for a position manager - /// @dev Note this URI may be a data: URI with the JSON contents directly inlined - /// @param positionManager The position manager for which to describe the token - /// @param tokenId The ID of the token for which to produce a description, which may not be valid - /// @return The URI of the ERC721-compliant metadata - function tokenURI(INonfungiblePositionManager positionManager, uint256 tokenId) - external - view - returns (string memory); -} diff --git a/lib/v3-periphery/contracts/interfaces/IPeripheryImmutableState.sol b/lib/v3-periphery/contracts/interfaces/IPeripheryImmutableState.sol deleted file mode 100644 index b337805..0000000 --- a/lib/v3-periphery/contracts/interfaces/IPeripheryImmutableState.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title Immutable state -/// @notice Functions that return immutable state of the router -interface IPeripheryImmutableState { - /// @return Returns the address of the Uniswap V3 factory - function factory() external view returns (address); - - /// @return Returns the address of WETH9 - function WETH9() external view returns (address); -} diff --git a/lib/v3-periphery/contracts/interfaces/IPeripheryPayments.sol b/lib/v3-periphery/contracts/interfaces/IPeripheryPayments.sol deleted file mode 100644 index ac74f8c..0000000 --- a/lib/v3-periphery/contracts/interfaces/IPeripheryPayments.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.7.5; - -/// @title Periphery Payments -/// @notice Functions to ease deposits and withdrawals of ETH -interface IPeripheryPayments { - /// @notice Unwraps the contract's WETH9 balance and sends it to recipient as ETH. - /// @dev The amountMinimum parameter prevents malicious contracts from stealing WETH9 from users. - /// @param amountMinimum The minimum amount of WETH9 to unwrap - /// @param recipient The address receiving ETH - function unwrapWETH9(uint256 amountMinimum, address recipient) external payable; - - /// @notice Refunds any ETH balance held by this contract to the `msg.sender` - /// @dev Useful for bundling with mint or increase liquidity that uses ether, or exact output swaps - /// that use ether for the input amount - function refundETH() external payable; - - /// @notice Transfers the full amount of a token held by this contract to recipient - /// @dev The amountMinimum parameter prevents malicious contracts from stealing the token from users - /// @param token The contract address of the token which will be transferred to `recipient` - /// @param amountMinimum The minimum amount of token required for a transfer - /// @param recipient The destination address of the token - function sweepToken( - address token, - uint256 amountMinimum, - address recipient - ) external payable; -} diff --git a/lib/v3-periphery/contracts/interfaces/IPeripheryPaymentsWithFee.sol b/lib/v3-periphery/contracts/interfaces/IPeripheryPaymentsWithFee.sol deleted file mode 100644 index 907e446..0000000 --- a/lib/v3-periphery/contracts/interfaces/IPeripheryPaymentsWithFee.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.7.5; - -import './IPeripheryPayments.sol'; - -/// @title Periphery Payments -/// @notice Functions to ease deposits and withdrawals of ETH -interface IPeripheryPaymentsWithFee is IPeripheryPayments { - /// @notice Unwraps the contract's WETH9 balance and sends it to recipient as ETH, with a percentage between - /// 0 (exclusive), and 1 (inclusive) going to feeRecipient - /// @dev The amountMinimum parameter prevents malicious contracts from stealing WETH9 from users. - function unwrapWETH9WithFee( - uint256 amountMinimum, - address recipient, - uint256 feeBips, - address feeRecipient - ) external payable; - - /// @notice Transfers the full amount of a token held by this contract to recipient, with a percentage between - /// 0 (exclusive) and 1 (inclusive) going to feeRecipient - /// @dev The amountMinimum parameter prevents malicious contracts from stealing the token from users - function sweepTokenWithFee( - address token, - uint256 amountMinimum, - address recipient, - uint256 feeBips, - address feeRecipient - ) external payable; -} diff --git a/lib/v3-periphery/contracts/interfaces/IPoolInitializer.sol b/lib/v3-periphery/contracts/interfaces/IPoolInitializer.sol deleted file mode 100644 index d2949b3..0000000 --- a/lib/v3-periphery/contracts/interfaces/IPoolInitializer.sol +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.7.5; -pragma abicoder v2; - -/// @title Creates and initializes V3 Pools -/// @notice Provides a method for creating and initializing a pool, if necessary, for bundling with other methods that -/// require the pool to exist. -interface IPoolInitializer { - /// @notice Creates a new pool if it does not exist, then initializes if not initialized - /// @dev This method can be bundled with others via IMulticall for the first action (e.g. mint) performed against a pool - /// @param token0 The contract address of token0 of the pool - /// @param token1 The contract address of token1 of the pool - /// @param fee The fee amount of the v3 pool for the specified token pair - /// @param sqrtPriceX96 The initial square root price of the pool as a Q64.96 value - /// @return pool Returns the pool address based on the pair of tokens and fee, will return the newly created pool address if necessary - function createAndInitializePoolIfNecessary( - address token0, - address token1, - uint24 fee, - uint160 sqrtPriceX96 - ) external payable returns (address pool); -} diff --git a/lib/v3-periphery/contracts/interfaces/IQuoter.sol b/lib/v3-periphery/contracts/interfaces/IQuoter.sol deleted file mode 100644 index 3410e0c..0000000 --- a/lib/v3-periphery/contracts/interfaces/IQuoter.sol +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.7.5; -pragma abicoder v2; - -/// @title Quoter Interface -/// @notice Supports quoting the calculated amounts from exact input or exact output swaps -/// @dev These functions are not marked view because they rely on calling non-view functions and reverting -/// to compute the result. They are also not gas efficient and should not be called on-chain. -interface IQuoter { - /// @notice Returns the amount out received for a given exact input swap without executing the swap - /// @param path The path of the swap, i.e. each token pair and the pool fee - /// @param amountIn The amount of the first token to swap - /// @return amountOut The amount of the last token that would be received - function quoteExactInput(bytes memory path, uint256 amountIn) external returns (uint256 amountOut); - - /// @notice Returns the amount out received for a given exact input but for a swap of a single pool - /// @param tokenIn The token being swapped in - /// @param tokenOut The token being swapped out - /// @param fee The fee of the token pool to consider for the pair - /// @param amountIn The desired input amount - /// @param sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap - /// @return amountOut The amount of `tokenOut` that would be received - function quoteExactInputSingle( - address tokenIn, - address tokenOut, - uint24 fee, - uint256 amountIn, - uint160 sqrtPriceLimitX96 - ) external returns (uint256 amountOut); - - /// @notice Returns the amount in required for a given exact output swap without executing the swap - /// @param path The path of the swap, i.e. each token pair and the pool fee. Path must be provided in reverse order - /// @param amountOut The amount of the last token to receive - /// @return amountIn The amount of first token required to be paid - function quoteExactOutput(bytes memory path, uint256 amountOut) external returns (uint256 amountIn); - - /// @notice Returns the amount in required to receive the given exact output amount but for a swap of a single pool - /// @param tokenIn The token being swapped in - /// @param tokenOut The token being swapped out - /// @param fee The fee of the token pool to consider for the pair - /// @param amountOut The desired output amount - /// @param sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap - /// @return amountIn The amount required as the input for the swap in order to receive `amountOut` - function quoteExactOutputSingle( - address tokenIn, - address tokenOut, - uint24 fee, - uint256 amountOut, - uint160 sqrtPriceLimitX96 - ) external returns (uint256 amountIn); -} diff --git a/lib/v3-periphery/contracts/interfaces/IQuoterV2.sol b/lib/v3-periphery/contracts/interfaces/IQuoterV2.sol deleted file mode 100644 index 3c2961b..0000000 --- a/lib/v3-periphery/contracts/interfaces/IQuoterV2.sol +++ /dev/null @@ -1,98 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.7.5; -pragma abicoder v2; - -/// @title QuoterV2 Interface -/// @notice Supports quoting the calculated amounts from exact input or exact output swaps. -/// @notice For each pool also tells you the number of initialized ticks crossed and the sqrt price of the pool after the swap. -/// @dev These functions are not marked view because they rely on calling non-view functions and reverting -/// to compute the result. They are also not gas efficient and should not be called on-chain. -interface IQuoterV2 { - /// @notice Returns the amount out received for a given exact input swap without executing the swap - /// @param path The path of the swap, i.e. each token pair and the pool fee - /// @param amountIn The amount of the first token to swap - /// @return amountOut The amount of the last token that would be received - /// @return sqrtPriceX96AfterList List of the sqrt price after the swap for each pool in the path - /// @return initializedTicksCrossedList List of the initialized ticks that the swap crossed for each pool in the path - /// @return gasEstimate The estimate of the gas that the swap consumes - function quoteExactInput(bytes memory path, uint256 amountIn) - external - returns ( - uint256 amountOut, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksCrossedList, - uint256 gasEstimate - ); - - struct QuoteExactInputSingleParams { - address tokenIn; - address tokenOut; - uint256 amountIn; - uint24 fee; - uint160 sqrtPriceLimitX96; - } - - /// @notice Returns the amount out received for a given exact input but for a swap of a single pool - /// @param params The params for the quote, encoded as `QuoteExactInputSingleParams` - /// tokenIn The token being swapped in - /// tokenOut The token being swapped out - /// fee The fee of the token pool to consider for the pair - /// amountIn The desired input amount - /// sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap - /// @return amountOut The amount of `tokenOut` that would be received - /// @return sqrtPriceX96After The sqrt price of the pool after the swap - /// @return initializedTicksCrossed The number of initialized ticks that the swap crossed - /// @return gasEstimate The estimate of the gas that the swap consumes - function quoteExactInputSingle(QuoteExactInputSingleParams memory params) - external - returns ( - uint256 amountOut, - uint160 sqrtPriceX96After, - uint32 initializedTicksCrossed, - uint256 gasEstimate - ); - - /// @notice Returns the amount in required for a given exact output swap without executing the swap - /// @param path The path of the swap, i.e. each token pair and the pool fee. Path must be provided in reverse order - /// @param amountOut The amount of the last token to receive - /// @return amountIn The amount of first token required to be paid - /// @return sqrtPriceX96AfterList List of the sqrt price after the swap for each pool in the path - /// @return initializedTicksCrossedList List of the initialized ticks that the swap crossed for each pool in the path - /// @return gasEstimate The estimate of the gas that the swap consumes - function quoteExactOutput(bytes memory path, uint256 amountOut) - external - returns ( - uint256 amountIn, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksCrossedList, - uint256 gasEstimate - ); - - struct QuoteExactOutputSingleParams { - address tokenIn; - address tokenOut; - uint256 amount; - uint24 fee; - uint160 sqrtPriceLimitX96; - } - - /// @notice Returns the amount in required to receive the given exact output amount but for a swap of a single pool - /// @param params The params for the quote, encoded as `QuoteExactOutputSingleParams` - /// tokenIn The token being swapped in - /// tokenOut The token being swapped out - /// fee The fee of the token pool to consider for the pair - /// amountOut The desired output amount - /// sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap - /// @return amountIn The amount required as the input for the swap in order to receive `amountOut` - /// @return sqrtPriceX96After The sqrt price of the pool after the swap - /// @return initializedTicksCrossed The number of initialized ticks that the swap crossed - /// @return gasEstimate The estimate of the gas that the swap consumes - function quoteExactOutputSingle(QuoteExactOutputSingleParams memory params) - external - returns ( - uint256 amountIn, - uint160 sqrtPriceX96After, - uint32 initializedTicksCrossed, - uint256 gasEstimate - ); -} diff --git a/lib/v3-periphery/contracts/interfaces/ISelfPermit.sol b/lib/v3-periphery/contracts/interfaces/ISelfPermit.sol deleted file mode 100644 index 0ab8a25..0000000 --- a/lib/v3-periphery/contracts/interfaces/ISelfPermit.sol +++ /dev/null @@ -1,76 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.7.5; - -/// @title Self Permit -/// @notice Functionality to call permit on any EIP-2612-compliant token for use in the route -interface ISelfPermit { - /// @notice Permits this contract to spend a given token from `msg.sender` - /// @dev The `owner` is always msg.sender and the `spender` is always address(this). - /// @param token The address of the token spent - /// @param value The amount that can be spent of token - /// @param deadline A timestamp, the current blocktime must be less than or equal to this timestamp - /// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s` - /// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s` - /// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v` - function selfPermit( - address token, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) external payable; - - /// @notice Permits this contract to spend a given token from `msg.sender` - /// @dev The `owner` is always msg.sender and the `spender` is always address(this). - /// Can be used instead of #selfPermit to prevent calls from failing due to a frontrun of a call to #selfPermit - /// @param token The address of the token spent - /// @param value The amount that can be spent of token - /// @param deadline A timestamp, the current blocktime must be less than or equal to this timestamp - /// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s` - /// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s` - /// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v` - function selfPermitIfNecessary( - address token, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) external payable; - - /// @notice Permits this contract to spend the sender's tokens for permit signatures that have the `allowed` parameter - /// @dev The `owner` is always msg.sender and the `spender` is always address(this) - /// @param token The address of the token spent - /// @param nonce The current nonce of the owner - /// @param expiry The timestamp at which the permit is no longer valid - /// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s` - /// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s` - /// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v` - function selfPermitAllowed( - address token, - uint256 nonce, - uint256 expiry, - uint8 v, - bytes32 r, - bytes32 s - ) external payable; - - /// @notice Permits this contract to spend the sender's tokens for permit signatures that have the `allowed` parameter - /// @dev The `owner` is always msg.sender and the `spender` is always address(this) - /// Can be used instead of #selfPermitAllowed to prevent calls from failing due to a frontrun of a call to #selfPermitAllowed. - /// @param token The address of the token spent - /// @param nonce The current nonce of the owner - /// @param expiry The timestamp at which the permit is no longer valid - /// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s` - /// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s` - /// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v` - function selfPermitAllowedIfNecessary( - address token, - uint256 nonce, - uint256 expiry, - uint8 v, - bytes32 r, - bytes32 s - ) external payable; -} diff --git a/lib/v3-periphery/contracts/interfaces/ISwapRouter.sol b/lib/v3-periphery/contracts/interfaces/ISwapRouter.sol deleted file mode 100644 index 35806a2..0000000 --- a/lib/v3-periphery/contracts/interfaces/ISwapRouter.sol +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.7.5; -pragma abicoder v2; - -import '@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol'; - -/// @title Router token swapping functionality -/// @notice Functions for swapping tokens via Uniswap V3 -interface ISwapRouter is IUniswapV3SwapCallback { - struct ExactInputSingleParams { - address tokenIn; - address tokenOut; - uint24 fee; - address recipient; - uint256 deadline; - uint256 amountIn; - uint256 amountOutMinimum; - uint160 sqrtPriceLimitX96; - } - - /// @notice Swaps `amountIn` of one token for as much as possible of another token - /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata - /// @return amountOut The amount of the received token - function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut); - - struct ExactInputParams { - bytes path; - address recipient; - uint256 deadline; - uint256 amountIn; - uint256 amountOutMinimum; - } - - /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path - /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata - /// @return amountOut The amount of the received token - function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut); - - struct ExactOutputSingleParams { - address tokenIn; - address tokenOut; - uint24 fee; - address recipient; - uint256 deadline; - uint256 amountOut; - uint256 amountInMaximum; - uint160 sqrtPriceLimitX96; - } - - /// @notice Swaps as little as possible of one token for `amountOut` of another token - /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata - /// @return amountIn The amount of the input token - function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn); - - struct ExactOutputParams { - bytes path; - address recipient; - uint256 deadline; - uint256 amountOut; - uint256 amountInMaximum; - } - - /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed) - /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata - /// @return amountIn The amount of the input token - function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn); -} diff --git a/lib/v3-periphery/contracts/interfaces/ITickLens.sol b/lib/v3-periphery/contracts/interfaces/ITickLens.sol deleted file mode 100644 index 89bac2d..0000000 --- a/lib/v3-periphery/contracts/interfaces/ITickLens.sol +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.7.5; -pragma abicoder v2; - -/// @title Tick Lens -/// @notice Provides functions for fetching chunks of tick data for a pool -/// @dev This avoids the waterfall of fetching the tick bitmap, parsing the bitmap to know which ticks to fetch, and -/// then sending additional multicalls to fetch the tick data -interface ITickLens { - struct PopulatedTick { - int24 tick; - int128 liquidityNet; - uint128 liquidityGross; - } - - /// @notice Get all the tick data for the populated ticks from a word of the tick bitmap of a pool - /// @param pool The address of the pool for which to fetch populated tick data - /// @param tickBitmapIndex The index of the word in the tick bitmap for which to parse the bitmap and - /// fetch all the populated ticks - /// @return populatedTicks An array of tick data for the given word in the tick bitmap - function getPopulatedTicksInWord(address pool, int16 tickBitmapIndex) - external - view - returns (PopulatedTick[] memory populatedTicks); -} diff --git a/lib/v3-periphery/contracts/interfaces/IV3Migrator.sol b/lib/v3-periphery/contracts/interfaces/IV3Migrator.sol deleted file mode 100644 index 6eb6e42..0000000 --- a/lib/v3-periphery/contracts/interfaces/IV3Migrator.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.7.5; -pragma abicoder v2; - -import './IMulticall.sol'; -import './ISelfPermit.sol'; -import './IPoolInitializer.sol'; - -/// @title V3 Migrator -/// @notice Enables migration of liqudity from Uniswap v2-compatible pairs into Uniswap v3 pools -interface IV3Migrator is IMulticall, ISelfPermit, IPoolInitializer { - struct MigrateParams { - address pair; // the Uniswap v2-compatible pair - uint256 liquidityToMigrate; // expected to be balanceOf(msg.sender) - uint8 percentageToMigrate; // represented as a numerator over 100 - address token0; - address token1; - uint24 fee; - int24 tickLower; - int24 tickUpper; - uint256 amount0Min; // must be discounted by percentageToMigrate - uint256 amount1Min; // must be discounted by percentageToMigrate - address recipient; - uint256 deadline; - bool refundAsETH; - } - - /// @notice Migrates liquidity to v3 by burning v2 liquidity and minting a new position for v3 - /// @dev Slippage protection is enforced via `amount{0,1}Min`, which should be a discount of the expected values of - /// the maximum amount of v3 liquidity that the v2 liquidity can get. For the special case of migrating to an - /// out-of-range position, `amount{0,1}Min` may be set to 0, enforcing that the position remains out of range - /// @param params The params necessary to migrate v2 liquidity, encoded as `MigrateParams` in calldata - function migrate(MigrateParams calldata params) external; -} diff --git a/lib/v3-periphery/contracts/interfaces/external/IERC1271.sol b/lib/v3-periphery/contracts/interfaces/external/IERC1271.sol deleted file mode 100644 index 824b03e..0000000 --- a/lib/v3-periphery/contracts/interfaces/external/IERC1271.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title Interface for verifying contract-based account signatures -/// @notice Interface that verifies provided signature for the data -/// @dev Interface defined by EIP-1271 -interface IERC1271 { - /// @notice Returns whether the provided signature is valid for the provided data - /// @dev MUST return the bytes4 magic value 0x1626ba7e when function passes. - /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5). - /// MUST allow external calls. - /// @param hash Hash of the data to be signed - /// @param signature Signature byte array associated with _data - /// @return magicValue The bytes4 magic value 0x1626ba7e - function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue); -} diff --git a/lib/v3-periphery/contracts/interfaces/external/IERC20PermitAllowed.sol b/lib/v3-periphery/contracts/interfaces/external/IERC20PermitAllowed.sol deleted file mode 100644 index a817e1c..0000000 --- a/lib/v3-periphery/contracts/interfaces/external/IERC20PermitAllowed.sol +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title Interface for permit -/// @notice Interface used by DAI/CHAI for permit -interface IERC20PermitAllowed { - /// @notice Approve the spender to spend some tokens via the holder signature - /// @dev This is the permit interface used by DAI and CHAI - /// @param holder The address of the token holder, the token owner - /// @param spender The address of the token spender - /// @param nonce The holder's nonce, increases at each call to permit - /// @param expiry The timestamp at which the permit is no longer valid - /// @param allowed Boolean that sets approval amount, true for type(uint256).max and false for 0 - /// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s` - /// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s` - /// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v` - function permit( - address holder, - address spender, - uint256 nonce, - uint256 expiry, - bool allowed, - uint8 v, - bytes32 r, - bytes32 s - ) external; -} diff --git a/lib/v3-periphery/contracts/interfaces/external/IWETH9.sol b/lib/v3-periphery/contracts/interfaces/external/IWETH9.sol deleted file mode 100644 index 58ab43e..0000000 --- a/lib/v3-periphery/contracts/interfaces/external/IWETH9.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity =0.7.6; - -import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; - -/// @title Interface for WETH9 -interface IWETH9 is IERC20 { - /// @notice Deposit ether to get wrapped ether - function deposit() external payable; - - /// @notice Withdraw wrapped ether to get ether - function withdraw(uint256) external; -} diff --git a/lib/v3-periphery/contracts/lens/Quoter.sol b/lib/v3-periphery/contracts/lens/Quoter.sol deleted file mode 100644 index f4a9ed6..0000000 --- a/lib/v3-periphery/contracts/lens/Quoter.sol +++ /dev/null @@ -1,170 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity =0.7.6; -pragma abicoder v2; - -import '@uniswap/v3-core/contracts/libraries/SafeCast.sol'; -import '@uniswap/v3-core/contracts/libraries/TickMath.sol'; -import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol'; -import '@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol'; - -import '../interfaces/IQuoter.sol'; -import '../base/PeripheryImmutableState.sol'; -import '../libraries/Path.sol'; -import '../libraries/PoolAddress.sol'; -import '../libraries/CallbackValidation.sol'; - -/// @title Provides quotes for swaps -/// @notice Allows getting the expected amount out or amount in for a given swap without executing the swap -/// @dev These functions are not gas efficient and should _not_ be called on chain. Instead, optimistically execute -/// the swap and check the amounts in the callback. -contract Quoter is IQuoter, IUniswapV3SwapCallback, PeripheryImmutableState { - using Path for bytes; - using SafeCast for uint256; - - /// @dev Transient storage variable used to check a safety condition in exact output swaps. - uint256 private amountOutCached; - - constructor(address _factory, address _WETH9) PeripheryImmutableState(_factory, _WETH9) {} - - function getPool( - address tokenA, - address tokenB, - uint24 fee - ) private view returns (IUniswapV3Pool) { - return IUniswapV3Pool(PoolAddress.computeAddress(factory, PoolAddress.getPoolKey(tokenA, tokenB, fee))); - } - - /// @inheritdoc IUniswapV3SwapCallback - function uniswapV3SwapCallback( - int256 amount0Delta, - int256 amount1Delta, - bytes memory path - ) external view override { - require(amount0Delta > 0 || amount1Delta > 0); // swaps entirely within 0-liquidity regions are not supported - (address tokenIn, address tokenOut, uint24 fee) = path.decodeFirstPool(); - CallbackValidation.verifyCallback(factory, tokenIn, tokenOut, fee); - - (bool isExactInput, uint256 amountToPay, uint256 amountReceived) = - amount0Delta > 0 - ? (tokenIn < tokenOut, uint256(amount0Delta), uint256(-amount1Delta)) - : (tokenOut < tokenIn, uint256(amount1Delta), uint256(-amount0Delta)); - if (isExactInput) { - assembly { - let ptr := mload(0x40) - mstore(ptr, amountReceived) - revert(ptr, 32) - } - } else { - // if the cache has been populated, ensure that the full output amount has been received - if (amountOutCached != 0) require(amountReceived == amountOutCached); - assembly { - let ptr := mload(0x40) - mstore(ptr, amountToPay) - revert(ptr, 32) - } - } - } - - /// @dev Parses a revert reason that should contain the numeric quote - function parseRevertReason(bytes memory reason) private pure returns (uint256) { - if (reason.length != 32) { - if (reason.length < 68) revert('Unexpected error'); - assembly { - reason := add(reason, 0x04) - } - revert(abi.decode(reason, (string))); - } - return abi.decode(reason, (uint256)); - } - - /// @inheritdoc IQuoter - function quoteExactInputSingle( - address tokenIn, - address tokenOut, - uint24 fee, - uint256 amountIn, - uint160 sqrtPriceLimitX96 - ) public override returns (uint256 amountOut) { - bool zeroForOne = tokenIn < tokenOut; - - try - getPool(tokenIn, tokenOut, fee).swap( - address(this), // address(0) might cause issues with some tokens - zeroForOne, - amountIn.toInt256(), - sqrtPriceLimitX96 == 0 - ? (zeroForOne ? TickMath.MIN_SQRT_RATIO + 1 : TickMath.MAX_SQRT_RATIO - 1) - : sqrtPriceLimitX96, - abi.encodePacked(tokenIn, fee, tokenOut) - ) - {} catch (bytes memory reason) { - return parseRevertReason(reason); - } - } - - /// @inheritdoc IQuoter - function quoteExactInput(bytes memory path, uint256 amountIn) external override returns (uint256 amountOut) { - while (true) { - bool hasMultiplePools = path.hasMultiplePools(); - - (address tokenIn, address tokenOut, uint24 fee) = path.decodeFirstPool(); - - // the outputs of prior swaps become the inputs to subsequent ones - amountIn = quoteExactInputSingle(tokenIn, tokenOut, fee, amountIn, 0); - - // decide whether to continue or terminate - if (hasMultiplePools) { - path = path.skipToken(); - } else { - return amountIn; - } - } - } - - /// @inheritdoc IQuoter - function quoteExactOutputSingle( - address tokenIn, - address tokenOut, - uint24 fee, - uint256 amountOut, - uint160 sqrtPriceLimitX96 - ) public override returns (uint256 amountIn) { - bool zeroForOne = tokenIn < tokenOut; - - // if no price limit has been specified, cache the output amount for comparison in the swap callback - if (sqrtPriceLimitX96 == 0) amountOutCached = amountOut; - try - getPool(tokenIn, tokenOut, fee).swap( - address(this), // address(0) might cause issues with some tokens - zeroForOne, - -amountOut.toInt256(), - sqrtPriceLimitX96 == 0 - ? (zeroForOne ? TickMath.MIN_SQRT_RATIO + 1 : TickMath.MAX_SQRT_RATIO - 1) - : sqrtPriceLimitX96, - abi.encodePacked(tokenOut, fee, tokenIn) - ) - {} catch (bytes memory reason) { - if (sqrtPriceLimitX96 == 0) delete amountOutCached; // clear cache - return parseRevertReason(reason); - } - } - - /// @inheritdoc IQuoter - function quoteExactOutput(bytes memory path, uint256 amountOut) external override returns (uint256 amountIn) { - while (true) { - bool hasMultiplePools = path.hasMultiplePools(); - - (address tokenOut, address tokenIn, uint24 fee) = path.decodeFirstPool(); - - // the inputs of prior swaps become the outputs of subsequent ones - amountOut = quoteExactOutputSingle(tokenIn, tokenOut, fee, amountOut, 0); - - // decide whether to continue or terminate - if (hasMultiplePools) { - path = path.skipToken(); - } else { - return amountOut; - } - } - } -} diff --git a/lib/v3-periphery/contracts/lens/QuoterV2.sol b/lib/v3-periphery/contracts/lens/QuoterV2.sol deleted file mode 100644 index b82dddd..0000000 --- a/lib/v3-periphery/contracts/lens/QuoterV2.sol +++ /dev/null @@ -1,273 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity =0.7.6; -pragma abicoder v2; - -import '@uniswap/v3-core/contracts/libraries/SafeCast.sol'; -import '@uniswap/v3-core/contracts/libraries/TickMath.sol'; -import '@uniswap/v3-core/contracts/libraries/TickBitmap.sol'; -import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol'; -import '@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol'; - -import '../interfaces/IQuoterV2.sol'; -import '../base/PeripheryImmutableState.sol'; -import '../libraries/Path.sol'; -import '../libraries/PoolAddress.sol'; -import '../libraries/CallbackValidation.sol'; -import '../libraries/PoolTicksCounter.sol'; - -/// @title Provides quotes for swaps -/// @notice Allows getting the expected amount out or amount in for a given swap without executing the swap -/// @dev These functions are not gas efficient and should _not_ be called on chain. Instead, optimistically execute -/// the swap and check the amounts in the callback. -contract QuoterV2 is IQuoterV2, IUniswapV3SwapCallback, PeripheryImmutableState { - using Path for bytes; - using SafeCast for uint256; - using PoolTicksCounter for IUniswapV3Pool; - - /// @dev Transient storage variable used to check a safety condition in exact output swaps. - uint256 private amountOutCached; - - constructor(address _factory, address _WETH9) PeripheryImmutableState(_factory, _WETH9) {} - - function getPool( - address tokenA, - address tokenB, - uint24 fee - ) private view returns (IUniswapV3Pool) { - return IUniswapV3Pool(PoolAddress.computeAddress(factory, PoolAddress.getPoolKey(tokenA, tokenB, fee))); - } - - /// @inheritdoc IUniswapV3SwapCallback - function uniswapV3SwapCallback( - int256 amount0Delta, - int256 amount1Delta, - bytes memory path - ) external view override { - require(amount0Delta > 0 || amount1Delta > 0); // swaps entirely within 0-liquidity regions are not supported - (address tokenIn, address tokenOut, uint24 fee) = path.decodeFirstPool(); - CallbackValidation.verifyCallback(factory, tokenIn, tokenOut, fee); - - (bool isExactInput, uint256 amountToPay, uint256 amountReceived) = - amount0Delta > 0 - ? (tokenIn < tokenOut, uint256(amount0Delta), uint256(-amount1Delta)) - : (tokenOut < tokenIn, uint256(amount1Delta), uint256(-amount0Delta)); - - IUniswapV3Pool pool = getPool(tokenIn, tokenOut, fee); - (uint160 sqrtPriceX96After, int24 tickAfter, , , , , ) = pool.slot0(); - - if (isExactInput) { - assembly { - let ptr := mload(0x40) - mstore(ptr, amountReceived) - mstore(add(ptr, 0x20), sqrtPriceX96After) - mstore(add(ptr, 0x40), tickAfter) - revert(ptr, 96) - } - } else { - // if the cache has been populated, ensure that the full output amount has been received - if (amountOutCached != 0) require(amountReceived == amountOutCached); - assembly { - let ptr := mload(0x40) - mstore(ptr, amountToPay) - mstore(add(ptr, 0x20), sqrtPriceX96After) - mstore(add(ptr, 0x40), tickAfter) - revert(ptr, 96) - } - } - } - - /// @dev Parses a revert reason that should contain the numeric quote - function parseRevertReason(bytes memory reason) - private - pure - returns ( - uint256 amount, - uint160 sqrtPriceX96After, - int24 tickAfter - ) - { - if (reason.length != 96) { - if (reason.length < 68) revert('Unexpected error'); - assembly { - reason := add(reason, 0x04) - } - revert(abi.decode(reason, (string))); - } - return abi.decode(reason, (uint256, uint160, int24)); - } - - function handleRevert( - bytes memory reason, - IUniswapV3Pool pool, - uint256 gasEstimate - ) - private - view - returns ( - uint256 amount, - uint160 sqrtPriceX96After, - uint32 initializedTicksCrossed, - uint256 - ) - { - int24 tickBefore; - int24 tickAfter; - (, tickBefore, , , , , ) = pool.slot0(); - (amount, sqrtPriceX96After, tickAfter) = parseRevertReason(reason); - - initializedTicksCrossed = pool.countInitializedTicksCrossed(tickBefore, tickAfter); - - return (amount, sqrtPriceX96After, initializedTicksCrossed, gasEstimate); - } - - function quoteExactInputSingle(QuoteExactInputSingleParams memory params) - public - override - returns ( - uint256 amountOut, - uint160 sqrtPriceX96After, - uint32 initializedTicksCrossed, - uint256 gasEstimate - ) - { - bool zeroForOne = params.tokenIn < params.tokenOut; - IUniswapV3Pool pool = getPool(params.tokenIn, params.tokenOut, params.fee); - - uint256 gasBefore = gasleft(); - try - pool.swap( - address(this), // address(0) might cause issues with some tokens - zeroForOne, - params.amountIn.toInt256(), - params.sqrtPriceLimitX96 == 0 - ? (zeroForOne ? TickMath.MIN_SQRT_RATIO + 1 : TickMath.MAX_SQRT_RATIO - 1) - : params.sqrtPriceLimitX96, - abi.encodePacked(params.tokenIn, params.fee, params.tokenOut) - ) - {} catch (bytes memory reason) { - gasEstimate = gasBefore - gasleft(); - return handleRevert(reason, pool, gasEstimate); - } - } - - function quoteExactInput(bytes memory path, uint256 amountIn) - public - override - returns ( - uint256 amountOut, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksCrossedList, - uint256 gasEstimate - ) - { - sqrtPriceX96AfterList = new uint160[](path.numPools()); - initializedTicksCrossedList = new uint32[](path.numPools()); - - uint256 i = 0; - while (true) { - (address tokenIn, address tokenOut, uint24 fee) = path.decodeFirstPool(); - - // the outputs of prior swaps become the inputs to subsequent ones - (uint256 _amountOut, uint160 _sqrtPriceX96After, uint32 _initializedTicksCrossed, uint256 _gasEstimate) = - quoteExactInputSingle( - QuoteExactInputSingleParams({ - tokenIn: tokenIn, - tokenOut: tokenOut, - fee: fee, - amountIn: amountIn, - sqrtPriceLimitX96: 0 - }) - ); - - sqrtPriceX96AfterList[i] = _sqrtPriceX96After; - initializedTicksCrossedList[i] = _initializedTicksCrossed; - amountIn = _amountOut; - gasEstimate += _gasEstimate; - i++; - - // decide whether to continue or terminate - if (path.hasMultiplePools()) { - path = path.skipToken(); - } else { - return (amountIn, sqrtPriceX96AfterList, initializedTicksCrossedList, gasEstimate); - } - } - } - - function quoteExactOutputSingle(QuoteExactOutputSingleParams memory params) - public - override - returns ( - uint256 amountIn, - uint160 sqrtPriceX96After, - uint32 initializedTicksCrossed, - uint256 gasEstimate - ) - { - bool zeroForOne = params.tokenIn < params.tokenOut; - IUniswapV3Pool pool = getPool(params.tokenIn, params.tokenOut, params.fee); - - // if no price limit has been specified, cache the output amount for comparison in the swap callback - if (params.sqrtPriceLimitX96 == 0) amountOutCached = params.amount; - uint256 gasBefore = gasleft(); - try - pool.swap( - address(this), // address(0) might cause issues with some tokens - zeroForOne, - -params.amount.toInt256(), - params.sqrtPriceLimitX96 == 0 - ? (zeroForOne ? TickMath.MIN_SQRT_RATIO + 1 : TickMath.MAX_SQRT_RATIO - 1) - : params.sqrtPriceLimitX96, - abi.encodePacked(params.tokenOut, params.fee, params.tokenIn) - ) - {} catch (bytes memory reason) { - gasEstimate = gasBefore - gasleft(); - if (params.sqrtPriceLimitX96 == 0) delete amountOutCached; // clear cache - return handleRevert(reason, pool, gasEstimate); - } - } - - function quoteExactOutput(bytes memory path, uint256 amountOut) - public - override - returns ( - uint256 amountIn, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksCrossedList, - uint256 gasEstimate - ) - { - sqrtPriceX96AfterList = new uint160[](path.numPools()); - initializedTicksCrossedList = new uint32[](path.numPools()); - - uint256 i = 0; - while (true) { - (address tokenOut, address tokenIn, uint24 fee) = path.decodeFirstPool(); - - // the inputs of prior swaps become the outputs of subsequent ones - (uint256 _amountIn, uint160 _sqrtPriceX96After, uint32 _initializedTicksCrossed, uint256 _gasEstimate) = - quoteExactOutputSingle( - QuoteExactOutputSingleParams({ - tokenIn: tokenIn, - tokenOut: tokenOut, - amount: amountOut, - fee: fee, - sqrtPriceLimitX96: 0 - }) - ); - - sqrtPriceX96AfterList[i] = _sqrtPriceX96After; - initializedTicksCrossedList[i] = _initializedTicksCrossed; - amountOut = _amountIn; - gasEstimate += _gasEstimate; - i++; - - // decide whether to continue or terminate - if (path.hasMultiplePools()) { - path = path.skipToken(); - } else { - return (amountOut, sqrtPriceX96AfterList, initializedTicksCrossedList, gasEstimate); - } - } - } -} diff --git a/lib/v3-periphery/contracts/lens/README.md b/lib/v3-periphery/contracts/lens/README.md deleted file mode 100644 index 8359711..0000000 --- a/lib/v3-periphery/contracts/lens/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# lens - -These contracts are not designed to be called on-chain. They simplify -fetching on-chain data from off-chain. diff --git a/lib/v3-periphery/contracts/lens/TickLens.sol b/lib/v3-periphery/contracts/lens/TickLens.sol deleted file mode 100644 index 5e9be5f..0000000 --- a/lib/v3-periphery/contracts/lens/TickLens.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; -pragma abicoder v2; - -import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol'; - -import '../interfaces/ITickLens.sol'; - -/// @title Tick Lens contract -contract TickLens is ITickLens { - /// @inheritdoc ITickLens - function getPopulatedTicksInWord(address pool, int16 tickBitmapIndex) - public - view - override - returns (PopulatedTick[] memory populatedTicks) - { - // fetch bitmap - uint256 bitmap = IUniswapV3Pool(pool).tickBitmap(tickBitmapIndex); - - // calculate the number of populated ticks - uint256 numberOfPopulatedTicks; - for (uint256 i = 0; i < 256; i++) { - if (bitmap & (1 << i) > 0) numberOfPopulatedTicks++; - } - - // fetch populated tick data - int24 tickSpacing = IUniswapV3Pool(pool).tickSpacing(); - populatedTicks = new PopulatedTick[](numberOfPopulatedTicks); - for (uint256 i = 0; i < 256; i++) { - if (bitmap & (1 << i) > 0) { - int24 populatedTick = ((int24(tickBitmapIndex) << 8) + int24(i)) * tickSpacing; - (uint128 liquidityGross, int128 liquidityNet, , , , , , ) = IUniswapV3Pool(pool).ticks(populatedTick); - populatedTicks[--numberOfPopulatedTicks] = PopulatedTick({ - tick: populatedTick, - liquidityNet: liquidityNet, - liquidityGross: liquidityGross - }); - } - } - } -} diff --git a/lib/v3-periphery/contracts/lens/UniswapInterfaceMulticall.sol b/lib/v3-periphery/contracts/lens/UniswapInterfaceMulticall.sol deleted file mode 100644 index 54c62c9..0000000 --- a/lib/v3-periphery/contracts/lens/UniswapInterfaceMulticall.sol +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity =0.7.6; -pragma abicoder v2; - -/// @notice A fork of Multicall2 specifically tailored for the Uniswap Interface -contract UniswapInterfaceMulticall { - struct Call { - address target; - uint256 gasLimit; - bytes callData; - } - - struct Result { - bool success; - uint256 gasUsed; - bytes returnData; - } - - function getCurrentBlockTimestamp() public view returns (uint256 timestamp) { - timestamp = block.timestamp; - } - - function getEthBalance(address addr) public view returns (uint256 balance) { - balance = addr.balance; - } - - function multicall(Call[] memory calls) public returns (uint256 blockNumber, Result[] memory returnData) { - blockNumber = block.number; - returnData = new Result[](calls.length); - for (uint256 i = 0; i < calls.length; i++) { - (address target, uint256 gasLimit, bytes memory callData) = - (calls[i].target, calls[i].gasLimit, calls[i].callData); - uint256 gasLeftBefore = gasleft(); - (bool success, bytes memory ret) = target.call{gas: gasLimit}(callData); - uint256 gasUsed = gasLeftBefore - gasleft(); - returnData[i] = Result(success, gasUsed, ret); - } - } -} diff --git a/lib/v3-periphery/contracts/libraries/BytesLib.sol b/lib/v3-periphery/contracts/libraries/BytesLib.sol deleted file mode 100644 index ca1ae84..0000000 --- a/lib/v3-periphery/contracts/libraries/BytesLib.sol +++ /dev/null @@ -1,101 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * @title Solidity Bytes Arrays Utils - * @author Gonçalo Sá - * - * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity. - * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage. - */ -pragma solidity >=0.5.0 <0.8.0; - -library BytesLib { - function slice( - bytes memory _bytes, - uint256 _start, - uint256 _length - ) internal pure returns (bytes memory) { - require(_length + 31 >= _length, 'slice_overflow'); - require(_start + _length >= _start, 'slice_overflow'); - require(_bytes.length >= _start + _length, 'slice_outOfBounds'); - - bytes memory tempBytes; - - assembly { - switch iszero(_length) - case 0 { - // Get a location of some free memory and store it in tempBytes as - // Solidity does for memory variables. - tempBytes := mload(0x40) - - // The first word of the slice result is potentially a partial - // word read from the original array. To read it, we calculate - // the length of that partial word and start copying that many - // bytes into the array. The first word we copy will start with - // data we don't care about, but the last `lengthmod` bytes will - // land at the beginning of the contents of the new array. When - // we're done copying, we overwrite the full first word with - // the actual length of the slice. - let lengthmod := and(_length, 31) - - // The multiplication in the next line is necessary - // because when slicing multiples of 32 bytes (lengthmod == 0) - // the following copy loop was copying the origin's length - // and then ending prematurely not copying everything it should. - let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) - let end := add(mc, _length) - - for { - // The multiplication in the next line has the same exact purpose - // as the one above. - let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) - } lt(mc, end) { - mc := add(mc, 0x20) - cc := add(cc, 0x20) - } { - mstore(mc, mload(cc)) - } - - mstore(tempBytes, _length) - - //update free-memory pointer - //allocating the array padded to 32 bytes like the compiler does now - mstore(0x40, and(add(mc, 31), not(31))) - } - //if we want a zero-length slice let's just return a zero-length array - default { - tempBytes := mload(0x40) - //zero out the 32 bytes slice we are about to return - //we need to do it because Solidity does not garbage collect - mstore(tempBytes, 0) - - mstore(0x40, add(tempBytes, 0x20)) - } - } - - return tempBytes; - } - - function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) { - require(_start + 20 >= _start, 'toAddress_overflow'); - require(_bytes.length >= _start + 20, 'toAddress_outOfBounds'); - address tempAddress; - - assembly { - tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000) - } - - return tempAddress; - } - - function toUint24(bytes memory _bytes, uint256 _start) internal pure returns (uint24) { - require(_start + 3 >= _start, 'toUint24_overflow'); - require(_bytes.length >= _start + 3, 'toUint24_outOfBounds'); - uint24 tempUint; - - assembly { - tempUint := mload(add(add(_bytes, 0x3), _start)) - } - - return tempUint; - } -} diff --git a/lib/v3-periphery/contracts/libraries/CallbackValidation.sol b/lib/v3-periphery/contracts/libraries/CallbackValidation.sol deleted file mode 100644 index 788109f..0000000 --- a/lib/v3-periphery/contracts/libraries/CallbackValidation.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity =0.7.6; - -import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol'; -import './PoolAddress.sol'; - -/// @notice Provides validation for callbacks from Uniswap V3 Pools -library CallbackValidation { - /// @notice Returns the address of a valid Uniswap V3 Pool - /// @param factory The contract address of the Uniswap V3 factory - /// @param tokenA The contract address of either token0 or token1 - /// @param tokenB The contract address of the other token - /// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip - /// @return pool The V3 pool contract address - function verifyCallback( - address factory, - address tokenA, - address tokenB, - uint24 fee - ) internal view returns (IUniswapV3Pool pool) { - return verifyCallback(factory, PoolAddress.getPoolKey(tokenA, tokenB, fee)); - } - - /// @notice Returns the address of a valid Uniswap V3 Pool - /// @param factory The contract address of the Uniswap V3 factory - /// @param poolKey The identifying key of the V3 pool - /// @return pool The V3 pool contract address - function verifyCallback(address factory, PoolAddress.PoolKey memory poolKey) - internal - view - returns (IUniswapV3Pool pool) - { - pool = IUniswapV3Pool(PoolAddress.computeAddress(factory, poolKey)); - require(msg.sender == address(pool)); - } -} diff --git a/lib/v3-periphery/contracts/libraries/ChainId.sol b/lib/v3-periphery/contracts/libraries/ChainId.sol deleted file mode 100644 index 72cb8b7..0000000 --- a/lib/v3-periphery/contracts/libraries/ChainId.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.7.0; - -/// @title Function for getting the current chain ID -library ChainId { - /// @dev Gets the current chain ID - /// @return chainId The current chain ID - function get() internal pure returns (uint256 chainId) { - assembly { - chainId := chainid() - } - } -} diff --git a/lib/v3-periphery/contracts/libraries/HexStrings.sol b/lib/v3-periphery/contracts/libraries/HexStrings.sol deleted file mode 100644 index 8f82288..0000000 --- a/lib/v3-periphery/contracts/libraries/HexStrings.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity =0.7.6; - -library HexStrings { - bytes16 internal constant ALPHABET = '0123456789abcdef'; - - /// @notice Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. - /// @dev Credit to Open Zeppelin under MIT license https://github.com/OpenZeppelin/openzeppelin-contracts/blob/243adff49ce1700e0ecb99fe522fb16cff1d1ddc/contracts/utils/Strings.sol#L55 - 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] = ALPHABET[value & 0xf]; - value >>= 4; - } - require(value == 0, 'Strings: hex length insufficient'); - return string(buffer); - } - - function toHexStringNoPrefix(uint256 value, uint256 length) internal pure returns (string memory) { - bytes memory buffer = new bytes(2 * length); - for (uint256 i = buffer.length; i > 0; i--) { - buffer[i - 1] = ALPHABET[value & 0xf]; - value >>= 4; - } - return string(buffer); - } -} diff --git a/lib/v3-periphery/contracts/libraries/LiquidityAmounts.sol b/lib/v3-periphery/contracts/libraries/LiquidityAmounts.sol deleted file mode 100644 index 1427022..0000000 --- a/lib/v3-periphery/contracts/libraries/LiquidityAmounts.sol +++ /dev/null @@ -1,137 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -import '@uniswap/v3-core/contracts/libraries/FullMath.sol'; -import '@uniswap/v3-core/contracts/libraries/FixedPoint96.sol'; - -/// @title Liquidity amount functions -/// @notice Provides functions for computing liquidity amounts from token amounts and prices -library LiquidityAmounts { - /// @notice Downcasts uint256 to uint128 - /// @param x The uint258 to be downcasted - /// @return y The passed value, downcasted to uint128 - function toUint128(uint256 x) private pure returns (uint128 y) { - require((y = uint128(x)) == x); - } - - /// @notice Computes the amount of liquidity received for a given amount of token0 and price range - /// @dev Calculates amount0 * (sqrt(upper) * sqrt(lower)) / (sqrt(upper) - sqrt(lower)) - /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary - /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary - /// @param amount0 The amount0 being sent in - /// @return liquidity The amount of returned liquidity - function getLiquidityForAmount0( - uint160 sqrtRatioAX96, - uint160 sqrtRatioBX96, - uint256 amount0 - ) internal pure returns (uint128 liquidity) { - if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96); - uint256 intermediate = FullMath.mulDiv(sqrtRatioAX96, sqrtRatioBX96, FixedPoint96.Q96); - return toUint128(FullMath.mulDiv(amount0, intermediate, sqrtRatioBX96 - sqrtRatioAX96)); - } - - /// @notice Computes the amount of liquidity received for a given amount of token1 and price range - /// @dev Calculates amount1 / (sqrt(upper) - sqrt(lower)). - /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary - /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary - /// @param amount1 The amount1 being sent in - /// @return liquidity The amount of returned liquidity - function getLiquidityForAmount1( - uint160 sqrtRatioAX96, - uint160 sqrtRatioBX96, - uint256 amount1 - ) internal pure returns (uint128 liquidity) { - if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96); - return toUint128(FullMath.mulDiv(amount1, FixedPoint96.Q96, sqrtRatioBX96 - sqrtRatioAX96)); - } - - /// @notice Computes the maximum amount of liquidity received for a given amount of token0, token1, the current - /// pool prices and the prices at the tick boundaries - /// @param sqrtRatioX96 A sqrt price representing the current pool prices - /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary - /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary - /// @param amount0 The amount of token0 being sent in - /// @param amount1 The amount of token1 being sent in - /// @return liquidity The maximum amount of liquidity received - function getLiquidityForAmounts( - uint160 sqrtRatioX96, - uint160 sqrtRatioAX96, - uint160 sqrtRatioBX96, - uint256 amount0, - uint256 amount1 - ) internal pure returns (uint128 liquidity) { - if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96); - - if (sqrtRatioX96 <= sqrtRatioAX96) { - liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0); - } else if (sqrtRatioX96 < sqrtRatioBX96) { - uint128 liquidity0 = getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, amount0); - uint128 liquidity1 = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, amount1); - - liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1; - } else { - liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1); - } - } - - /// @notice Computes the amount of token0 for a given amount of liquidity and a price range - /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary - /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary - /// @param liquidity The liquidity being valued - /// @return amount0 The amount of token0 - function getAmount0ForLiquidity( - uint160 sqrtRatioAX96, - uint160 sqrtRatioBX96, - uint128 liquidity - ) internal pure returns (uint256 amount0) { - if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96); - - return - FullMath.mulDiv( - uint256(liquidity) << FixedPoint96.RESOLUTION, - sqrtRatioBX96 - sqrtRatioAX96, - sqrtRatioBX96 - ) / sqrtRatioAX96; - } - - /// @notice Computes the amount of token1 for a given amount of liquidity and a price range - /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary - /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary - /// @param liquidity The liquidity being valued - /// @return amount1 The amount of token1 - function getAmount1ForLiquidity( - uint160 sqrtRatioAX96, - uint160 sqrtRatioBX96, - uint128 liquidity - ) internal pure returns (uint256 amount1) { - if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96); - - return FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96); - } - - /// @notice Computes the token0 and token1 value for a given amount of liquidity, the current - /// pool prices and the prices at the tick boundaries - /// @param sqrtRatioX96 A sqrt price representing the current pool prices - /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary - /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary - /// @param liquidity The liquidity being valued - /// @return amount0 The amount of token0 - /// @return amount1 The amount of token1 - function getAmountsForLiquidity( - uint160 sqrtRatioX96, - uint160 sqrtRatioAX96, - uint160 sqrtRatioBX96, - uint128 liquidity - ) internal pure returns (uint256 amount0, uint256 amount1) { - if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96); - - if (sqrtRatioX96 <= sqrtRatioAX96) { - amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity); - } else if (sqrtRatioX96 < sqrtRatioBX96) { - amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity); - amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity); - } else { - amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity); - } - } -} diff --git a/lib/v3-periphery/contracts/libraries/NFTDescriptor.sol b/lib/v3-periphery/contracts/libraries/NFTDescriptor.sol deleted file mode 100644 index 8414872..0000000 --- a/lib/v3-periphery/contracts/libraries/NFTDescriptor.sol +++ /dev/null @@ -1,477 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.7.0; -pragma abicoder v2; - -import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol'; -import '@uniswap/v3-core/contracts/libraries/TickMath.sol'; -import '@uniswap/v3-core/contracts/libraries/BitMath.sol'; -import '@uniswap/v3-core/contracts/libraries/FullMath.sol'; -import '@openzeppelin/contracts/utils/Strings.sol'; -import '@openzeppelin/contracts/math/SafeMath.sol'; -import '@openzeppelin/contracts/math/SignedSafeMath.sol'; -import 'base64-sol/base64.sol'; -import './HexStrings.sol'; -import './NFTSVG.sol'; - -library NFTDescriptor { - using TickMath for int24; - using Strings for uint256; - using SafeMath for uint256; - using SafeMath for uint160; - using SafeMath for uint8; - using SignedSafeMath for int256; - using HexStrings for uint256; - - uint256 constant sqrt10X128 = 1076067327063303206878105757264492625226; - - struct ConstructTokenURIParams { - uint256 tokenId; - address quoteTokenAddress; - address baseTokenAddress; - string quoteTokenSymbol; - string baseTokenSymbol; - uint8 quoteTokenDecimals; - uint8 baseTokenDecimals; - bool flipRatio; - int24 tickLower; - int24 tickUpper; - int24 tickCurrent; - int24 tickSpacing; - uint24 fee; - address poolAddress; - } - - function constructTokenURI(ConstructTokenURIParams memory params) public pure returns (string memory) { - string memory name = generateName(params, feeToPercentString(params.fee)); - string memory descriptionPartOne = - generateDescriptionPartOne( - escapeQuotes(params.quoteTokenSymbol), - escapeQuotes(params.baseTokenSymbol), - addressToString(params.poolAddress) - ); - string memory descriptionPartTwo = - generateDescriptionPartTwo( - params.tokenId.toString(), - escapeQuotes(params.baseTokenSymbol), - addressToString(params.quoteTokenAddress), - addressToString(params.baseTokenAddress), - feeToPercentString(params.fee) - ); - string memory image = Base64.encode(bytes(generateSVGImage(params))); - - return - string( - abi.encodePacked( - 'data:application/json;base64,', - Base64.encode( - bytes( - abi.encodePacked( - '{"name":"', - name, - '", "description":"', - descriptionPartOne, - descriptionPartTwo, - '", "image": "', - 'data:image/svg+xml;base64,', - image, - '"}' - ) - ) - ) - ) - ); - } - - function escapeQuotes(string memory symbol) internal pure returns (string memory) { - bytes memory symbolBytes = bytes(symbol); - uint8 quotesCount = 0; - for (uint8 i = 0; i < symbolBytes.length; i++) { - if (symbolBytes[i] == '"') { - quotesCount++; - } - } - if (quotesCount > 0) { - bytes memory escapedBytes = new bytes(symbolBytes.length + (quotesCount)); - uint256 index; - for (uint8 i = 0; i < symbolBytes.length; i++) { - if (symbolBytes[i] == '"') { - escapedBytes[index++] = '\\'; - } - escapedBytes[index++] = symbolBytes[i]; - } - return string(escapedBytes); - } - return symbol; - } - - function generateDescriptionPartOne( - string memory quoteTokenSymbol, - string memory baseTokenSymbol, - string memory poolAddress - ) private pure returns (string memory) { - return - string( - abi.encodePacked( - 'This NFT represents a liquidity position in a Uniswap V3 ', - quoteTokenSymbol, - '-', - baseTokenSymbol, - ' pool. ', - 'The owner of this NFT can modify or redeem the position.\\n', - '\\nPool Address: ', - poolAddress, - '\\n', - quoteTokenSymbol - ) - ); - } - - function generateDescriptionPartTwo( - string memory tokenId, - string memory baseTokenSymbol, - string memory quoteTokenAddress, - string memory baseTokenAddress, - string memory feeTier - ) private pure returns (string memory) { - return - string( - abi.encodePacked( - ' Address: ', - quoteTokenAddress, - '\\n', - baseTokenSymbol, - ' Address: ', - baseTokenAddress, - '\\nFee Tier: ', - feeTier, - '\\nToken ID: ', - tokenId, - '\\n\\n', - unicode'⚠️ DISCLAIMER: Due diligence is imperative when assessing this NFT. Make sure token addresses match the expected tokens, as token symbols may be imitated.' - ) - ); - } - - function generateName(ConstructTokenURIParams memory params, string memory feeTier) - private - pure - returns (string memory) - { - return - string( - abi.encodePacked( - 'Uniswap - ', - feeTier, - ' - ', - escapeQuotes(params.quoteTokenSymbol), - '/', - escapeQuotes(params.baseTokenSymbol), - ' - ', - tickToDecimalString( - !params.flipRatio ? params.tickLower : params.tickUpper, - params.tickSpacing, - params.baseTokenDecimals, - params.quoteTokenDecimals, - params.flipRatio - ), - '<>', - tickToDecimalString( - !params.flipRatio ? params.tickUpper : params.tickLower, - params.tickSpacing, - params.baseTokenDecimals, - params.quoteTokenDecimals, - params.flipRatio - ) - ) - ); - } - - struct DecimalStringParams { - // significant figures of decimal - uint256 sigfigs; - // length of decimal string - uint8 bufferLength; - // ending index for significant figures (funtion works backwards when copying sigfigs) - uint8 sigfigIndex; - // index of decimal place (0 if no decimal) - uint8 decimalIndex; - // start index for trailing/leading 0's for very small/large numbers - uint8 zerosStartIndex; - // end index for trailing/leading 0's for very small/large numbers - uint8 zerosEndIndex; - // true if decimal number is less than one - bool isLessThanOne; - // true if string should include "%" - bool isPercent; - } - - function generateDecimalString(DecimalStringParams memory params) private pure returns (string memory) { - bytes memory buffer = new bytes(params.bufferLength); - if (params.isPercent) { - buffer[buffer.length - 1] = '%'; - } - if (params.isLessThanOne) { - buffer[0] = '0'; - buffer[1] = '.'; - } - - // add leading/trailing 0's - for (uint256 zerosCursor = params.zerosStartIndex; zerosCursor < params.zerosEndIndex.add(1); zerosCursor++) { - buffer[zerosCursor] = bytes1(uint8(48)); - } - // add sigfigs - while (params.sigfigs > 0) { - if (params.decimalIndex > 0 && params.sigfigIndex == params.decimalIndex) { - buffer[params.sigfigIndex--] = '.'; - } - buffer[params.sigfigIndex--] = bytes1(uint8(uint256(48).add(params.sigfigs % 10))); - params.sigfigs /= 10; - } - return string(buffer); - } - - function tickToDecimalString( - int24 tick, - int24 tickSpacing, - uint8 baseTokenDecimals, - uint8 quoteTokenDecimals, - bool flipRatio - ) internal pure returns (string memory) { - if (tick == (TickMath.MIN_TICK / tickSpacing) * tickSpacing) { - return !flipRatio ? 'MIN' : 'MAX'; - } else if (tick == (TickMath.MAX_TICK / tickSpacing) * tickSpacing) { - return !flipRatio ? 'MAX' : 'MIN'; - } else { - uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(tick); - if (flipRatio) { - sqrtRatioX96 = uint160(uint256(1 << 192).div(sqrtRatioX96)); - } - return fixedPointToDecimalString(sqrtRatioX96, baseTokenDecimals, quoteTokenDecimals); - } - } - - function sigfigsRounded(uint256 value, uint8 digits) private pure returns (uint256, bool) { - bool extraDigit; - if (digits > 5) { - value = value.div((10**(digits - 5))); - } - bool roundUp = value % 10 > 4; - value = value.div(10); - if (roundUp) { - value = value + 1; - } - // 99999 -> 100000 gives an extra sigfig - if (value == 100000) { - value /= 10; - extraDigit = true; - } - return (value, extraDigit); - } - - function adjustForDecimalPrecision( - uint160 sqrtRatioX96, - uint8 baseTokenDecimals, - uint8 quoteTokenDecimals - ) private pure returns (uint256 adjustedSqrtRatioX96) { - uint256 difference = abs(int256(baseTokenDecimals).sub(int256(quoteTokenDecimals))); - if (difference > 0 && difference <= 18) { - if (baseTokenDecimals > quoteTokenDecimals) { - adjustedSqrtRatioX96 = sqrtRatioX96.mul(10**(difference.div(2))); - if (difference % 2 == 1) { - adjustedSqrtRatioX96 = FullMath.mulDiv(adjustedSqrtRatioX96, sqrt10X128, 1 << 128); - } - } else { - adjustedSqrtRatioX96 = sqrtRatioX96.div(10**(difference.div(2))); - if (difference % 2 == 1) { - adjustedSqrtRatioX96 = FullMath.mulDiv(adjustedSqrtRatioX96, 1 << 128, sqrt10X128); - } - } - } else { - adjustedSqrtRatioX96 = uint256(sqrtRatioX96); - } - } - - function abs(int256 x) private pure returns (uint256) { - return uint256(x >= 0 ? x : -x); - } - - // @notice Returns string that includes first 5 significant figures of a decimal number - // @param sqrtRatioX96 a sqrt price - function fixedPointToDecimalString( - uint160 sqrtRatioX96, - uint8 baseTokenDecimals, - uint8 quoteTokenDecimals - ) internal pure returns (string memory) { - uint256 adjustedSqrtRatioX96 = adjustForDecimalPrecision(sqrtRatioX96, baseTokenDecimals, quoteTokenDecimals); - uint256 value = FullMath.mulDiv(adjustedSqrtRatioX96, adjustedSqrtRatioX96, 1 << 64); - - bool priceBelow1 = adjustedSqrtRatioX96 < 2**96; - if (priceBelow1) { - // 10 ** 43 is precision needed to retreive 5 sigfigs of smallest possible price + 1 for rounding - value = FullMath.mulDiv(value, 10**44, 1 << 128); - } else { - // leave precision for 4 decimal places + 1 place for rounding - value = FullMath.mulDiv(value, 10**5, 1 << 128); - } - - // get digit count - uint256 temp = value; - uint8 digits; - while (temp != 0) { - digits++; - temp /= 10; - } - // don't count extra digit kept for rounding - digits = digits - 1; - - // address rounding - (uint256 sigfigs, bool extraDigit) = sigfigsRounded(value, digits); - if (extraDigit) { - digits++; - } - - DecimalStringParams memory params; - if (priceBelow1) { - // 7 bytes ( "0." and 5 sigfigs) + leading 0's bytes - params.bufferLength = uint8(uint8(7).add(uint8(43).sub(digits))); - params.zerosStartIndex = 2; - params.zerosEndIndex = uint8(uint256(43).sub(digits).add(1)); - params.sigfigIndex = uint8(params.bufferLength.sub(1)); - } else if (digits >= 9) { - // no decimal in price string - params.bufferLength = uint8(digits.sub(4)); - params.zerosStartIndex = 5; - params.zerosEndIndex = uint8(params.bufferLength.sub(1)); - params.sigfigIndex = 4; - } else { - // 5 sigfigs surround decimal - params.bufferLength = 6; - params.sigfigIndex = 5; - params.decimalIndex = uint8(digits.sub(5).add(1)); - } - params.sigfigs = sigfigs; - params.isLessThanOne = priceBelow1; - params.isPercent = false; - - return generateDecimalString(params); - } - - // @notice Returns string as decimal percentage of fee amount. - // @param fee fee amount - function feeToPercentString(uint24 fee) internal pure returns (string memory) { - if (fee == 0) { - return '0%'; - } - uint24 temp = fee; - uint256 digits; - uint8 numSigfigs; - while (temp != 0) { - if (numSigfigs > 0) { - // count all digits preceding least significant figure - numSigfigs++; - } else if (temp % 10 != 0) { - numSigfigs++; - } - digits++; - temp /= 10; - } - - DecimalStringParams memory params; - uint256 nZeros; - if (digits >= 5) { - // if decimal > 1 (5th digit is the ones place) - uint256 decimalPlace = digits.sub(numSigfigs) >= 4 ? 0 : 1; - nZeros = digits.sub(5) < (numSigfigs.sub(1)) ? 0 : digits.sub(5).sub(numSigfigs.sub(1)); - params.zerosStartIndex = numSigfigs; - params.zerosEndIndex = uint8(params.zerosStartIndex.add(nZeros).sub(1)); - params.sigfigIndex = uint8(params.zerosStartIndex.sub(1).add(decimalPlace)); - params.bufferLength = uint8(nZeros.add(numSigfigs.add(1)).add(decimalPlace)); - } else { - // else if decimal < 1 - nZeros = uint256(5).sub(digits); - params.zerosStartIndex = 2; - params.zerosEndIndex = uint8(nZeros.add(params.zerosStartIndex).sub(1)); - params.bufferLength = uint8(nZeros.add(numSigfigs.add(2))); - params.sigfigIndex = uint8((params.bufferLength).sub(2)); - params.isLessThanOne = true; - } - params.sigfigs = uint256(fee).div(10**(digits.sub(numSigfigs))); - params.isPercent = true; - params.decimalIndex = digits > 4 ? uint8(digits.sub(4)) : 0; - - return generateDecimalString(params); - } - - function addressToString(address addr) internal pure returns (string memory) { - return (uint256(addr)).toHexString(20); - } - - function generateSVGImage(ConstructTokenURIParams memory params) internal pure returns (string memory svg) { - NFTSVG.SVGParams memory svgParams = - NFTSVG.SVGParams({ - quoteToken: addressToString(params.quoteTokenAddress), - baseToken: addressToString(params.baseTokenAddress), - poolAddress: params.poolAddress, - quoteTokenSymbol: params.quoteTokenSymbol, - baseTokenSymbol: params.baseTokenSymbol, - feeTier: feeToPercentString(params.fee), - tickLower: params.tickLower, - tickUpper: params.tickUpper, - tickSpacing: params.tickSpacing, - overRange: overRange(params.tickLower, params.tickUpper, params.tickCurrent), - tokenId: params.tokenId, - color0: tokenToColorHex(uint256(params.quoteTokenAddress), 136), - color1: tokenToColorHex(uint256(params.baseTokenAddress), 136), - color2: tokenToColorHex(uint256(params.quoteTokenAddress), 0), - color3: tokenToColorHex(uint256(params.baseTokenAddress), 0), - x1: scale(getCircleCoord(uint256(params.quoteTokenAddress), 16, params.tokenId), 0, 255, 16, 274), - y1: scale(getCircleCoord(uint256(params.baseTokenAddress), 16, params.tokenId), 0, 255, 100, 484), - x2: scale(getCircleCoord(uint256(params.quoteTokenAddress), 32, params.tokenId), 0, 255, 16, 274), - y2: scale(getCircleCoord(uint256(params.baseTokenAddress), 32, params.tokenId), 0, 255, 100, 484), - x3: scale(getCircleCoord(uint256(params.quoteTokenAddress), 48, params.tokenId), 0, 255, 16, 274), - y3: scale(getCircleCoord(uint256(params.baseTokenAddress), 48, params.tokenId), 0, 255, 100, 484) - }); - - return NFTSVG.generateSVG(svgParams); - } - - function overRange( - int24 tickLower, - int24 tickUpper, - int24 tickCurrent - ) private pure returns (int8) { - if (tickCurrent < tickLower) { - return -1; - } else if (tickCurrent > tickUpper) { - return 1; - } else { - return 0; - } - } - - function scale( - uint256 n, - uint256 inMn, - uint256 inMx, - uint256 outMn, - uint256 outMx - ) private pure returns (string memory) { - return (n.sub(inMn).mul(outMx.sub(outMn)).div(inMx.sub(inMn)).add(outMn)).toString(); - } - - function tokenToColorHex(uint256 token, uint256 offset) internal pure returns (string memory str) { - return string((token >> offset).toHexStringNoPrefix(3)); - } - - function getCircleCoord( - uint256 tokenAddress, - uint256 offset, - uint256 tokenId - ) internal pure returns (uint256) { - return (sliceTokenHex(tokenAddress, offset) * tokenId) % 255; - } - - function sliceTokenHex(uint256 token, uint256 offset) internal pure returns (uint256) { - return uint256(uint8(token >> offset)); - } -} diff --git a/lib/v3-periphery/contracts/libraries/NFTSVG.sol b/lib/v3-periphery/contracts/libraries/NFTSVG.sol deleted file mode 100644 index 2d5ce83..0000000 --- a/lib/v3-periphery/contracts/libraries/NFTSVG.sol +++ /dev/null @@ -1,406 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.7.6; - -import '@openzeppelin/contracts/utils/Strings.sol'; -import '@uniswap/v3-core/contracts/libraries/BitMath.sol'; -import 'base64-sol/base64.sol'; - -/// @title NFTSVG -/// @notice Provides a function for generating an SVG associated with a Uniswap NFT -library NFTSVG { - using Strings for uint256; - - string constant curve1 = 'M1 1C41 41 105 105 145 145'; - string constant curve2 = 'M1 1C33 49 97 113 145 145'; - string constant curve3 = 'M1 1C33 57 89 113 145 145'; - string constant curve4 = 'M1 1C25 65 81 121 145 145'; - string constant curve5 = 'M1 1C17 73 73 129 145 145'; - string constant curve6 = 'M1 1C9 81 65 137 145 145'; - string constant curve7 = 'M1 1C1 89 57.5 145 145 145'; - string constant curve8 = 'M1 1C1 97 49 145 145 145'; - - struct SVGParams { - string quoteToken; - string baseToken; - address poolAddress; - string quoteTokenSymbol; - string baseTokenSymbol; - string feeTier; - int24 tickLower; - int24 tickUpper; - int24 tickSpacing; - int8 overRange; - uint256 tokenId; - string color0; - string color1; - string color2; - string color3; - string x1; - string y1; - string x2; - string y2; - string x3; - string y3; - } - - function generateSVG(SVGParams memory params) internal pure returns (string memory svg) { - /* - address: "0xe8ab59d3bcde16a29912de83a90eb39628cfc163", - msg: "Forged in SVG for Uniswap in 2021 by 0xe8ab59d3bcde16a29912de83a90eb39628cfc163", - sig: "0x2df0e99d9cbfec33a705d83f75666d98b22dea7c1af412c584f7d626d83f02875993df740dc87563b9c73378f8462426da572d7989de88079a382ad96c57b68d1b", - version: "2" - */ - return - string( - abi.encodePacked( - generateSVGDefs(params), - generateSVGBorderText( - params.quoteToken, - params.baseToken, - params.quoteTokenSymbol, - params.baseTokenSymbol - ), - generateSVGCardMantle(params.quoteTokenSymbol, params.baseTokenSymbol, params.feeTier), - generageSvgCurve(params.tickLower, params.tickUpper, params.tickSpacing, params.overRange), - generateSVGPositionDataAndLocationCurve( - params.tokenId.toString(), - params.tickLower, - params.tickUpper - ), - generateSVGRareSparkle(params.tokenId, params.poolAddress), - '' - ) - ); - } - - function generateSVGDefs(SVGParams memory params) private pure returns (string memory svg) { - svg = string( - abi.encodePacked( - '", - '', - '" - ) - ) - ), - '"/>" - ) - ) - ), - '"/>" - ) - ) - ), - '" />', - '" - ) - ) - ), - '" /> ', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - ' ', - '', - '', - '' - ) - ); - } - - function generateSVGBorderText( - string memory quoteToken, - string memory baseToken, - string memory quoteTokenSymbol, - string memory baseTokenSymbol - ) private pure returns (string memory svg) { - svg = string( - abi.encodePacked( - '', - '', - baseToken, - unicode' • ', - baseTokenSymbol, - ' ', - ' ', - baseToken, - unicode' • ', - baseTokenSymbol, - ' ', - '', - quoteToken, - unicode' • ', - quoteTokenSymbol, - ' ', - quoteToken, - unicode' • ', - quoteTokenSymbol, - ' ' - ) - ); - } - - function generateSVGCardMantle( - string memory quoteTokenSymbol, - string memory baseTokenSymbol, - string memory feeTier - ) private pure returns (string memory svg) { - svg = string( - abi.encodePacked( - ' ', - quoteTokenSymbol, - '/', - baseTokenSymbol, - '', - feeTier, - '', - '' - ) - ); - } - - function generageSvgCurve( - int24 tickLower, - int24 tickUpper, - int24 tickSpacing, - int8 overRange - ) private pure returns (string memory svg) { - string memory fade = overRange == 1 ? '#fade-up' : overRange == -1 ? '#fade-down' : '#none'; - string memory curve = getCurve(tickLower, tickUpper, tickSpacing); - svg = string( - abi.encodePacked( - '' - '' - '', - '', - '', - '', - generateSVGCurveCircle(overRange) - ) - ); - } - - function getCurve( - int24 tickLower, - int24 tickUpper, - int24 tickSpacing - ) internal pure returns (string memory curve) { - int24 tickRange = (tickUpper - tickLower) / tickSpacing; - if (tickRange <= 4) { - curve = curve1; - } else if (tickRange <= 8) { - curve = curve2; - } else if (tickRange <= 16) { - curve = curve3; - } else if (tickRange <= 32) { - curve = curve4; - } else if (tickRange <= 64) { - curve = curve5; - } else if (tickRange <= 128) { - curve = curve6; - } else if (tickRange <= 256) { - curve = curve7; - } else { - curve = curve8; - } - } - - function generateSVGCurveCircle(int8 overRange) internal pure returns (string memory svg) { - string memory curvex1 = '73'; - string memory curvey1 = '190'; - string memory curvex2 = '217'; - string memory curvey2 = '334'; - if (overRange == 1 || overRange == -1) { - svg = string( - abi.encodePacked( - '' - ) - ); - } else { - svg = string( - abi.encodePacked( - '', - '' - ) - ); - } - } - - function generateSVGPositionDataAndLocationCurve( - string memory tokenId, - int24 tickLower, - int24 tickUpper - ) private pure returns (string memory svg) { - string memory tickLowerStr = tickToString(tickLower); - string memory tickUpperStr = tickToString(tickUpper); - uint256 str1length = bytes(tokenId).length + 4; - uint256 str2length = bytes(tickLowerStr).length + 10; - uint256 str3length = bytes(tickUpperStr).length + 10; - (string memory xCoord, string memory yCoord) = rangeLocation(tickLower, tickUpper); - svg = string( - abi.encodePacked( - ' ', - '', - 'ID: ', - tokenId, - '', - ' ', - '', - 'Min Tick: ', - tickLowerStr, - '', - ' ', - '', - 'Max Tick: ', - tickUpperStr, - '' - '', - '', - '', - '' - ) - ); - } - - function tickToString(int24 tick) private pure returns (string memory) { - string memory sign = ''; - if (tick < 0) { - tick = tick * -1; - sign = '-'; - } - return string(abi.encodePacked(sign, uint256(tick).toString())); - } - - function rangeLocation(int24 tickLower, int24 tickUpper) internal pure returns (string memory, string memory) { - int24 midPoint = (tickLower + tickUpper) / 2; - if (midPoint < -125_000) { - return ('8', '7'); - } else if (midPoint < -75_000) { - return ('8', '10.5'); - } else if (midPoint < -25_000) { - return ('8', '14.25'); - } else if (midPoint < -5_000) { - return ('10', '18'); - } else if (midPoint < 0) { - return ('11', '21'); - } else if (midPoint < 5_000) { - return ('13', '23'); - } else if (midPoint < 25_000) { - return ('15', '25'); - } else if (midPoint < 75_000) { - return ('18', '26'); - } else if (midPoint < 125_000) { - return ('21', '27'); - } else { - return ('24', '27'); - } - } - - function generateSVGRareSparkle(uint256 tokenId, address poolAddress) private pure returns (string memory svg) { - if (isRare(tokenId, poolAddress)) { - svg = string( - abi.encodePacked( - '', - '', - '' - ) - ); - } else { - svg = ''; - } - } - - function isRare(uint256 tokenId, address poolAddress) internal pure returns (bool) { - bytes32 h = keccak256(abi.encodePacked(tokenId, poolAddress)); - return uint256(h) < type(uint256).max / (1 + BitMath.mostSignificantBit(tokenId) * 2); - } -} diff --git a/lib/v3-periphery/contracts/libraries/OracleLibrary.sol b/lib/v3-periphery/contracts/libraries/OracleLibrary.sol deleted file mode 100644 index ddb82be..0000000 --- a/lib/v3-periphery/contracts/libraries/OracleLibrary.sol +++ /dev/null @@ -1,180 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0 <0.8.0; - -import '@uniswap/v3-core/contracts/libraries/FullMath.sol'; -import '@uniswap/v3-core/contracts/libraries/TickMath.sol'; -import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol'; - -/// @title Oracle library -/// @notice Provides functions to integrate with V3 pool oracle -library OracleLibrary { - /// @notice Calculates time-weighted means of tick and liquidity for a given Uniswap V3 pool - /// @param pool Address of the pool that we want to observe - /// @param secondsAgo Number of seconds in the past from which to calculate the time-weighted means - /// @return arithmeticMeanTick The arithmetic mean tick from (block.timestamp - secondsAgo) to block.timestamp - /// @return harmonicMeanLiquidity The harmonic mean liquidity from (block.timestamp - secondsAgo) to block.timestamp - function consult(address pool, uint32 secondsAgo) - internal - view - returns (int24 arithmeticMeanTick, uint128 harmonicMeanLiquidity) - { - require(secondsAgo != 0, 'BP'); - - uint32[] memory secondsAgos = new uint32[](2); - secondsAgos[0] = secondsAgo; - secondsAgos[1] = 0; - - (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s) = - IUniswapV3Pool(pool).observe(secondsAgos); - - int56 tickCumulativesDelta = tickCumulatives[1] - tickCumulatives[0]; - uint160 secondsPerLiquidityCumulativesDelta = - secondsPerLiquidityCumulativeX128s[1] - secondsPerLiquidityCumulativeX128s[0]; - - arithmeticMeanTick = int24(tickCumulativesDelta / secondsAgo); - // Always round to negative infinity - if (tickCumulativesDelta < 0 && (tickCumulativesDelta % secondsAgo != 0)) arithmeticMeanTick--; - - // We are multiplying here instead of shifting to ensure that harmonicMeanLiquidity doesn't overflow uint128 - uint192 secondsAgoX160 = uint192(secondsAgo) * type(uint160).max; - harmonicMeanLiquidity = uint128(secondsAgoX160 / (uint192(secondsPerLiquidityCumulativesDelta) << 32)); - } - - /// @notice Given a tick and a token amount, calculates the amount of token received in exchange - /// @param tick Tick value used to calculate the quote - /// @param baseAmount Amount of token to be converted - /// @param baseToken Address of an ERC20 token contract used as the baseAmount denomination - /// @param quoteToken Address of an ERC20 token contract used as the quoteAmount denomination - /// @return quoteAmount Amount of quoteToken received for baseAmount of baseToken - function getQuoteAtTick( - int24 tick, - uint128 baseAmount, - address baseToken, - address quoteToken - ) internal pure returns (uint256 quoteAmount) { - uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(tick); - - // Calculate quoteAmount with better precision if it doesn't overflow when multiplied by itself - if (sqrtRatioX96 <= type(uint128).max) { - uint256 ratioX192 = uint256(sqrtRatioX96) * sqrtRatioX96; - quoteAmount = baseToken < quoteToken - ? FullMath.mulDiv(ratioX192, baseAmount, 1 << 192) - : FullMath.mulDiv(1 << 192, baseAmount, ratioX192); - } else { - uint256 ratioX128 = FullMath.mulDiv(sqrtRatioX96, sqrtRatioX96, 1 << 64); - quoteAmount = baseToken < quoteToken - ? FullMath.mulDiv(ratioX128, baseAmount, 1 << 128) - : FullMath.mulDiv(1 << 128, baseAmount, ratioX128); - } - } - - /// @notice Given a pool, it returns the number of seconds ago of the oldest stored observation - /// @param pool Address of Uniswap V3 pool that we want to observe - /// @return secondsAgo The number of seconds ago of the oldest observation stored for the pool - function getOldestObservationSecondsAgo(address pool) internal view returns (uint32 secondsAgo) { - (, , uint16 observationIndex, uint16 observationCardinality, , , ) = IUniswapV3Pool(pool).slot0(); - require(observationCardinality > 0, 'NI'); - - (uint32 observationTimestamp, , , bool initialized) = - IUniswapV3Pool(pool).observations((observationIndex + 1) % observationCardinality); - - // The next index might not be initialized if the cardinality is in the process of increasing - // In this case the oldest observation is always in index 0 - if (!initialized) { - (observationTimestamp, , , ) = IUniswapV3Pool(pool).observations(0); - } - - secondsAgo = uint32(block.timestamp) - observationTimestamp; - } - - /// @notice Given a pool, it returns the tick value as of the start of the current block - /// @param pool Address of Uniswap V3 pool - /// @return The tick that the pool was in at the start of the current block - function getBlockStartingTickAndLiquidity(address pool) internal view returns (int24, uint128) { - (, int24 tick, uint16 observationIndex, uint16 observationCardinality, , , ) = IUniswapV3Pool(pool).slot0(); - - // 2 observations are needed to reliably calculate the block starting tick - require(observationCardinality > 1, 'NEO'); - - // If the latest observation occurred in the past, then no tick-changing trades have happened in this block - // therefore the tick in `slot0` is the same as at the beginning of the current block. - // We don't need to check if this observation is initialized - it is guaranteed to be. - (uint32 observationTimestamp, int56 tickCumulative, uint160 secondsPerLiquidityCumulativeX128, ) = - IUniswapV3Pool(pool).observations(observationIndex); - if (observationTimestamp != uint32(block.timestamp)) { - return (tick, IUniswapV3Pool(pool).liquidity()); - } - - uint256 prevIndex = (uint256(observationIndex) + observationCardinality - 1) % observationCardinality; - ( - uint32 prevObservationTimestamp, - int56 prevTickCumulative, - uint160 prevSecondsPerLiquidityCumulativeX128, - bool prevInitialized - ) = IUniswapV3Pool(pool).observations(prevIndex); - - require(prevInitialized, 'ONI'); - - uint32 delta = observationTimestamp - prevObservationTimestamp; - tick = int24((tickCumulative - prevTickCumulative) / delta); - uint128 liquidity = - uint128( - (uint192(delta) * type(uint160).max) / - (uint192(secondsPerLiquidityCumulativeX128 - prevSecondsPerLiquidityCumulativeX128) << 32) - ); - return (tick, liquidity); - } - - /// @notice Information for calculating a weighted arithmetic mean tick - struct WeightedTickData { - int24 tick; - uint128 weight; - } - - /// @notice Given an array of ticks and weights, calculates the weighted arithmetic mean tick - /// @param weightedTickData An array of ticks and weights - /// @return weightedArithmeticMeanTick The weighted arithmetic mean tick - /// @dev Each entry of `weightedTickData` should represents ticks from pools with the same underlying pool tokens. If they do not, - /// extreme care must be taken to ensure that ticks are comparable (including decimal differences). - /// @dev Note that the weighted arithmetic mean tick corresponds to the weighted geometric mean price. - function getWeightedArithmeticMeanTick(WeightedTickData[] memory weightedTickData) - internal - pure - returns (int24 weightedArithmeticMeanTick) - { - // Accumulates the sum of products between each tick and its weight - int256 numerator; - - // Accumulates the sum of the weights - uint256 denominator; - - // Products fit in 152 bits, so it would take an array of length ~2**104 to overflow this logic - for (uint256 i; i < weightedTickData.length; i++) { - numerator += weightedTickData[i].tick * int256(weightedTickData[i].weight); - denominator += weightedTickData[i].weight; - } - - weightedArithmeticMeanTick = int24(numerator / int256(denominator)); - // Always round to negative infinity - if (numerator < 0 && (numerator % int256(denominator) != 0)) weightedArithmeticMeanTick--; - } - - /// @notice Returns the "synthetic" tick which represents the price of the first entry in `tokens` in terms of the last - /// @dev Useful for calculating relative prices along routes. - /// @dev There must be one tick for each pairwise set of tokens. - /// @param tokens The token contract addresses - /// @param ticks The ticks, representing the price of each token pair in `tokens` - /// @return syntheticTick The synthetic tick, representing the relative price of the outermost tokens in `tokens` - function getChainedPrice(address[] memory tokens, int24[] memory ticks) - internal - pure - returns (int256 syntheticTick) - { - require(tokens.length - 1 == ticks.length, 'DL'); - for (uint256 i = 1; i <= ticks.length; i++) { - // check the tokens for address sort order, then accumulate the - // ticks into the running synthetic tick, ensuring that intermediate tokens "cancel out" - tokens[i - 1] < tokens[i] ? syntheticTick += ticks[i - 1] : syntheticTick -= ticks[i - 1]; - } - } -} diff --git a/lib/v3-periphery/contracts/libraries/Path.sol b/lib/v3-periphery/contracts/libraries/Path.sol deleted file mode 100644 index d6ee864..0000000 --- a/lib/v3-periphery/contracts/libraries/Path.sol +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.6.0; - -import './BytesLib.sol'; - -/// @title Functions for manipulating path data for multihop swaps -library Path { - using BytesLib for bytes; - - /// @dev The length of the bytes encoded address - uint256 private constant ADDR_SIZE = 20; - /// @dev The length of the bytes encoded fee - uint256 private constant FEE_SIZE = 3; - - /// @dev The offset of a single token address and pool fee - uint256 private constant NEXT_OFFSET = ADDR_SIZE + FEE_SIZE; - /// @dev The offset of an encoded pool key - uint256 private constant POP_OFFSET = NEXT_OFFSET + ADDR_SIZE; - /// @dev The minimum length of an encoding that contains 2 or more pools - uint256 private constant MULTIPLE_POOLS_MIN_LENGTH = POP_OFFSET + NEXT_OFFSET; - - /// @notice Returns true iff the path contains two or more pools - /// @param path The encoded swap path - /// @return True if path contains two or more pools, otherwise false - function hasMultiplePools(bytes memory path) internal pure returns (bool) { - return path.length >= MULTIPLE_POOLS_MIN_LENGTH; - } - - /// @notice Returns the number of pools in the path - /// @param path The encoded swap path - /// @return The number of pools in the path - function numPools(bytes memory path) internal pure returns (uint256) { - // Ignore the first token address. From then on every fee and token offset indicates a pool. - return ((path.length - ADDR_SIZE) / NEXT_OFFSET); - } - - /// @notice Decodes the first pool in path - /// @param path The bytes encoded swap path - /// @return tokenA The first token of the given pool - /// @return tokenB The second token of the given pool - /// @return fee The fee level of the pool - function decodeFirstPool(bytes memory path) - internal - pure - returns ( - address tokenA, - address tokenB, - uint24 fee - ) - { - tokenA = path.toAddress(0); - fee = path.toUint24(ADDR_SIZE); - tokenB = path.toAddress(NEXT_OFFSET); - } - - /// @notice Gets the segment corresponding to the first pool in the path - /// @param path The bytes encoded swap path - /// @return The segment containing all data necessary to target the first pool in the path - function getFirstPool(bytes memory path) internal pure returns (bytes memory) { - return path.slice(0, POP_OFFSET); - } - - /// @notice Skips a token + fee element from the buffer and returns the remainder - /// @param path The swap path - /// @return The remaining token + fee elements in the path - function skipToken(bytes memory path) internal pure returns (bytes memory) { - return path.slice(NEXT_OFFSET, path.length - NEXT_OFFSET); - } -} diff --git a/lib/v3-periphery/contracts/libraries/PoolAddress.sol b/lib/v3-periphery/contracts/libraries/PoolAddress.sol deleted file mode 100644 index 60de385..0000000 --- a/lib/v3-periphery/contracts/libraries/PoolAddress.sol +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title Provides functions for deriving a pool address from the factory, tokens, and the fee -library PoolAddress { - bytes32 internal constant POOL_INIT_CODE_HASH = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54; - - /// @notice The identifying key of the pool - struct PoolKey { - address token0; - address token1; - uint24 fee; - } - - /// @notice Returns PoolKey: the ordered tokens with the matched fee levels - /// @param tokenA The first token of a pool, unsorted - /// @param tokenB The second token of a pool, unsorted - /// @param fee The fee level of the pool - /// @return Poolkey The pool details with ordered token0 and token1 assignments - function getPoolKey( - address tokenA, - address tokenB, - uint24 fee - ) internal pure returns (PoolKey memory) { - if (tokenA > tokenB) (tokenA, tokenB) = (tokenB, tokenA); - return PoolKey({token0: tokenA, token1: tokenB, fee: fee}); - } - - /// @notice Deterministically computes the pool address given the factory and PoolKey - /// @param factory The Uniswap V3 factory contract address - /// @param key The PoolKey - /// @return pool The contract address of the V3 pool - function computeAddress(address factory, PoolKey memory key) internal pure returns (address pool) { - require(key.token0 < key.token1); - pool = address( - uint256( - keccak256( - abi.encodePacked( - hex'ff', - factory, - keccak256(abi.encode(key.token0, key.token1, key.fee)), - POOL_INIT_CODE_HASH - ) - ) - ) - ); - } -} diff --git a/lib/v3-periphery/contracts/libraries/PoolTicksCounter.sol b/lib/v3-periphery/contracts/libraries/PoolTicksCounter.sol deleted file mode 100644 index fb0682f..0000000 --- a/lib/v3-periphery/contracts/libraries/PoolTicksCounter.sol +++ /dev/null @@ -1,96 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.6.0; - -import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol'; - -library PoolTicksCounter { - /// @dev This function counts the number of initialized ticks that would incur a gas cost between tickBefore and tickAfter. - /// When tickBefore and/or tickAfter themselves are initialized, the logic over whether we should count them depends on the - /// direction of the swap. If we are swapping upwards (tickAfter > tickBefore) we don't want to count tickBefore but we do - /// want to count tickAfter. The opposite is true if we are swapping downwards. - function countInitializedTicksCrossed( - IUniswapV3Pool self, - int24 tickBefore, - int24 tickAfter - ) internal view returns (uint32 initializedTicksCrossed) { - int16 wordPosLower; - int16 wordPosHigher; - uint8 bitPosLower; - uint8 bitPosHigher; - bool tickBeforeInitialized; - bool tickAfterInitialized; - - { - // Get the key and offset in the tick bitmap of the active tick before and after the swap. - int16 wordPos = int16((tickBefore / self.tickSpacing()) >> 8); - uint8 bitPos = uint8((tickBefore / self.tickSpacing()) % 256); - - int16 wordPosAfter = int16((tickAfter / self.tickSpacing()) >> 8); - uint8 bitPosAfter = uint8((tickAfter / self.tickSpacing()) % 256); - - // In the case where tickAfter is initialized, we only want to count it if we are swapping downwards. - // If the initializable tick after the swap is initialized, our original tickAfter is a - // multiple of tick spacing, and we are swapping downwards we know that tickAfter is initialized - // and we shouldn't count it. - tickAfterInitialized = - ((self.tickBitmap(wordPosAfter) & (1 << bitPosAfter)) > 0) && - ((tickAfter % self.tickSpacing()) == 0) && - (tickBefore > tickAfter); - - // In the case where tickBefore is initialized, we only want to count it if we are swapping upwards. - // Use the same logic as above to decide whether we should count tickBefore or not. - tickBeforeInitialized = - ((self.tickBitmap(wordPos) & (1 << bitPos)) > 0) && - ((tickBefore % self.tickSpacing()) == 0) && - (tickBefore < tickAfter); - - if (wordPos < wordPosAfter || (wordPos == wordPosAfter && bitPos <= bitPosAfter)) { - wordPosLower = wordPos; - bitPosLower = bitPos; - wordPosHigher = wordPosAfter; - bitPosHigher = bitPosAfter; - } else { - wordPosLower = wordPosAfter; - bitPosLower = bitPosAfter; - wordPosHigher = wordPos; - bitPosHigher = bitPos; - } - } - - // Count the number of initialized ticks crossed by iterating through the tick bitmap. - // Our first mask should include the lower tick and everything to its left. - uint256 mask = type(uint256).max << bitPosLower; - while (wordPosLower <= wordPosHigher) { - // If we're on the final tick bitmap page, ensure we only count up to our - // ending tick. - if (wordPosLower == wordPosHigher) { - mask = mask & (type(uint256).max >> (255 - bitPosHigher)); - } - - uint256 masked = self.tickBitmap(wordPosLower) & mask; - initializedTicksCrossed += countOneBits(masked); - wordPosLower++; - // Reset our mask so we consider all bits on the next iteration. - mask = type(uint256).max; - } - - if (tickAfterInitialized) { - initializedTicksCrossed -= 1; - } - - if (tickBeforeInitialized) { - initializedTicksCrossed -= 1; - } - - return initializedTicksCrossed; - } - - function countOneBits(uint256 x) private pure returns (uint16) { - uint16 bits = 0; - while (x != 0) { - bits++; - x &= (x - 1); - } - return bits; - } -} diff --git a/lib/v3-periphery/contracts/libraries/PositionKey.sol b/lib/v3-periphery/contracts/libraries/PositionKey.sol deleted file mode 100644 index a60fc18..0000000 --- a/lib/v3-periphery/contracts/libraries/PositionKey.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -library PositionKey { - /// @dev Returns the key of the position in the core library - function compute( - address owner, - int24 tickLower, - int24 tickUpper - ) internal pure returns (bytes32) { - return keccak256(abi.encodePacked(owner, tickLower, tickUpper)); - } -} diff --git a/lib/v3-periphery/contracts/libraries/PositionValue.sol b/lib/v3-periphery/contracts/libraries/PositionValue.sol deleted file mode 100644 index 265fc04..0000000 --- a/lib/v3-periphery/contracts/libraries/PositionValue.sol +++ /dev/null @@ -1,167 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.6.8 <0.8.0; - -import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol'; -import '@uniswap/v3-core/contracts/libraries/FixedPoint128.sol'; -import '@uniswap/v3-core/contracts/libraries/TickMath.sol'; -import '@uniswap/v3-core/contracts/libraries/Tick.sol'; -import '../interfaces/INonfungiblePositionManager.sol'; -import './LiquidityAmounts.sol'; -import './PoolAddress.sol'; -import './PositionKey.sol'; - -/// @title Returns information about the token value held in a Uniswap V3 NFT -library PositionValue { - /// @notice Returns the total amounts of token0 and token1, i.e. the sum of fees and principal - /// that a given nonfungible position manager token is worth - /// @param positionManager The Uniswap V3 NonfungiblePositionManager - /// @param tokenId The tokenId of the token for which to get the total value - /// @param sqrtRatioX96 The square root price X96 for which to calculate the principal amounts - /// @return amount0 The total amount of token0 including principal and fees - /// @return amount1 The total amount of token1 including principal and fees - function total( - INonfungiblePositionManager positionManager, - uint256 tokenId, - uint160 sqrtRatioX96 - ) internal view returns (uint256 amount0, uint256 amount1) { - (uint256 amount0Principal, uint256 amount1Principal) = principal(positionManager, tokenId, sqrtRatioX96); - (uint256 amount0Fee, uint256 amount1Fee) = fees(positionManager, tokenId); - return (amount0Principal + amount0Fee, amount1Principal + amount1Fee); - } - - /// @notice Calculates the principal (currently acting as liquidity) owed to the token owner in the event - /// that the position is burned - /// @param positionManager The Uniswap V3 NonfungiblePositionManager - /// @param tokenId The tokenId of the token for which to get the total principal owed - /// @param sqrtRatioX96 The square root price X96 for which to calculate the principal amounts - /// @return amount0 The principal amount of token0 - /// @return amount1 The principal amount of token1 - function principal( - INonfungiblePositionManager positionManager, - uint256 tokenId, - uint160 sqrtRatioX96 - ) internal view returns (uint256 amount0, uint256 amount1) { - (, , , , , int24 tickLower, int24 tickUpper, uint128 liquidity, , , , ) = positionManager.positions(tokenId); - - return - LiquidityAmounts.getAmountsForLiquidity( - sqrtRatioX96, - TickMath.getSqrtRatioAtTick(tickLower), - TickMath.getSqrtRatioAtTick(tickUpper), - liquidity - ); - } - - struct FeeParams { - address token0; - address token1; - uint24 fee; - int24 tickLower; - int24 tickUpper; - uint128 liquidity; - uint256 positionFeeGrowthInside0LastX128; - uint256 positionFeeGrowthInside1LastX128; - uint256 tokensOwed0; - uint256 tokensOwed1; - } - - /// @notice Calculates the total fees owed to the token owner - /// @param positionManager The Uniswap V3 NonfungiblePositionManager - /// @param tokenId The tokenId of the token for which to get the total fees owed - /// @return amount0 The amount of fees owed in token0 - /// @return amount1 The amount of fees owed in token1 - function fees(INonfungiblePositionManager positionManager, uint256 tokenId) - internal - view - returns (uint256 amount0, uint256 amount1) - { - ( - , - , - address token0, - address token1, - uint24 fee, - int24 tickLower, - int24 tickUpper, - uint128 liquidity, - uint256 positionFeeGrowthInside0LastX128, - uint256 positionFeeGrowthInside1LastX128, - uint256 tokensOwed0, - uint256 tokensOwed1 - ) = positionManager.positions(tokenId); - - return - _fees( - positionManager, - FeeParams({ - token0: token0, - token1: token1, - fee: fee, - tickLower: tickLower, - tickUpper: tickUpper, - liquidity: liquidity, - positionFeeGrowthInside0LastX128: positionFeeGrowthInside0LastX128, - positionFeeGrowthInside1LastX128: positionFeeGrowthInside1LastX128, - tokensOwed0: tokensOwed0, - tokensOwed1: tokensOwed1 - }) - ); - } - - function _fees(INonfungiblePositionManager positionManager, FeeParams memory feeParams) - private - view - returns (uint256 amount0, uint256 amount1) - { - (uint256 poolFeeGrowthInside0LastX128, uint256 poolFeeGrowthInside1LastX128) = - _getFeeGrowthInside( - IUniswapV3Pool( - PoolAddress.computeAddress( - positionManager.factory(), - PoolAddress.PoolKey({token0: feeParams.token0, token1: feeParams.token1, fee: feeParams.fee}) - ) - ), - feeParams.tickLower, - feeParams.tickUpper - ); - - amount0 = - FullMath.mulDiv( - poolFeeGrowthInside0LastX128 - feeParams.positionFeeGrowthInside0LastX128, - feeParams.liquidity, - FixedPoint128.Q128 - ) + - feeParams.tokensOwed0; - - amount1 = - FullMath.mulDiv( - poolFeeGrowthInside1LastX128 - feeParams.positionFeeGrowthInside1LastX128, - feeParams.liquidity, - FixedPoint128.Q128 - ) + - feeParams.tokensOwed1; - } - - function _getFeeGrowthInside( - IUniswapV3Pool pool, - int24 tickLower, - int24 tickUpper - ) private view returns (uint256 feeGrowthInside0X128, uint256 feeGrowthInside1X128) { - (, int24 tickCurrent, , , , , ) = pool.slot0(); - (, , uint256 lowerFeeGrowthOutside0X128, uint256 lowerFeeGrowthOutside1X128, , , , ) = pool.ticks(tickLower); - (, , uint256 upperFeeGrowthOutside0X128, uint256 upperFeeGrowthOutside1X128, , , , ) = pool.ticks(tickUpper); - - if (tickCurrent < tickLower) { - feeGrowthInside0X128 = lowerFeeGrowthOutside0X128 - upperFeeGrowthOutside0X128; - feeGrowthInside1X128 = lowerFeeGrowthOutside1X128 - upperFeeGrowthOutside1X128; - } else if (tickCurrent < tickUpper) { - uint256 feeGrowthGlobal0X128 = pool.feeGrowthGlobal0X128(); - uint256 feeGrowthGlobal1X128 = pool.feeGrowthGlobal1X128(); - feeGrowthInside0X128 = feeGrowthGlobal0X128 - lowerFeeGrowthOutside0X128 - upperFeeGrowthOutside0X128; - feeGrowthInside1X128 = feeGrowthGlobal1X128 - lowerFeeGrowthOutside1X128 - upperFeeGrowthOutside1X128; - } else { - feeGrowthInside0X128 = upperFeeGrowthOutside0X128 - lowerFeeGrowthOutside0X128; - feeGrowthInside1X128 = upperFeeGrowthOutside1X128 - lowerFeeGrowthOutside1X128; - } - } -} diff --git a/lib/v3-periphery/contracts/libraries/SqrtPriceMathPartial.sol b/lib/v3-periphery/contracts/libraries/SqrtPriceMathPartial.sol deleted file mode 100644 index bb8c769..0000000 --- a/lib/v3-periphery/contracts/libraries/SqrtPriceMathPartial.sol +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -import '@uniswap/v3-core/contracts/libraries/FullMath.sol'; -import '@uniswap/v3-core/contracts/libraries/UnsafeMath.sol'; -import '@uniswap/v3-core/contracts/libraries/FixedPoint96.sol'; - -/// @title Functions based on Q64.96 sqrt price and liquidity -/// @notice Exposes two functions from @uniswap/v3-core SqrtPriceMath -/// that use square root of price as a Q64.96 and liquidity to compute deltas -library SqrtPriceMathPartial { - /// @notice Gets the amount0 delta between two prices - /// @dev Calculates liquidity / sqrt(lower) - liquidity / sqrt(upper), - /// i.e. liquidity * (sqrt(upper) - sqrt(lower)) / (sqrt(upper) * sqrt(lower)) - /// @param sqrtRatioAX96 A sqrt price - /// @param sqrtRatioBX96 Another sqrt price - /// @param liquidity The amount of usable liquidity - /// @param roundUp Whether to round the amount up or down - /// @return amount0 Amount of token0 required to cover a position of size liquidity between the two passed prices - function getAmount0Delta( - uint160 sqrtRatioAX96, - uint160 sqrtRatioBX96, - uint128 liquidity, - bool roundUp - ) internal pure returns (uint256 amount0) { - if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96); - - uint256 numerator1 = uint256(liquidity) << FixedPoint96.RESOLUTION; - uint256 numerator2 = sqrtRatioBX96 - sqrtRatioAX96; - - require(sqrtRatioAX96 > 0); - - return - roundUp - ? UnsafeMath.divRoundingUp( - FullMath.mulDivRoundingUp(numerator1, numerator2, sqrtRatioBX96), - sqrtRatioAX96 - ) - : FullMath.mulDiv(numerator1, numerator2, sqrtRatioBX96) / sqrtRatioAX96; - } - - /// @notice Gets the amount1 delta between two prices - /// @dev Calculates liquidity * (sqrt(upper) - sqrt(lower)) - /// @param sqrtRatioAX96 A sqrt price - /// @param sqrtRatioBX96 Another sqrt price - /// @param liquidity The amount of usable liquidity - /// @param roundUp Whether to round the amount up, or down - /// @return amount1 Amount of token1 required to cover a position of size liquidity between the two passed prices - function getAmount1Delta( - uint160 sqrtRatioAX96, - uint160 sqrtRatioBX96, - uint128 liquidity, - bool roundUp - ) internal pure returns (uint256 amount1) { - if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96); - - return - roundUp - ? FullMath.mulDivRoundingUp(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96) - : FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96); - } -} diff --git a/lib/v3-periphery/contracts/libraries/TokenRatioSortOrder.sol b/lib/v3-periphery/contracts/libraries/TokenRatioSortOrder.sol deleted file mode 100644 index d9a2c9e..0000000 --- a/lib/v3-periphery/contracts/libraries/TokenRatioSortOrder.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity =0.7.6; - -library TokenRatioSortOrder { - int256 constant NUMERATOR_MOST = 300; - int256 constant NUMERATOR_MORE = 200; - int256 constant NUMERATOR = 100; - - int256 constant DENOMINATOR_MOST = -300; - int256 constant DENOMINATOR_MORE = -200; - int256 constant DENOMINATOR = -100; -} diff --git a/lib/v3-periphery/contracts/libraries/TransferHelper.sol b/lib/v3-periphery/contracts/libraries/TransferHelper.sol deleted file mode 100644 index 7fc2797..0000000 --- a/lib/v3-periphery/contracts/libraries/TransferHelper.sol +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.6.0; - -import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; - -library TransferHelper { - /// @notice Transfers tokens from the targeted address to the given destination - /// @notice Errors with 'STF' if transfer fails - /// @param token The contract address of the token to be transferred - /// @param from The originating address from which the tokens will be transferred - /// @param to The destination address of the transfer - /// @param value The amount to be transferred - function safeTransferFrom( - address token, - address from, - address to, - uint256 value - ) internal { - (bool success, bytes memory data) = - token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value)); - require(success && (data.length == 0 || abi.decode(data, (bool))), 'STF'); - } - - /// @notice Transfers tokens from msg.sender to a recipient - /// @dev Errors with ST if transfer fails - /// @param token The contract address of the token which will be transferred - /// @param to The recipient of the transfer - /// @param value The value of the transfer - function safeTransfer( - address token, - address to, - uint256 value - ) internal { - (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value)); - require(success && (data.length == 0 || abi.decode(data, (bool))), 'ST'); - } - - /// @notice Approves the stipulated contract to spend the given allowance in the given token - /// @dev Errors with 'SA' if transfer fails - /// @param token The contract address of the token to be approved - /// @param to The target of the approval - /// @param value The amount of the given token the target will be allowed to spend - function safeApprove( - address token, - address to, - uint256 value - ) internal { - (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, to, value)); - require(success && (data.length == 0 || abi.decode(data, (bool))), 'SA'); - } - - /// @notice Transfers ETH to the recipient address - /// @dev Fails with `STE` - /// @param to The destination of the transfer - /// @param value The value to be transferred - function safeTransferETH(address to, uint256 value) internal { - (bool success, ) = to.call{value: value}(new bytes(0)); - require(success, 'STE'); - } -} diff --git a/lib/v3-periphery/contracts/test/Base64Test.sol b/lib/v3-periphery/contracts/test/Base64Test.sol deleted file mode 100644 index cb66a87..0000000 --- a/lib/v3-periphery/contracts/test/Base64Test.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import 'base64-sol/base64.sol'; - -contract Base64Test { - function encode(bytes memory data) external pure returns (string memory) { - return Base64.encode(data); - } - - function getGasCostOfEncode(bytes memory data) external view returns (uint256) { - uint256 gasBefore = gasleft(); - Base64.encode(data); - return gasBefore - gasleft(); - } -} diff --git a/lib/v3-periphery/contracts/test/LiquidityAmountsTest.sol b/lib/v3-periphery/contracts/test/LiquidityAmountsTest.sol deleted file mode 100644 index dad61c0..0000000 --- a/lib/v3-periphery/contracts/test/LiquidityAmountsTest.sol +++ /dev/null @@ -1,120 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../libraries/LiquidityAmounts.sol'; - -contract LiquidityAmountsTest { - function getLiquidityForAmount0( - uint160 sqrtRatioAX96, - uint160 sqrtRatioBX96, - uint256 amount0 - ) external pure returns (uint128 liquidity) { - return LiquidityAmounts.getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0); - } - - function getGasCostOfGetLiquidityForAmount0( - uint160 sqrtRatioAX96, - uint160 sqrtRatioBX96, - uint256 amount0 - ) external view returns (uint256) { - uint256 gasBefore = gasleft(); - LiquidityAmounts.getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0); - return gasBefore - gasleft(); - } - - function getLiquidityForAmount1( - uint160 sqrtRatioAX96, - uint160 sqrtRatioBX96, - uint256 amount1 - ) external pure returns (uint128 liquidity) { - return LiquidityAmounts.getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1); - } - - function getGasCostOfGetLiquidityForAmount1( - uint160 sqrtRatioAX96, - uint160 sqrtRatioBX96, - uint256 amount1 - ) external view returns (uint256) { - uint256 gasBefore = gasleft(); - LiquidityAmounts.getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1); - return gasBefore - gasleft(); - } - - function getLiquidityForAmounts( - uint160 sqrtRatioX96, - uint160 sqrtRatioAX96, - uint160 sqrtRatioBX96, - uint256 amount0, - uint256 amount1 - ) external pure returns (uint128 liquidity) { - return LiquidityAmounts.getLiquidityForAmounts(sqrtRatioX96, sqrtRatioAX96, sqrtRatioBX96, amount0, amount1); - } - - function getGasCostOfGetLiquidityForAmounts( - uint160 sqrtRatioX96, - uint160 sqrtRatioAX96, - uint160 sqrtRatioBX96, - uint256 amount0, - uint256 amount1 - ) external view returns (uint256) { - uint256 gasBefore = gasleft(); - LiquidityAmounts.getLiquidityForAmounts(sqrtRatioX96, sqrtRatioAX96, sqrtRatioBX96, amount0, amount1); - return gasBefore - gasleft(); - } - - function getAmount0ForLiquidity( - uint160 sqrtRatioAX96, - uint160 sqrtRatioBX96, - uint128 liquidity - ) external pure returns (uint256 amount0) { - return LiquidityAmounts.getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity); - } - - function getGasCostOfGetAmount0ForLiquidity( - uint160 sqrtRatioAX96, - uint160 sqrtRatioBX96, - uint128 liquidity - ) external view returns (uint256) { - uint256 gasBefore = gasleft(); - LiquidityAmounts.getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity); - return gasBefore - gasleft(); - } - - function getAmount1ForLiquidity( - uint160 sqrtRatioAX96, - uint160 sqrtRatioBX96, - uint128 liquidity - ) external pure returns (uint256 amount1) { - return LiquidityAmounts.getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity); - } - - function getGasCostOfGetAmount1ForLiquidity( - uint160 sqrtRatioAX96, - uint160 sqrtRatioBX96, - uint128 liquidity - ) external view returns (uint256) { - uint256 gasBefore = gasleft(); - LiquidityAmounts.getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, liquidity); - return gasBefore - gasleft(); - } - - function getAmountsForLiquidity( - uint160 sqrtRatioX96, - uint160 sqrtRatioAX96, - uint160 sqrtRatioBX96, - uint128 liquidity - ) external pure returns (uint256 amount0, uint256 amount1) { - return LiquidityAmounts.getAmountsForLiquidity(sqrtRatioX96, sqrtRatioAX96, sqrtRatioBX96, liquidity); - } - - function getGasCostOfGetAmountsForLiquidity( - uint160 sqrtRatioX96, - uint160 sqrtRatioAX96, - uint160 sqrtRatioBX96, - uint128 liquidity - ) external view returns (uint256) { - uint256 gasBefore = gasleft(); - LiquidityAmounts.getAmountsForLiquidity(sqrtRatioX96, sqrtRatioAX96, sqrtRatioBX96, liquidity); - return gasBefore - gasleft(); - } -} diff --git a/lib/v3-periphery/contracts/test/MockObservable.sol b/lib/v3-periphery/contracts/test/MockObservable.sol deleted file mode 100644 index 19e8674..0000000 --- a/lib/v3-periphery/contracts/test/MockObservable.sol +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -contract MockObservable { - Observation private observation0; - Observation private observation1; - - struct Observation { - uint32 secondsAgo; - int56 tickCumulatives; - uint160 secondsPerLiquidityCumulativeX128s; - } - - constructor( - uint32[] memory secondsAgos, - int56[] memory tickCumulatives, - uint160[] memory secondsPerLiquidityCumulativeX128s - ) { - require( - secondsAgos.length == 2 && tickCumulatives.length == 2 && secondsPerLiquidityCumulativeX128s.length == 2, - 'Invalid test case size' - ); - - observation0 = Observation(secondsAgos[0], tickCumulatives[0], secondsPerLiquidityCumulativeX128s[0]); - observation1 = Observation(secondsAgos[1], tickCumulatives[1], secondsPerLiquidityCumulativeX128s[1]); - } - - function observe(uint32[] calldata secondsAgos) - external - view - returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s) - { - require( - secondsAgos[0] == observation0.secondsAgo && secondsAgos[1] == observation1.secondsAgo, - 'Invalid test case' - ); - - int56[] memory _tickCumulatives = new int56[](2); - _tickCumulatives[0] = observation0.tickCumulatives; - _tickCumulatives[1] = observation1.tickCumulatives; - - uint160[] memory _secondsPerLiquidityCumulativeX128s = new uint160[](2); - _secondsPerLiquidityCumulativeX128s[0] = observation0.secondsPerLiquidityCumulativeX128s; - _secondsPerLiquidityCumulativeX128s[1] = observation1.secondsPerLiquidityCumulativeX128s; - - return (_tickCumulatives, _secondsPerLiquidityCumulativeX128s); - } -} diff --git a/lib/v3-periphery/contracts/test/MockObservations.sol b/lib/v3-periphery/contracts/test/MockObservations.sol deleted file mode 100644 index 81b5c75..0000000 --- a/lib/v3-periphery/contracts/test/MockObservations.sol +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '@uniswap/v3-core/contracts/libraries/Oracle.sol'; - -contract MockObservations { - Oracle.Observation[4] internal oracleObservations; - - int24 slot0Tick; - uint16 internal slot0ObservationCardinality; - uint16 internal slot0ObservationIndex; - uint128 public liquidity; - - bool internal lastObservationCurrentTimestamp; - - constructor( - uint32[4] memory _blockTimestamps, - int56[4] memory _tickCumulatives, - uint128[4] memory _secondsPerLiquidityCumulativeX128s, - bool[4] memory _initializeds, - int24 _tick, - uint16 _observationCardinality, - uint16 _observationIndex, - bool _lastObservationCurrentTimestamp, - uint128 _liquidity - ) { - for (uint256 i = 0; i < _blockTimestamps.length; i++) { - oracleObservations[i] = Oracle.Observation({ - blockTimestamp: _blockTimestamps[i], - tickCumulative: _tickCumulatives[i], - secondsPerLiquidityCumulativeX128: _secondsPerLiquidityCumulativeX128s[i], - initialized: _initializeds[i] - }); - } - - slot0Tick = _tick; - slot0ObservationCardinality = _observationCardinality; - slot0ObservationIndex = _observationIndex; - lastObservationCurrentTimestamp = _lastObservationCurrentTimestamp; - liquidity = _liquidity; - } - - function slot0() - external - view - returns ( - uint160, - int24, - uint16, - uint16, - uint16, - uint8, - bool - ) - { - return (0, slot0Tick, slot0ObservationIndex, slot0ObservationCardinality, 0, 0, false); - } - - function observations(uint256 index) - external - view - returns ( - uint32, - int56, - uint160, - bool - ) - { - Oracle.Observation memory observation = oracleObservations[index]; - if (lastObservationCurrentTimestamp) { - observation.blockTimestamp = - uint32(block.timestamp) - - (oracleObservations[slot0ObservationIndex].blockTimestamp - observation.blockTimestamp); - } - return ( - observation.blockTimestamp, - observation.tickCumulative, - observation.secondsPerLiquidityCumulativeX128, - observation.initialized - ); - } -} diff --git a/lib/v3-periphery/contracts/test/MockTimeNonfungiblePositionManager.sol b/lib/v3-periphery/contracts/test/MockTimeNonfungiblePositionManager.sol deleted file mode 100644 index 4b1c1f9..0000000 --- a/lib/v3-periphery/contracts/test/MockTimeNonfungiblePositionManager.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; -pragma abicoder v2; - -import '../NonfungiblePositionManager.sol'; - -contract MockTimeNonfungiblePositionManager is NonfungiblePositionManager { - uint256 time; - - constructor( - address _factory, - address _WETH9, - address _tokenDescriptor - ) NonfungiblePositionManager(_factory, _WETH9, _tokenDescriptor) {} - - function _blockTimestamp() internal view override returns (uint256) { - return time; - } - - function setTime(uint256 _time) external { - time = _time; - } -} diff --git a/lib/v3-periphery/contracts/test/MockTimeSwapRouter.sol b/lib/v3-periphery/contracts/test/MockTimeSwapRouter.sol deleted file mode 100644 index 984707b..0000000 --- a/lib/v3-periphery/contracts/test/MockTimeSwapRouter.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; -pragma abicoder v2; - -import '../SwapRouter.sol'; - -contract MockTimeSwapRouter is SwapRouter { - uint256 time; - - constructor(address _factory, address _WETH9) SwapRouter(_factory, _WETH9) {} - - function _blockTimestamp() internal view override returns (uint256) { - return time; - } - - function setTime(uint256 _time) external { - time = _time; - } -} diff --git a/lib/v3-periphery/contracts/test/NFTDescriptorTest.sol b/lib/v3-periphery/contracts/test/NFTDescriptorTest.sol deleted file mode 100644 index 89f783b..0000000 --- a/lib/v3-periphery/contracts/test/NFTDescriptorTest.sol +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; -pragma abicoder v2; - -import '../libraries/NFTDescriptor.sol'; -import '../libraries/NFTSVG.sol'; -import '../libraries/HexStrings.sol'; - -contract NFTDescriptorTest { - using HexStrings for uint256; - - function constructTokenURI(NFTDescriptor.ConstructTokenURIParams calldata params) - public - pure - returns (string memory) - { - return NFTDescriptor.constructTokenURI(params); - } - - function getGasCostOfConstructTokenURI(NFTDescriptor.ConstructTokenURIParams calldata params) - public - view - returns (uint256) - { - uint256 gasBefore = gasleft(); - NFTDescriptor.constructTokenURI(params); - return gasBefore - gasleft(); - } - - function tickToDecimalString( - int24 tick, - int24 tickSpacing, - uint8 token0Decimals, - uint8 token1Decimals, - bool flipRatio - ) public pure returns (string memory) { - return NFTDescriptor.tickToDecimalString(tick, tickSpacing, token0Decimals, token1Decimals, flipRatio); - } - - function fixedPointToDecimalString( - uint160 sqrtRatioX96, - uint8 token0Decimals, - uint8 token1Decimals - ) public pure returns (string memory) { - return NFTDescriptor.fixedPointToDecimalString(sqrtRatioX96, token0Decimals, token1Decimals); - } - - function feeToPercentString(uint24 fee) public pure returns (string memory) { - return NFTDescriptor.feeToPercentString(fee); - } - - function addressToString(address _address) public pure returns (string memory) { - return NFTDescriptor.addressToString(_address); - } - - function generateSVGImage(NFTDescriptor.ConstructTokenURIParams memory params) public pure returns (string memory) { - return NFTDescriptor.generateSVGImage(params); - } - - function tokenToColorHex(address token, uint256 offset) public pure returns (string memory) { - return NFTDescriptor.tokenToColorHex(uint256(token), offset); - } - - function sliceTokenHex(address token, uint256 offset) public pure returns (uint256) { - return NFTDescriptor.sliceTokenHex(uint256(token), offset); - } - - function rangeLocation(int24 tickLower, int24 tickUpper) public pure returns (string memory, string memory) { - return NFTSVG.rangeLocation(tickLower, tickUpper); - } - - function isRare(uint256 tokenId, address poolAddress) public pure returns (bool) { - return NFTSVG.isRare(tokenId, poolAddress); - } -} diff --git a/lib/v3-periphery/contracts/test/NonfungiblePositionManagerPositionsGasTest.sol b/lib/v3-periphery/contracts/test/NonfungiblePositionManagerPositionsGasTest.sol deleted file mode 100644 index 7bec623..0000000 --- a/lib/v3-periphery/contracts/test/NonfungiblePositionManagerPositionsGasTest.sol +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../interfaces/INonfungiblePositionManager.sol'; - -contract NonfungiblePositionManagerPositionsGasTest { - INonfungiblePositionManager immutable nonfungiblePositionManager; - - constructor(INonfungiblePositionManager _nonfungiblePositionManager) { - nonfungiblePositionManager = _nonfungiblePositionManager; - } - - function getGasCostOfPositions(uint256 tokenId) external view returns (uint256) { - uint256 gasBefore = gasleft(); - nonfungiblePositionManager.positions(tokenId); - return gasBefore - gasleft(); - } -} diff --git a/lib/v3-periphery/contracts/test/OracleTest.sol b/lib/v3-periphery/contracts/test/OracleTest.sol deleted file mode 100644 index b0cf921..0000000 --- a/lib/v3-periphery/contracts/test/OracleTest.sol +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; -pragma abicoder v2; - -import '../libraries/OracleLibrary.sol'; - -contract OracleTest { - function consult(address pool, uint32 secondsAgo) - public - view - returns (int24 arithmeticMeanTick, uint128 harmonicMeanLiquidity) - { - return OracleLibrary.consult(pool, secondsAgo); - } - - function getQuoteAtTick( - int24 tick, - uint128 baseAmount, - address baseToken, - address quoteToken - ) public pure returns (uint256 quoteAmount) { - quoteAmount = OracleLibrary.getQuoteAtTick(tick, baseAmount, baseToken, quoteToken); - } - - // For gas snapshot test - function getGasCostOfConsult(address pool, uint32 period) public view returns (uint256) { - uint256 gasBefore = gasleft(); - OracleLibrary.consult(pool, period); - return gasBefore - gasleft(); - } - - function getGasCostOfGetQuoteAtTick( - int24 tick, - uint128 baseAmount, - address baseToken, - address quoteToken - ) public view returns (uint256) { - uint256 gasBefore = gasleft(); - OracleLibrary.getQuoteAtTick(tick, baseAmount, baseToken, quoteToken); - return gasBefore - gasleft(); - } - - function getOldestObservationSecondsAgo(address pool) - public - view - returns (uint32 secondsAgo, uint32 currentTimestamp) - { - secondsAgo = OracleLibrary.getOldestObservationSecondsAgo(pool); - currentTimestamp = uint32(block.timestamp); - } - - function getBlockStartingTickAndLiquidity(address pool) public view returns (int24, uint128) { - return OracleLibrary.getBlockStartingTickAndLiquidity(pool); - } - - function getWeightedArithmeticMeanTick(OracleLibrary.WeightedTickData[] memory observations) - public - pure - returns (int24 arithmeticMeanWeightedTick) - { - return OracleLibrary.getWeightedArithmeticMeanTick(observations); - } - - function getChainedPrice(address[] memory tokens, int24[] memory ticks) public view returns (int256 syntheticTick) { - return OracleLibrary.getChainedPrice(tokens, ticks); - } -} diff --git a/lib/v3-periphery/contracts/test/PathTest.sol b/lib/v3-periphery/contracts/test/PathTest.sol deleted file mode 100644 index 1a7280e..0000000 --- a/lib/v3-periphery/contracts/test/PathTest.sol +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../libraries/Path.sol'; - -contract PathTest { - function hasMultiplePools(bytes memory path) public pure returns (bool) { - return Path.hasMultiplePools(path); - } - - function decodeFirstPool(bytes memory path) - public - pure - returns ( - address tokenA, - address tokenB, - uint24 fee - ) - { - return Path.decodeFirstPool(path); - } - - function getFirstPool(bytes memory path) public pure returns (bytes memory) { - return Path.getFirstPool(path); - } - - function skipToken(bytes memory path) public pure returns (bytes memory) { - return Path.skipToken(path); - } - - // gas funcs - function getGasCostOfDecodeFirstPool(bytes memory path) public view returns (uint256) { - uint256 gasBefore = gasleft(); - Path.decodeFirstPool(path); - return gasBefore - gasleft(); - } -} diff --git a/lib/v3-periphery/contracts/test/PeripheryImmutableStateTest.sol b/lib/v3-periphery/contracts/test/PeripheryImmutableStateTest.sol deleted file mode 100644 index 6298162..0000000 --- a/lib/v3-periphery/contracts/test/PeripheryImmutableStateTest.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity =0.7.6; - -import '../base/PeripheryImmutableState.sol'; - -contract PeripheryImmutableStateTest is PeripheryImmutableState { - constructor(address _factory, address _WETH9) PeripheryImmutableState(_factory, _WETH9) {} -} diff --git a/lib/v3-periphery/contracts/test/PoolAddressTest.sol b/lib/v3-periphery/contracts/test/PoolAddressTest.sol deleted file mode 100644 index c1571e4..0000000 --- a/lib/v3-periphery/contracts/test/PoolAddressTest.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../libraries/PoolAddress.sol'; - -contract PoolAddressTest { - function POOL_INIT_CODE_HASH() external pure returns (bytes32) { - return PoolAddress.POOL_INIT_CODE_HASH; - } - - function computeAddress( - address factory, - address token0, - address token1, - uint24 fee - ) external pure returns (address) { - return PoolAddress.computeAddress(factory, PoolAddress.PoolKey({token0: token0, token1: token1, fee: fee})); - } - - function getGasCostOfComputeAddress( - address factory, - address token0, - address token1, - uint24 fee - ) external view returns (uint256) { - uint256 gasBefore = gasleft(); - PoolAddress.computeAddress(factory, PoolAddress.PoolKey({token0: token0, token1: token1, fee: fee})); - return gasBefore - gasleft(); - } -} diff --git a/lib/v3-periphery/contracts/test/PoolTicksCounterTest.sol b/lib/v3-periphery/contracts/test/PoolTicksCounterTest.sol deleted file mode 100644 index 3d47bf7..0000000 --- a/lib/v3-periphery/contracts/test/PoolTicksCounterTest.sol +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol'; - -pragma solidity >=0.6.0; - -import '../libraries/PoolTicksCounter.sol'; - -contract PoolTicksCounterTest { - using PoolTicksCounter for IUniswapV3Pool; - - function countInitializedTicksCrossed( - IUniswapV3Pool pool, - int24 tickBefore, - int24 tickAfter - ) external view returns (uint32 initializedTicksCrossed) { - return pool.countInitializedTicksCrossed(tickBefore, tickAfter); - } -} diff --git a/lib/v3-periphery/contracts/test/PositionValueTest.sol b/lib/v3-periphery/contracts/test/PositionValueTest.sol deleted file mode 100644 index 7752f7a..0000000 --- a/lib/v3-periphery/contracts/test/PositionValueTest.sol +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../libraries/PositionValue.sol'; -import '../interfaces/INonfungiblePositionManager.sol'; - -contract PositionValueTest { - function total( - INonfungiblePositionManager nft, - uint256 tokenId, - uint160 sqrtRatioX96 - ) external view returns (uint256 amount0, uint256 amount1) { - return PositionValue.total(nft, tokenId, sqrtRatioX96); - } - - function principal( - INonfungiblePositionManager nft, - uint256 tokenId, - uint160 sqrtRatioX96 - ) external view returns (uint256 amount0, uint256 amount1) { - return PositionValue.principal(nft, tokenId, sqrtRatioX96); - } - - function fees(INonfungiblePositionManager nft, uint256 tokenId) - external - view - returns (uint256 amount0, uint256 amount1) - { - return PositionValue.fees(nft, tokenId); - } - - function totalGas( - INonfungiblePositionManager nft, - uint256 tokenId, - uint160 sqrtRatioX96 - ) external view returns (uint256) { - uint256 gasBefore = gasleft(); - PositionValue.total(nft, tokenId, sqrtRatioX96); - return gasBefore - gasleft(); - } - - function principalGas( - INonfungiblePositionManager nft, - uint256 tokenId, - uint160 sqrtRatioX96 - ) external view returns (uint256) { - uint256 gasBefore = gasleft(); - PositionValue.principal(nft, tokenId, sqrtRatioX96); - return gasBefore - gasleft(); - } - - function feesGas(INonfungiblePositionManager nft, uint256 tokenId) external view returns (uint256) { - uint256 gasBefore = gasleft(); - PositionValue.fees(nft, tokenId); - return gasBefore - gasleft(); - } -} diff --git a/lib/v3-periphery/contracts/test/SelfPermitTest.sol b/lib/v3-periphery/contracts/test/SelfPermitTest.sol deleted file mode 100644 index 1a3c022..0000000 --- a/lib/v3-periphery/contracts/test/SelfPermitTest.sol +++ /dev/null @@ -1,9 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../base/SelfPermit.sol'; - -/// @dev Same as SelfPermit but not abstract -contract SelfPermitTest is SelfPermit { - -} diff --git a/lib/v3-periphery/contracts/test/TestCallbackValidation.sol b/lib/v3-periphery/contracts/test/TestCallbackValidation.sol deleted file mode 100644 index e0c2eeb..0000000 --- a/lib/v3-periphery/contracts/test/TestCallbackValidation.sol +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../libraries/CallbackValidation.sol'; - -contract TestCallbackValidation { - function verifyCallback( - address factory, - address tokenA, - address tokenB, - uint24 fee - ) external view returns (IUniswapV3Pool pool) { - return CallbackValidation.verifyCallback(factory, tokenA, tokenB, fee); - } -} diff --git a/lib/v3-periphery/contracts/test/TestERC20.sol b/lib/v3-periphery/contracts/test/TestERC20.sol deleted file mode 100644 index 66ed4ac..0000000 --- a/lib/v3-periphery/contracts/test/TestERC20.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '@openzeppelin/contracts/drafts/ERC20Permit.sol'; - -contract TestERC20 is ERC20Permit { - constructor(uint256 amountToMint) ERC20('Test ERC20', 'TEST') ERC20Permit('Test ERC20') { - _mint(msg.sender, amountToMint); - } -} diff --git a/lib/v3-periphery/contracts/test/TestERC20Metadata.sol b/lib/v3-periphery/contracts/test/TestERC20Metadata.sol deleted file mode 100644 index af94bf6..0000000 --- a/lib/v3-periphery/contracts/test/TestERC20Metadata.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '@openzeppelin/contracts/drafts/ERC20Permit.sol'; - -contract TestERC20Metadata is ERC20Permit { - constructor( - uint256 amountToMint, - string memory name, - string memory symbol - ) ERC20(name, symbol) ERC20Permit(name) { - _mint(msg.sender, amountToMint); - } -} diff --git a/lib/v3-periphery/contracts/test/TestERC20PermitAllowed.sol b/lib/v3-periphery/contracts/test/TestERC20PermitAllowed.sol deleted file mode 100644 index 1bdf8ab..0000000 --- a/lib/v3-periphery/contracts/test/TestERC20PermitAllowed.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import './TestERC20.sol'; -import '../interfaces/external/IERC20PermitAllowed.sol'; - -// has a fake permit that just uses the other signature type for type(uint256).max -contract TestERC20PermitAllowed is TestERC20, IERC20PermitAllowed { - constructor(uint256 amountToMint) TestERC20(amountToMint) {} - - function permit( - address holder, - address spender, - uint256 nonce, - uint256 expiry, - bool allowed, - uint8 v, - bytes32 r, - bytes32 s - ) external override { - require(this.nonces(holder) == nonce, 'TestERC20PermitAllowed::permit: wrong nonce'); - permit(holder, spender, allowed ? type(uint256).max : 0, expiry, v, r, s); - } -} diff --git a/lib/v3-periphery/contracts/test/TestMulticall.sol b/lib/v3-periphery/contracts/test/TestMulticall.sol deleted file mode 100644 index 5d351d3..0000000 --- a/lib/v3-periphery/contracts/test/TestMulticall.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; -pragma abicoder v2; - -import '../base/Multicall.sol'; - -contract TestMulticall is Multicall { - function functionThatRevertsWithError(string memory error) external pure { - revert(error); - } - - struct Tuple { - uint256 a; - uint256 b; - } - - function functionThatReturnsTuple(uint256 a, uint256 b) external pure returns (Tuple memory tuple) { - tuple = Tuple({b: a, a: b}); - } - - uint256 public paid; - - function pays() external payable { - paid += msg.value; - } - - function returnSender() external view returns (address) { - return msg.sender; - } -} diff --git a/lib/v3-periphery/contracts/test/TestPositionNFTOwner.sol b/lib/v3-periphery/contracts/test/TestPositionNFTOwner.sol deleted file mode 100644 index 58f1818..0000000 --- a/lib/v3-periphery/contracts/test/TestPositionNFTOwner.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '../interfaces/external/IERC1271.sol'; - -contract TestPositionNFTOwner is IERC1271 { - address public owner; - - function setOwner(address _owner) external { - owner = _owner; - } - - function isValidSignature(bytes32 hash, bytes memory signature) external view override returns (bytes4 magicValue) { - bytes32 r; - bytes32 s; - uint8 v; - assembly { - r := mload(add(signature, 0x20)) - s := mload(add(signature, 0x40)) - v := byte(0, mload(add(signature, 0x60))) - } - if (ecrecover(hash, v, r, s) == owner) { - return bytes4(0x1626ba7e); - } else { - return bytes4(0); - } - } -} diff --git a/lib/v3-periphery/contracts/test/TestUniswapV3Callee.sol b/lib/v3-periphery/contracts/test/TestUniswapV3Callee.sol deleted file mode 100644 index 1400bd6..0000000 --- a/lib/v3-periphery/contracts/test/TestUniswapV3Callee.sol +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.7.6; - -import '@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol'; -import '@uniswap/v3-core/contracts/libraries/SafeCast.sol'; -import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol'; -import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; - -contract TestUniswapV3Callee is IUniswapV3SwapCallback { - using SafeCast for uint256; - - function swapExact0For1( - address pool, - uint256 amount0In, - address recipient, - uint160 sqrtPriceLimitX96 - ) external { - IUniswapV3Pool(pool).swap(recipient, true, amount0In.toInt256(), sqrtPriceLimitX96, abi.encode(msg.sender)); - } - - function swap0ForExact1( - address pool, - uint256 amount1Out, - address recipient, - uint160 sqrtPriceLimitX96 - ) external { - IUniswapV3Pool(pool).swap(recipient, true, -amount1Out.toInt256(), sqrtPriceLimitX96, abi.encode(msg.sender)); - } - - function swapExact1For0( - address pool, - uint256 amount1In, - address recipient, - uint160 sqrtPriceLimitX96 - ) external { - IUniswapV3Pool(pool).swap(recipient, false, amount1In.toInt256(), sqrtPriceLimitX96, abi.encode(msg.sender)); - } - - function swap1ForExact0( - address pool, - uint256 amount0Out, - address recipient, - uint160 sqrtPriceLimitX96 - ) external { - IUniswapV3Pool(pool).swap(recipient, false, -amount0Out.toInt256(), sqrtPriceLimitX96, abi.encode(msg.sender)); - } - - function uniswapV3SwapCallback( - int256 amount0Delta, - int256 amount1Delta, - bytes calldata data - ) external override { - address sender = abi.decode(data, (address)); - - if (amount0Delta > 0) { - IERC20(IUniswapV3Pool(msg.sender).token0()).transferFrom(sender, msg.sender, uint256(amount0Delta)); - } else { - assert(amount1Delta > 0); - IERC20(IUniswapV3Pool(msg.sender).token1()).transferFrom(sender, msg.sender, uint256(amount1Delta)); - } - } -} diff --git a/lib/v3-periphery/contracts/test/TickLensTest.sol b/lib/v3-periphery/contracts/test/TickLensTest.sol deleted file mode 100644 index 55cb7fd..0000000 --- a/lib/v3-periphery/contracts/test/TickLensTest.sol +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; -pragma abicoder v2; - -import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol'; -import '../lens/TickLens.sol'; - -/// @title Tick Lens contract -contract TickLensTest is TickLens { - function getGasCostOfGetPopulatedTicksInWord(address pool, int16 tickBitmapIndex) external view returns (uint256) { - uint256 gasBefore = gasleft(); - getPopulatedTicksInWord(pool, tickBitmapIndex); - return gasBefore - gasleft(); - } -} diff --git a/lib/v3-periphery/deploys.md b/lib/v3-periphery/deploys.md deleted file mode 100644 index c0af53c..0000000 --- a/lib/v3-periphery/deploys.md +++ /dev/null @@ -1,25 +0,0 @@ -# Deployment addresses - -The latest version of `@uniswap/v3-core`, `@uniswap/v3-periphery`, `@uniswap/swap-router-contracts`, and `@uniswap/v3-staker` are deployed at the addresses listed below. Integrators should **no longer assume that they are deployed to the same addresses across chains** and be extremely careful to confirm mappings below. - -| Contract | Mainnet, Polygon, Optimism, Arbitrum, Testnets Address | Celo Address | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------ | -------------------------------------------- | -| [UniswapV3Factory](https://github.com/Uniswap/uniswap-v3-core/blob/v1.0.0/contracts/UniswapV3Factory.sol) | `0x1F98431c8aD98523631AE4a59f267346ea31F984` | `0xAfE208a311B21f13EF87E33A90049fC17A7acDEc` | -| [Multicall2](https://etherscan.io/address/0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696#code) | `0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696` | `0x633987602DE5C4F337e3DbF265303A1080324204` | -| [ProxyAdmin](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.1-solc-0.7-2/contracts/proxy/ProxyAdmin.sol) | `0xB753548F6E010e7e680BA186F9Ca1BdAB2E90cf2` | `0xc1b262Dd7643D4B7cA9e51631bBd900a564BF49A` | -| [TickLens](https://github.com/Uniswap/uniswap-v3-periphery/blob/v1.0.0/contracts/lens/TickLens.sol) | `0xbfd8137f7d1516D3ea5cA83523914859ec47F573` | `0x5f115D9113F88e0a0Db1b5033D90D4a9690AcD3D` | -| [Quoter](https://github.com/Uniswap/uniswap-v3-periphery/blob/v1.0.0/contracts/lens/Quoter.sol) | `0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6` | `0x82825d0554fA07f7FC52Ab63c961F330fdEFa8E8` | -| [SwapRouter](https://github.com/Uniswap/uniswap-v3-periphery/blob/v1.0.0/contracts/SwapRouter.sol) | `0xE592427A0AEce92De3Edee1F18E0157C05861564` | `0x5615CDAb10dc425a742d643d949a7F474C01abc4` | -| [NFTDescriptor](https://github.com/Uniswap/uniswap-v3-periphery/blob/v1.0.0/contracts/libraries/NFTDescriptor.sol) | `0x42B24A95702b9986e82d421cC3568932790A48Ec` | `0xa9Fd765d85938D278cb0b108DbE4BF7186831186` | -| [NonfungibleTokenPositionDescriptor](https://github.com/Uniswap/uniswap-v3-periphery/blob/v1.0.0/contracts/NonfungibleTokenPositionDescriptor.sol) | `0x91ae842A5Ffd8d12023116943e72A606179294f3` | `0x644023b316bB65175C347DE903B60a756F6dd554` | -| [TransparentUpgradeableProxy](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.1-solc-0.7-2/contracts/proxy/TransparentUpgradeableProxy.sol) | `0xEe6A57eC80ea46401049E92587E52f5Ec1c24785` | `0x505B43c452AA4443e0a6B84bb37771494633Fde9` | -| [NonfungiblePositionManager](https://github.com/Uniswap/uniswap-v3-periphery/blob/v1.0.0/contracts/NonfungiblePositionManager.sol) | `0xC36442b4a4522E871399CD717aBDD847Ab11FE88` | `0x3d79EdAaBC0EaB6F08ED885C05Fc0B014290D95A` | -| [V3Migrator](https://github.com/Uniswap/uniswap-v3-periphery/blob/v1.0.0/contracts/V3Migrator.sol) | `0xA5644E29708357803b5A882D272c41cC0dF92B34` | `0x3cFd4d48EDfDCC53D3f173F596f621064614C582` | - -These addresses are final and were deployed from these npm package versions: - -- `@uniswap/v3-core`: [`1.0.0`](https://github.com/Uniswap/uniswap-v3-core/tree/v1.0.0) -- `@uniswap/v3-periphery`: [`1.0.0`](https://github.com/Uniswap/uniswap-v3-periphery/tree/v1.0.0) - -The source code is verified with Etherscan on all networks, for all contracts except `UniswapV3Pool`. -We are working on getting the `UniswapV3Pool` contract verified with Etherscan. diff --git a/lib/v3-periphery/hardhat.config.ts b/lib/v3-periphery/hardhat.config.ts deleted file mode 100644 index 57343da..0000000 --- a/lib/v3-periphery/hardhat.config.ts +++ /dev/null @@ -1,104 +0,0 @@ -import '@nomiclabs/hardhat-ethers' -import '@nomiclabs/hardhat-etherscan' -import '@nomiclabs/hardhat-waffle' -import 'hardhat-typechain' -import 'hardhat-watcher' - -const LOW_OPTIMIZER_COMPILER_SETTINGS = { - version: '0.7.6', - settings: { - evmVersion: 'istanbul', - optimizer: { - enabled: true, - runs: 2_000, - }, - metadata: { - bytecodeHash: 'none', - }, - }, -} - -const LOWEST_OPTIMIZER_COMPILER_SETTINGS = { - version: '0.7.6', - settings: { - evmVersion: 'istanbul', - optimizer: { - enabled: true, - runs: 1_000, - }, - metadata: { - bytecodeHash: 'none', - }, - }, -} - -const DEFAULT_COMPILER_SETTINGS = { - version: '0.7.6', - settings: { - evmVersion: 'istanbul', - optimizer: { - enabled: true, - runs: 1_000_000, - }, - metadata: { - bytecodeHash: 'none', - }, - }, -} - -export default { - networks: { - hardhat: { - allowUnlimitedContractSize: false, - }, - mainnet: { - url: `https://mainnet.infura.io/v3/${process.env.INFURA_API_KEY}`, - }, - ropsten: { - url: `https://ropsten.infura.io/v3/${process.env.INFURA_API_KEY}`, - }, - rinkeby: { - url: `https://rinkeby.infura.io/v3/${process.env.INFURA_API_KEY}`, - }, - goerli: { - url: `https://goerli.infura.io/v3/${process.env.INFURA_API_KEY}`, - }, - kovan: { - url: `https://kovan.infura.io/v3/${process.env.INFURA_API_KEY}`, - }, - arbitrumRinkeby: { - url: `https://arbitrum-rinkeby.infura.io/v3/${process.env.INFURA_API_KEY}`, - }, - arbitrum: { - url: `https://arbitrum-mainnet.infura.io/v3/${process.env.INFURA_API_KEY}`, - }, - optimismKovan: { - url: `https://optimism-kovan.infura.io/v3/${process.env.INFURA_API_KEY}`, - }, - optimism: { - url: `https://optimism-mainnet.infura.io/v3/${process.env.INFURA_API_KEY}`, - }, - }, - etherscan: { - // Your API key for Etherscan - // Obtain one at https://etherscan.io/ - apiKey: process.env.ETHERSCAN_API_KEY, - }, - solidity: { - compilers: [DEFAULT_COMPILER_SETTINGS], - overrides: { - 'contracts/NonfungiblePositionManager.sol': LOW_OPTIMIZER_COMPILER_SETTINGS, - 'contracts/test/MockTimeNonfungiblePositionManager.sol': LOW_OPTIMIZER_COMPILER_SETTINGS, - 'contracts/test/NFTDescriptorTest.sol': LOWEST_OPTIMIZER_COMPILER_SETTINGS, - 'contracts/NonfungibleTokenPositionDescriptor.sol': LOWEST_OPTIMIZER_COMPILER_SETTINGS, - 'contracts/libraries/NFTDescriptor.sol': LOWEST_OPTIMIZER_COMPILER_SETTINGS, - }, - }, - watcher: { - test: { - tasks: [{ command: 'test', params: { testFiles: ['{path}'] } }], - files: ['./test/**/*'], - verbose: true, - }, - }, -} diff --git a/lib/v3-periphery/package.json b/lib/v3-periphery/package.json deleted file mode 100644 index 33ed0f9..0000000 --- a/lib/v3-periphery/package.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "name": "@uniswap/v3-periphery", - "description": "🎚 Peripheral smart contracts for interacting with Uniswap V3", - "license": "GPL-2.0-or-later", - "publishConfig": { - "access": "public" - }, - "version": "1.4.4", - "homepage": "https://uniswap.org", - "keywords": [ - "uniswap", - "periphery", - "v3" - ], - "repository": { - "type": "git", - "url": "https://github.com/Uniswap/uniswap-v3-periphery" - }, - "files": [ - "contracts/base", - "contracts/interfaces", - "contracts/libraries", - "artifacts/contracts/**/*.json", - "!artifacts/contracts/**/*.dbg.json", - "!artifacts/contracts/test/**/*", - "!artifacts/contracts/base/**/*" - ], - "engines": { - "node": ">=10" - }, - "dependencies": { - "@openzeppelin/contracts": "3.4.2-solc-0.7", - "@uniswap/lib": "^4.0.1-alpha", - "@uniswap/v2-core": "^1.0.1", - "@uniswap/v3-core": "^1.0.0", - "base64-sol": "1.0.1" - }, - "devDependencies": { - "@nomiclabs/hardhat-ethers": "^2.0.2", - "@nomiclabs/hardhat-etherscan": "^2.1.8", - "@nomiclabs/hardhat-waffle": "^2.0.1", - "@typechain/ethers-v5": "^4.0.0", - "@types/chai": "^4.2.6", - "@types/mocha": "^5.2.7", - "chai": "^4.2.0", - "decimal.js": "^10.2.1", - "ethereum-waffle": "^3.0.2", - "ethers": "^5.0.8", - "hardhat": "^2.6.8", - "hardhat-typechain": "^0.3.5", - "hardhat-watcher": "^2.1.1", - "is-svg": "^4.3.1", - "mocha": "^6.2.2", - "mocha-chai-jest-snapshot": "^1.1.0", - "prettier": "^2.0.5", - "prettier-plugin-solidity": "^1.0.0-beta.10", - "solhint": "^3.2.1", - "solhint-plugin-prettier": "^0.0.5", - "ts-generator": "^0.1.1", - "ts-node": "^8.5.4", - "typechain": "^4.0.0", - "typescript": "^3.7.3" - }, - "scripts": { - "compile": "hardhat compile", - "test": "hardhat test" - } -} diff --git a/lib/v3-periphery/test/Base64.spec.ts b/lib/v3-periphery/test/Base64.spec.ts deleted file mode 100644 index 5baef4b..0000000 --- a/lib/v3-periphery/test/Base64.spec.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { ethers } from 'hardhat' -import { base64Encode } from './shared/base64' -import { expect } from './shared/expect' -import { Base64Test } from '../typechain' -import { randomBytes } from 'crypto' -import snapshotGasCost from './shared/snapshotGasCost' - -function stringToHex(str: string): string { - return `0x${Buffer.from(str, 'utf8').toString('hex')}` -} - -describe('Base64', () => { - let base64: Base64Test - before('deploy test contract', async () => { - base64 = (await (await ethers.getContractFactory('Base64Test')).deploy()) as Base64Test - }) - - describe('#encode', () => { - it('is correct for empty bytes', async () => { - expect(await base64.encode(stringToHex(''))).to.eq('') - }) - - for (const example of [ - 'test string', - 'this is a test', - 'alphabet soup', - 'aLpHaBeT', - 'includes\nnewlines', - '', - '😀', - 'f', - 'fo', - 'foo', - 'foob', - 'fooba', - 'foobar', - 'this is a very long string that should cost a lot of gas to encode :)', - ]) { - it(`works for "${example}"`, async () => { - expect(await base64.encode(stringToHex(example))).to.eq(base64Encode(example)) - }) - - it(`gas cost of encode(${example})`, async () => { - await snapshotGasCost(base64.getGasCostOfEncode(stringToHex(example))) - }) - } - - describe('max size string (24kB)', () => { - let str: string - before(() => { - str = Array(24 * 1024) - .fill(null) - .map((_, i) => String.fromCharCode(i % 1024)) - .join('') - }) - it('correctness', async () => { - expect(await base64.encode(stringToHex(str))).to.eq(base64Encode(str)) - }) - it('gas cost', async () => { - await snapshotGasCost(base64.getGasCostOfEncode(stringToHex(str))) - }) - }) - - it('tiny fuzzing', async () => { - const inputs = [] - for (let i = 0; i < 100; i++) { - inputs.push(randomBytes(Math.random() * 100)) - } - - const promises = inputs.map((input) => { - return base64.encode(`0x${input.toString('hex')}`) - }) - - const results = await Promise.all(promises) - - for (let i = 0; i < inputs.length; i++) { - expect(inputs[i].toString('base64')).to.eq(results[i]) - } - }).timeout(300_000) - }) -}) diff --git a/lib/v3-periphery/test/CallbackValidation.spec.ts b/lib/v3-periphery/test/CallbackValidation.spec.ts deleted file mode 100644 index 98eea96..0000000 --- a/lib/v3-periphery/test/CallbackValidation.spec.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Contract, constants, Wallet } from 'ethers' -import { waffle, ethers } from 'hardhat' -import { Fixture } from 'ethereum-waffle' -import completeFixture from './shared/completeFixture' -import { expect } from './shared/expect' -import { TestERC20, TestCallbackValidation } from '../typechain' -import { FeeAmount } from './shared/constants' - -describe('CallbackValidation', () => { - let nonpairAddr: Wallet, wallets: Wallet[] - - const callbackValidationFixture: Fixture<{ - callbackValidation: TestCallbackValidation - tokens: [TestERC20, TestERC20] - factory: Contract - }> = async (wallets, provider) => { - const { factory } = await completeFixture(wallets, provider) - const tokenFactory = await ethers.getContractFactory('TestERC20') - const callbackValidationFactory = await ethers.getContractFactory('TestCallbackValidation') - const tokens: [TestERC20, TestERC20] = [ - (await tokenFactory.deploy(constants.MaxUint256.div(2))) as TestERC20, // do not use maxu256 to avoid overflowing - (await tokenFactory.deploy(constants.MaxUint256.div(2))) as TestERC20, - ] - const callbackValidation = (await callbackValidationFactory.deploy()) as TestCallbackValidation - - return { - tokens, - callbackValidation, - factory, - } - } - - let callbackValidation: TestCallbackValidation - let tokens: [TestERC20, TestERC20] - let factory: Contract - - let loadFixture: ReturnType - - before('create fixture loader', async () => { - ;[nonpairAddr, ...wallets] = await (ethers as any).getSigners() - - loadFixture = waffle.createFixtureLoader(wallets) - }) - - beforeEach('load fixture', async () => { - ;({ callbackValidation, tokens, factory } = await loadFixture(callbackValidationFixture)) - }) - - it('reverts when called from an address other than the associated UniswapV3Pool', async () => { - expect( - callbackValidation - .connect(nonpairAddr) - .verifyCallback(factory.address, tokens[0].address, tokens[1].address, FeeAmount.MEDIUM) - ).to.be.reverted - }) -}) diff --git a/lib/v3-periphery/test/LiquidityAmounts.spec.ts b/lib/v3-periphery/test/LiquidityAmounts.spec.ts deleted file mode 100644 index b24dd3c..0000000 --- a/lib/v3-periphery/test/LiquidityAmounts.spec.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { ethers } from 'hardhat' -import { LiquidityAmountsTest } from '../typechain/LiquidityAmountsTest' -import { encodePriceSqrt } from './shared/encodePriceSqrt' -import { expect } from './shared/expect' - -import snapshotGasCost from './shared/snapshotGasCost' - -describe('LiquidityAmounts', async () => { - let liquidityFromAmounts: LiquidityAmountsTest - - before('deploy test library', async () => { - const liquidityFromAmountsTestFactory = await ethers.getContractFactory('LiquidityAmountsTest') - liquidityFromAmounts = (await liquidityFromAmountsTestFactory.deploy()) as LiquidityAmountsTest - }) - - describe('#getLiquidityForAmount0', () => { - it('gas', async () => { - const sqrtPriceAX96 = encodePriceSqrt(100, 110) - const sqrtPriceBX96 = encodePriceSqrt(110, 100) - await snapshotGasCost(liquidityFromAmounts.getGasCostOfGetLiquidityForAmount0(sqrtPriceAX96, sqrtPriceBX96, 100)) - }) - }) - - describe('#getLiquidityForAmount1', () => { - it('gas', async () => { - const sqrtPriceAX96 = encodePriceSqrt(100, 110) - const sqrtPriceBX96 = encodePriceSqrt(110, 100) - await snapshotGasCost(liquidityFromAmounts.getGasCostOfGetLiquidityForAmount1(sqrtPriceAX96, sqrtPriceBX96, 100)) - }) - }) - - describe('#getLiquidityForAmounts', () => { - it('amounts for price inside', async () => { - const sqrtPriceX96 = encodePriceSqrt(1, 1) - const sqrtPriceAX96 = encodePriceSqrt(100, 110) - const sqrtPriceBX96 = encodePriceSqrt(110, 100) - const liquidity = await liquidityFromAmounts.getLiquidityForAmounts( - sqrtPriceX96, - sqrtPriceAX96, - sqrtPriceBX96, - 100, - 200 - ) - expect(liquidity).to.eq(2148) - }) - - it('amounts for price below', async () => { - const sqrtPriceX96 = encodePriceSqrt(99, 110) - const sqrtPriceAX96 = encodePriceSqrt(100, 110) - const sqrtPriceBX96 = encodePriceSqrt(110, 100) - const liquidity = await liquidityFromAmounts.getLiquidityForAmounts( - sqrtPriceX96, - sqrtPriceAX96, - sqrtPriceBX96, - 100, - 200 - ) - expect(liquidity).to.eq(1048) - }) - - it('amounts for price above', async () => { - const sqrtPriceX96 = encodePriceSqrt(111, 100) - const sqrtPriceAX96 = encodePriceSqrt(100, 110) - const sqrtPriceBX96 = encodePriceSqrt(110, 100) - const liquidity = await liquidityFromAmounts.getLiquidityForAmounts( - sqrtPriceX96, - sqrtPriceAX96, - sqrtPriceBX96, - 100, - 200 - ) - expect(liquidity).to.eq(2097) - }) - - it('amounts for price equal to lower boundary', async () => { - const sqrtPriceAX96 = encodePriceSqrt(100, 110) - const sqrtPriceX96 = sqrtPriceAX96 - const sqrtPriceBX96 = encodePriceSqrt(110, 100) - const liquidity = await liquidityFromAmounts.getLiquidityForAmounts( - sqrtPriceX96, - sqrtPriceAX96, - sqrtPriceBX96, - 100, - 200 - ) - expect(liquidity).to.eq(1048) - }) - - it('amounts for price equal to upper boundary', async () => { - const sqrtPriceAX96 = encodePriceSqrt(100, 110) - const sqrtPriceBX96 = encodePriceSqrt(110, 100) - const sqrtPriceX96 = sqrtPriceBX96 - const liquidity = await liquidityFromAmounts.getLiquidityForAmounts( - sqrtPriceX96, - sqrtPriceAX96, - sqrtPriceBX96, - 100, - 200 - ) - expect(liquidity).to.eq(2097) - }) - - it('gas for price below', async () => { - const sqrtPriceX96 = encodePriceSqrt(99, 110) - const sqrtPriceAX96 = encodePriceSqrt(100, 110) - const sqrtPriceBX96 = encodePriceSqrt(110, 100) - await snapshotGasCost( - liquidityFromAmounts.getGasCostOfGetLiquidityForAmounts(sqrtPriceX96, sqrtPriceAX96, sqrtPriceBX96, 100, 200) - ) - }) - it('gas for price above', async () => { - const sqrtPriceX96 = encodePriceSqrt(111, 100) - const sqrtPriceAX96 = encodePriceSqrt(100, 110) - const sqrtPriceBX96 = encodePriceSqrt(110, 100) - await snapshotGasCost( - liquidityFromAmounts.getGasCostOfGetLiquidityForAmounts(sqrtPriceX96, sqrtPriceAX96, sqrtPriceBX96, 100, 200) - ) - }) - it('gas for price inside', async () => { - const sqrtPriceX96 = encodePriceSqrt(1, 1) - const sqrtPriceAX96 = encodePriceSqrt(100, 110) - const sqrtPriceBX96 = encodePriceSqrt(110, 100) - await snapshotGasCost( - liquidityFromAmounts.getGasCostOfGetLiquidityForAmounts(sqrtPriceX96, sqrtPriceAX96, sqrtPriceBX96, 100, 200) - ) - }) - }) - - describe('#getAmount0ForLiquidity', () => { - it('gas', async () => { - const sqrtPriceAX96 = encodePriceSqrt(100, 110) - const sqrtPriceBX96 = encodePriceSqrt(110, 100) - await snapshotGasCost(liquidityFromAmounts.getGasCostOfGetAmount0ForLiquidity(sqrtPriceAX96, sqrtPriceBX96, 100)) - }) - }) - - describe('#getLiquidityForAmount1', () => { - it('gas', async () => { - const sqrtPriceAX96 = encodePriceSqrt(100, 110) - const sqrtPriceBX96 = encodePriceSqrt(110, 100) - await snapshotGasCost(liquidityFromAmounts.getGasCostOfGetAmount1ForLiquidity(sqrtPriceAX96, sqrtPriceBX96, 100)) - }) - }) - - describe('#getAmountsForLiquidity', () => { - it('amounts for price inside', async () => { - const sqrtPriceX96 = encodePriceSqrt(1, 1) - const sqrtPriceAX96 = encodePriceSqrt(100, 110) - const sqrtPriceBX96 = encodePriceSqrt(110, 100) - const { amount0, amount1 } = await liquidityFromAmounts.getAmountsForLiquidity( - sqrtPriceX96, - sqrtPriceAX96, - sqrtPriceBX96, - 2148 - ) - expect(amount0).to.eq(99) - expect(amount1).to.eq(99) - }) - - it('amounts for price below', async () => { - const sqrtPriceX96 = encodePriceSqrt(99, 110) - const sqrtPriceAX96 = encodePriceSqrt(100, 110) - const sqrtPriceBX96 = encodePriceSqrt(110, 100) - const { amount0, amount1 } = await liquidityFromAmounts.getAmountsForLiquidity( - sqrtPriceX96, - sqrtPriceAX96, - sqrtPriceBX96, - 1048 - ) - expect(amount0).to.eq(99) - expect(amount1).to.eq(0) - }) - - it('amounts for price above', async () => { - const sqrtPriceX96 = encodePriceSqrt(111, 100) - const sqrtPriceAX96 = encodePriceSqrt(100, 110) - const sqrtPriceBX96 = encodePriceSqrt(110, 100) - const { amount0, amount1 } = await liquidityFromAmounts.getAmountsForLiquidity( - sqrtPriceX96, - sqrtPriceAX96, - sqrtPriceBX96, - 2097 - ) - expect(amount0).to.eq(0) - expect(amount1).to.eq(199) - }) - - it('amounts for price on lower boundary', async () => { - const sqrtPriceAX96 = encodePriceSqrt(100, 110) - const sqrtPriceX96 = sqrtPriceAX96 - const sqrtPriceBX96 = encodePriceSqrt(110, 100) - const { amount0, amount1 } = await liquidityFromAmounts.getAmountsForLiquidity( - sqrtPriceX96, - sqrtPriceAX96, - sqrtPriceBX96, - 1048 - ) - expect(amount0).to.eq(99) - expect(amount1).to.eq(0) - }) - - it('amounts for price on upper boundary', async () => { - const sqrtPriceAX96 = encodePriceSqrt(100, 110) - const sqrtPriceBX96 = encodePriceSqrt(110, 100) - const sqrtPriceX96 = sqrtPriceBX96 - const { amount0, amount1 } = await liquidityFromAmounts.getAmountsForLiquidity( - sqrtPriceX96, - sqrtPriceAX96, - sqrtPriceBX96, - 2097 - ) - expect(amount0).to.eq(0) - expect(amount1).to.eq(199) - }) - - it('gas for price below', async () => { - const sqrtPriceX96 = encodePriceSqrt(99, 110) - const sqrtPriceAX96 = encodePriceSqrt(100, 110) - const sqrtPriceBX96 = encodePriceSqrt(110, 100) - await snapshotGasCost( - liquidityFromAmounts.getGasCostOfGetAmountsForLiquidity(sqrtPriceX96, sqrtPriceAX96, sqrtPriceBX96, 2148) - ) - }) - it('gas for price above', async () => { - const sqrtPriceX96 = encodePriceSqrt(111, 100) - const sqrtPriceAX96 = encodePriceSqrt(100, 110) - const sqrtPriceBX96 = encodePriceSqrt(110, 100) - await snapshotGasCost( - liquidityFromAmounts.getGasCostOfGetAmountsForLiquidity(sqrtPriceX96, sqrtPriceAX96, sqrtPriceBX96, 1048) - ) - }) - it('gas for price inside', async () => { - const sqrtPriceX96 = encodePriceSqrt(1, 1) - const sqrtPriceAX96 = encodePriceSqrt(100, 110) - const sqrtPriceBX96 = encodePriceSqrt(110, 100) - await snapshotGasCost( - liquidityFromAmounts.getGasCostOfGetAmountsForLiquidity(sqrtPriceX96, sqrtPriceAX96, sqrtPriceBX96, 2097) - ) - }) - }) -}) diff --git a/lib/v3-periphery/test/Multicall.spec.ts b/lib/v3-periphery/test/Multicall.spec.ts deleted file mode 100644 index 44ca334..0000000 --- a/lib/v3-periphery/test/Multicall.spec.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Wallet } from 'ethers' -import { ethers, waffle } from 'hardhat' -import { TestMulticall } from '../typechain/TestMulticall' -import { expect } from './shared/expect' - -import snapshotGasCost from './shared/snapshotGasCost' - -describe('Multicall', async () => { - let wallets: Wallet[] - - let multicall: TestMulticall - - before('get wallets', async () => { - wallets = await (ethers as any).getSigners() - }) - - beforeEach('create multicall', async () => { - const multicallTestFactory = await ethers.getContractFactory('TestMulticall') - multicall = (await multicallTestFactory.deploy()) as TestMulticall - }) - - it('revert messages are returned', async () => { - await expect( - multicall.multicall([multicall.interface.encodeFunctionData('functionThatRevertsWithError', ['abcdef'])]) - ).to.be.revertedWith('abcdef') - }) - - it('return data is properly encoded', async () => { - const [data] = await multicall.callStatic.multicall([ - multicall.interface.encodeFunctionData('functionThatReturnsTuple', ['1', '2']), - ]) - const { - tuple: { a, b }, - } = multicall.interface.decodeFunctionResult('functionThatReturnsTuple', data) - expect(b).to.eq(1) - expect(a).to.eq(2) - }) - - describe('context is preserved', () => { - it('msg.value', async () => { - await multicall.multicall([multicall.interface.encodeFunctionData('pays')], { value: 3 }) - expect(await multicall.paid()).to.eq(3) - }) - - it('msg.value used twice', async () => { - await multicall.multicall( - [multicall.interface.encodeFunctionData('pays'), multicall.interface.encodeFunctionData('pays')], - { value: 3 } - ) - expect(await multicall.paid()).to.eq(6) - }) - - it('msg.sender', async () => { - expect(await multicall.returnSender()).to.eq(wallets[0].address) - }) - }) - - it('gas cost of pay w/o multicall', async () => { - await snapshotGasCost(multicall.pays({ value: 3 })) - }) - - it('gas cost of pay w/ multicall', async () => { - await snapshotGasCost(multicall.multicall([multicall.interface.encodeFunctionData('pays')], { value: 3 })) - }) -}) diff --git a/lib/v3-periphery/test/NFTDescriptor.spec.ts b/lib/v3-periphery/test/NFTDescriptor.spec.ts deleted file mode 100644 index fce07b1..0000000 --- a/lib/v3-periphery/test/NFTDescriptor.spec.ts +++ /dev/null @@ -1,907 +0,0 @@ -import { BigNumber, constants, Wallet } from 'ethers' -import { encodePriceSqrt } from './shared/encodePriceSqrt' -import { waffle, ethers } from 'hardhat' -import { expect } from './shared/expect' -import { TestERC20Metadata, NFTDescriptorTest } from '../typechain' -import { Fixture } from 'ethereum-waffle' -import { FeeAmount, TICK_SPACINGS } from './shared/constants' -import snapshotGasCost from './shared/snapshotGasCost' -import { formatSqrtRatioX96 } from './shared/formatSqrtRatioX96' -import { getMaxTick, getMinTick } from './shared/ticks' -import { randomBytes } from 'crypto' -import { extractJSONFromURI } from './shared/extractJSONFromURI' -import fs from 'fs' -import isSvg from 'is-svg' - -const TEN = BigNumber.from(10) -const LOWEST_SQRT_RATIO = 4310618292 -const HIGHEST_SQRT_RATIO = BigNumber.from(33849).mul(TEN.pow(34)) - -describe('NFTDescriptor', () => { - let wallets: Wallet[] - - const nftDescriptorFixture: Fixture<{ - tokens: [TestERC20Metadata, TestERC20Metadata, TestERC20Metadata, TestERC20Metadata] - nftDescriptor: NFTDescriptorTest - }> = async (wallets, provider) => { - const nftDescriptorLibraryFactory = await ethers.getContractFactory('NFTDescriptor') - const nftDescriptorLibrary = await nftDescriptorLibraryFactory.deploy() - - const tokenFactory = await ethers.getContractFactory('TestERC20Metadata') - const NFTDescriptorFactory = await ethers.getContractFactory('NFTDescriptorTest', { - libraries: { - NFTDescriptor: nftDescriptorLibrary.address, - }, - }) - const nftDescriptor = (await NFTDescriptorFactory.deploy()) as NFTDescriptorTest - const TestERC20Metadata = tokenFactory.deploy(constants.MaxUint256.div(2), 'Test ERC20', 'TEST1') - const tokens: [TestERC20Metadata, TestERC20Metadata, TestERC20Metadata, TestERC20Metadata] = [ - (await tokenFactory.deploy(constants.MaxUint256.div(2), 'Test ERC20', 'TEST1')) as TestERC20Metadata, // do not use maxu256 to avoid overflowing - (await tokenFactory.deploy(constants.MaxUint256.div(2), 'Test ERC20', 'TEST2')) as TestERC20Metadata, - (await tokenFactory.deploy(constants.MaxUint256.div(2), 'Test ERC20', 'TEST3')) as TestERC20Metadata, - (await tokenFactory.deploy(constants.MaxUint256.div(2), 'Test ERC20', 'TEST4')) as TestERC20Metadata, - ] - tokens.sort((a, b) => (a.address.toLowerCase() < b.address.toLowerCase() ? -1 : 1)) - return { - nftDescriptor, - tokens, - } - } - - let nftDescriptor: NFTDescriptorTest - let tokens: [TestERC20Metadata, TestERC20Metadata, TestERC20Metadata, TestERC20Metadata] - - let loadFixture: ReturnType - - before('create fixture loader', async () => { - wallets = await (ethers as any).getSigners() - - loadFixture = waffle.createFixtureLoader(wallets) - }) - - beforeEach('load fixture', async () => { - ;({ nftDescriptor, tokens } = await loadFixture(nftDescriptorFixture)) - }) - - describe('#constructTokenURI', () => { - let tokenId: number - let baseTokenAddress: string - let quoteTokenAddress: string - let baseTokenSymbol: string - let quoteTokenSymbol: string - let baseTokenDecimals: number - let quoteTokenDecimals: number - let flipRatio: boolean - let tickLower: number - let tickUpper: number - let tickCurrent: number - let tickSpacing: number - let fee: number - let poolAddress: string - - beforeEach(async () => { - tokenId = 123 - baseTokenAddress = tokens[0].address - quoteTokenAddress = tokens[1].address - baseTokenSymbol = await tokens[0].symbol() - quoteTokenSymbol = await tokens[1].symbol() - baseTokenDecimals = await tokens[0].decimals() - quoteTokenDecimals = await tokens[1].decimals() - flipRatio = false - tickLower = getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]) - tickUpper = getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]) - tickCurrent = 0 - tickSpacing = TICK_SPACINGS[FeeAmount.MEDIUM] - fee = 3000 - poolAddress = `0x${'b'.repeat(40)}` - }) - - it('returns the valid JSON string with min and max ticks', async () => { - const json = extractJSONFromURI( - await nftDescriptor.constructTokenURI({ - tokenId, - baseTokenAddress, - quoteTokenAddress, - baseTokenSymbol, - quoteTokenSymbol, - baseTokenDecimals, - quoteTokenDecimals, - flipRatio, - tickLower, - tickUpper, - tickCurrent, - tickSpacing, - fee, - poolAddress, - }) - ) - - const tokenUri = constructTokenMetadata( - tokenId, - quoteTokenAddress, - baseTokenAddress, - poolAddress, - quoteTokenSymbol, - baseTokenSymbol, - flipRatio, - tickLower, - tickUpper, - tickCurrent, - '0.3%', - 'MIN<>MAX' - ) - - expect(json.description).to.equal(tokenUri.description) - expect(json.name).to.equal(tokenUri.name) - }) - - it('returns the valid JSON string with mid ticks', async () => { - tickLower = -10 - tickUpper = 10 - tickSpacing = TICK_SPACINGS[FeeAmount.MEDIUM] - fee = 3000 - - const json = extractJSONFromURI( - await nftDescriptor.constructTokenURI({ - tokenId, - baseTokenAddress, - quoteTokenAddress, - baseTokenSymbol, - quoteTokenSymbol, - baseTokenDecimals, - quoteTokenDecimals, - flipRatio, - tickLower, - tickUpper, - tickCurrent, - tickSpacing, - fee, - poolAddress, - }) - ) - - const tokenMetadata = constructTokenMetadata( - tokenId, - quoteTokenAddress, - baseTokenAddress, - poolAddress, - quoteTokenSymbol, - baseTokenSymbol, - flipRatio, - tickLower, - tickUpper, - tickCurrent, - '0.3%', - '0.99900<>1.0010' - ) - - expect(json.description).to.equal(tokenMetadata.description) - expect(json.name).to.equal(tokenMetadata.name) - }) - - it('returns valid JSON when token symbols contain quotes', async () => { - quoteTokenSymbol = '"TES"T1"' - const json = extractJSONFromURI( - await nftDescriptor.constructTokenURI({ - tokenId, - baseTokenAddress, - quoteTokenAddress, - baseTokenSymbol, - quoteTokenSymbol, - baseTokenDecimals, - quoteTokenDecimals, - flipRatio, - tickLower, - tickUpper, - tickCurrent, - tickSpacing, - fee, - poolAddress, - }) - ) - - const tokenMetadata = constructTokenMetadata( - tokenId, - quoteTokenAddress, - baseTokenAddress, - poolAddress, - quoteTokenSymbol, - baseTokenSymbol, - flipRatio, - tickLower, - tickUpper, - tickCurrent, - '0.3%', - 'MIN<>MAX' - ) - - expect(json.description).to.equal(tokenMetadata.description) - expect(json.name).to.equal(tokenMetadata.name) - }) - - describe('when the token ratio is flipped', () => { - it('returns the valid JSON for mid ticks', async () => { - flipRatio = true - tickLower = -10 - tickUpper = 10 - - const json = extractJSONFromURI( - await nftDescriptor.constructTokenURI({ - tokenId, - baseTokenAddress, - quoteTokenAddress, - baseTokenSymbol, - quoteTokenSymbol, - baseTokenDecimals, - quoteTokenDecimals, - flipRatio, - tickLower, - tickUpper, - tickCurrent, - tickSpacing, - fee, - poolAddress, - }) - ) - - const tokenMetadata = constructTokenMetadata( - tokenId, - quoteTokenAddress, - baseTokenAddress, - poolAddress, - quoteTokenSymbol, - baseTokenSymbol, - flipRatio, - tickLower, - tickUpper, - tickCurrent, - '0.3%', - '0.99900<>1.0010' - ) - - expect(json.description).to.equal(tokenMetadata.description) - expect(json.name).to.equal(tokenMetadata.name) - }) - - it('returns the valid JSON for min/max ticks', async () => { - flipRatio = true - - const json = extractJSONFromURI( - await nftDescriptor.constructTokenURI({ - tokenId, - baseTokenAddress, - quoteTokenAddress, - baseTokenSymbol, - quoteTokenSymbol, - baseTokenDecimals, - quoteTokenDecimals, - flipRatio, - tickLower, - tickUpper, - tickCurrent, - tickSpacing, - fee, - poolAddress, - }) - ) - - const tokenMetadata = constructTokenMetadata( - tokenId, - quoteTokenAddress, - baseTokenAddress, - poolAddress, - quoteTokenSymbol, - baseTokenSymbol, - flipRatio, - tickLower, - tickUpper, - tickCurrent, - '0.3%', - 'MIN<>MAX' - ) - - expect(json.description).to.equal(tokenMetadata.description) - expect(json.name).to.equal(tokenMetadata.name) - }) - }) - - it('gas', async () => { - await snapshotGasCost( - nftDescriptor.getGasCostOfConstructTokenURI({ - tokenId, - baseTokenAddress, - quoteTokenAddress, - baseTokenSymbol, - quoteTokenSymbol, - baseTokenDecimals, - quoteTokenDecimals, - flipRatio, - tickLower, - tickUpper, - tickCurrent, - tickSpacing, - fee, - poolAddress, - }) - ) - }) - - it('snapshot matches', async () => { - // get snapshot with super rare special sparkle - tokenId = 1 - poolAddress = `0x${'b'.repeat(40)}` - // get a snapshot with svg fade - tickCurrent = -1 - tickLower = 0 - tickUpper = 1000 - tickSpacing = TICK_SPACINGS[FeeAmount.LOW] - fee = FeeAmount.LOW - quoteTokenAddress = '0xabcdeabcdefabcdefabcdefabcdefabcdefabcdf' - baseTokenAddress = '0x1234567890123456789123456789012345678901' - quoteTokenSymbol = 'UNI' - baseTokenSymbol = 'WETH' - expect( - await nftDescriptor.constructTokenURI({ - tokenId, - quoteTokenAddress, - baseTokenAddress, - quoteTokenSymbol, - baseTokenSymbol, - baseTokenDecimals, - quoteTokenDecimals, - flipRatio, - tickLower, - tickUpper, - tickCurrent, - tickSpacing, - fee, - poolAddress, - }) - ).toMatchSnapshot() - }) - }) - - describe('#addressToString', () => { - it('returns the correct string for a given address', async () => { - let addressStr = await nftDescriptor.addressToString(`0x${'1234abcdef'.repeat(4)}`) - expect(addressStr).to.eq('0x1234abcdef1234abcdef1234abcdef1234abcdef') - addressStr = await nftDescriptor.addressToString(`0x${'1'.repeat(40)}`) - expect(addressStr).to.eq(`0x${'1'.repeat(40)}`) - }) - }) - - describe('#tickToDecimalString', () => { - let tickSpacing: number - let minTick: number - let maxTick: number - - describe('when tickspacing is 10', () => { - before(() => { - tickSpacing = TICK_SPACINGS[FeeAmount.LOW] - minTick = getMinTick(tickSpacing) - maxTick = getMaxTick(tickSpacing) - }) - - it('returns MIN on lowest tick', async () => { - expect(await nftDescriptor.tickToDecimalString(minTick, tickSpacing, 18, 18, false)).to.equal('MIN') - }) - - it('returns MAX on the highest tick', async () => { - expect(await nftDescriptor.tickToDecimalString(maxTick, tickSpacing, 18, 18, false)).to.equal('MAX') - }) - - it('returns the correct decimal string when the tick is in range', async () => { - expect(await nftDescriptor.tickToDecimalString(1, tickSpacing, 18, 18, false)).to.equal('1.0001') - }) - - it('returns the correct decimal string when tick is mintick for different tickspace', async () => { - const otherMinTick = getMinTick(TICK_SPACINGS[FeeAmount.HIGH]) - expect(await nftDescriptor.tickToDecimalString(otherMinTick, tickSpacing, 18, 18, false)).to.equal( - '0.0000000000000000000000000000000000000029387' - ) - }) - }) - - describe('when tickspacing is 60', () => { - before(() => { - tickSpacing = TICK_SPACINGS[FeeAmount.MEDIUM] - minTick = getMinTick(tickSpacing) - maxTick = getMaxTick(tickSpacing) - }) - - it('returns MIN on lowest tick', async () => { - expect(await nftDescriptor.tickToDecimalString(minTick, tickSpacing, 18, 18, false)).to.equal('MIN') - }) - - it('returns MAX on the highest tick', async () => { - expect(await nftDescriptor.tickToDecimalString(maxTick, tickSpacing, 18, 18, false)).to.equal('MAX') - }) - - it('returns the correct decimal string when the tick is in range', async () => { - expect(await nftDescriptor.tickToDecimalString(-1, tickSpacing, 18, 18, false)).to.equal('0.99990') - }) - - it('returns the correct decimal string when tick is mintick for different tickspace', async () => { - const otherMinTick = getMinTick(TICK_SPACINGS[FeeAmount.HIGH]) - expect(await nftDescriptor.tickToDecimalString(otherMinTick, tickSpacing, 18, 18, false)).to.equal( - '0.0000000000000000000000000000000000000029387' - ) - }) - }) - - describe('when tickspacing is 200', () => { - before(() => { - tickSpacing = TICK_SPACINGS[FeeAmount.HIGH] - minTick = getMinTick(tickSpacing) - maxTick = getMaxTick(tickSpacing) - }) - - it('returns MIN on lowest tick', async () => { - expect(await nftDescriptor.tickToDecimalString(minTick, tickSpacing, 18, 18, false)).to.equal('MIN') - }) - - it('returns MAX on the highest tick', async () => { - expect(await nftDescriptor.tickToDecimalString(maxTick, tickSpacing, 18, 18, false)).to.equal('MAX') - }) - - it('returns the correct decimal string when the tick is in range', async () => { - expect(await nftDescriptor.tickToDecimalString(0, tickSpacing, 18, 18, false)).to.equal('1.0000') - }) - - it('returns the correct decimal string when tick is mintick for different tickspace', async () => { - const otherMinTick = getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]) - expect(await nftDescriptor.tickToDecimalString(otherMinTick, tickSpacing, 18, 18, false)).to.equal( - '0.0000000000000000000000000000000000000029387' - ) - }) - }) - - describe('when token ratio is flipped', () => { - it('returns the inverse of default ratio for medium sized numbers', async () => { - const tickSpacing = TICK_SPACINGS[FeeAmount.HIGH] - expect(await nftDescriptor.tickToDecimalString(10, tickSpacing, 18, 18, false)).to.eq('1.0010') - expect(await nftDescriptor.tickToDecimalString(10, tickSpacing, 18, 18, true)).to.eq('0.99900') - }) - - it('returns the inverse of default ratio for large numbers', async () => { - const tickSpacing = TICK_SPACINGS[FeeAmount.HIGH] - expect(await nftDescriptor.tickToDecimalString(487272, tickSpacing, 18, 18, false)).to.eq( - '1448400000000000000000' - ) - expect(await nftDescriptor.tickToDecimalString(487272, tickSpacing, 18, 18, true)).to.eq( - '0.00000000000000000000069041' - ) - }) - - it('returns the inverse of default ratio for small numbers', async () => { - const tickSpacing = TICK_SPACINGS[FeeAmount.HIGH] - expect(await nftDescriptor.tickToDecimalString(-387272, tickSpacing, 18, 18, false)).to.eq( - '0.000000000000000015200' - ) - expect(await nftDescriptor.tickToDecimalString(-387272, tickSpacing, 18, 18, true)).to.eq('65791000000000000') - }) - - it('returns the correct string with differing token decimals', async () => { - const tickSpacing = TICK_SPACINGS[FeeAmount.HIGH] - expect(await nftDescriptor.tickToDecimalString(1000, tickSpacing, 18, 18, true)).to.eq('0.90484') - expect(await nftDescriptor.tickToDecimalString(1000, tickSpacing, 18, 10, true)).to.eq('90484000') - expect(await nftDescriptor.tickToDecimalString(1000, tickSpacing, 10, 18, true)).to.eq('0.0000000090484') - }) - - it('returns MIN for highest tick', async () => { - const tickSpacing = TICK_SPACINGS[FeeAmount.HIGH] - const lowestTick = getMinTick(TICK_SPACINGS[FeeAmount.HIGH]) - expect(await nftDescriptor.tickToDecimalString(lowestTick, tickSpacing, 18, 18, true)).to.eq('MAX') - }) - - it('returns MAX for lowest tick', async () => { - const tickSpacing = TICK_SPACINGS[FeeAmount.HIGH] - const highestTick = getMaxTick(TICK_SPACINGS[FeeAmount.HIGH]) - expect(await nftDescriptor.tickToDecimalString(highestTick, tickSpacing, 18, 18, true)).to.eq('MIN') - }) - }) - }) - - describe('#fixedPointToDecimalString', () => { - describe('returns the correct string for', () => { - it('the highest possible price', async () => { - const ratio = encodePriceSqrt(33849, 1 / 10 ** 34) - expect(await nftDescriptor.fixedPointToDecimalString(ratio, 18, 18)).to.eq( - '338490000000000000000000000000000000000' - ) - }) - - it('large numbers', async () => { - let ratio = encodePriceSqrt(25811, 1 / 10 ** 11) - expect(await nftDescriptor.fixedPointToDecimalString(ratio, 18, 18)).to.eq('2581100000000000') - ratio = encodePriceSqrt(17662, 1 / 10 ** 5) - expect(await nftDescriptor.fixedPointToDecimalString(ratio, 18, 18)).to.eq('1766200000') - }) - - it('exactly 5 sigfig whole number', async () => { - const ratio = encodePriceSqrt(42026, 1) - expect(await nftDescriptor.fixedPointToDecimalString(ratio, 18, 18)).to.eq('42026') - }) - - it('when the decimal is at index 4', async () => { - const ratio = encodePriceSqrt(12087, 10) - expect(await nftDescriptor.fixedPointToDecimalString(ratio, 18, 18)).to.eq('1208.7') - }) - - it('when the decimal is at index 3', async () => { - const ratio = encodePriceSqrt(12087, 100) - expect(await nftDescriptor.fixedPointToDecimalString(ratio, 18, 18)).to.eq('120.87') - }) - - it('when the decimal is at index 2', async () => { - const ratio = encodePriceSqrt(12087, 1000) - expect(await nftDescriptor.fixedPointToDecimalString(ratio, 18, 18)).to.eq('12.087') - }) - - it('when the decimal is at index 1', async () => { - const ratio = encodePriceSqrt(12345, 10000) - const bla = await nftDescriptor.fixedPointToDecimalString(ratio, 18, 18) - expect(await nftDescriptor.fixedPointToDecimalString(ratio, 18, 18)).to.eq('1.2345') - }) - - it('when sigfigs have trailing 0s after the decimal', async () => { - const ratio = encodePriceSqrt(1, 1) - expect(await nftDescriptor.fixedPointToDecimalString(ratio, 18, 18)).to.eq('1.0000') - }) - - it('when there are exactly 5 numbers after the decimal', async () => { - const ratio = encodePriceSqrt(12345, 100000) - expect(await nftDescriptor.fixedPointToDecimalString(ratio, 18, 18)).to.eq('0.12345') - }) - - it('very small numbers', async () => { - let ratio = encodePriceSqrt(38741, 10 ** 20) - expect(await nftDescriptor.fixedPointToDecimalString(ratio, 18, 18)).to.eq('0.00000000000000038741') - ratio = encodePriceSqrt(88498, 10 ** 35) - expect(await nftDescriptor.fixedPointToDecimalString(ratio, 18, 18)).to.eq( - '0.00000000000000000000000000000088498' - ) - }) - - it('smallest number', async () => { - const ratio = encodePriceSqrt(39000, 10 ** 43) - expect(await nftDescriptor.fixedPointToDecimalString(ratio, 18, 18)).to.eq( - '0.0000000000000000000000000000000000000029387' - ) - }) - }) - - describe('when tokens have different decimal precision', () => { - describe('when baseToken has more precision decimals than quoteToken', () => { - it('returns the correct string when the decimal difference is even', async () => { - expect(await nftDescriptor.fixedPointToDecimalString(encodePriceSqrt(1, 1), 18, 16)).to.eq('100.00') - }) - - it('returns the correct string when the decimal difference is odd', async () => { - const tenRatio = encodePriceSqrt(10, 1) - expect(await nftDescriptor.fixedPointToDecimalString(tenRatio, 18, 17)).to.eq('100.00') - }) - - it('does not account for higher token0 precision if difference is more than 18', async () => { - expect(await nftDescriptor.fixedPointToDecimalString(encodePriceSqrt(1, 1), 24, 5)).to.eq('1.0000') - }) - }) - - describe('when quoteToken has more precision decimals than baseToken', () => { - it('returns the correct string when the decimal difference is even', async () => { - expect(await nftDescriptor.fixedPointToDecimalString(encodePriceSqrt(1, 1), 10, 18)).to.eq('0.000000010000') - }) - - it('returns the correct string when the decimal difference is odd', async () => { - expect(await nftDescriptor.fixedPointToDecimalString(encodePriceSqrt(1, 1), 7, 18)).to.eq('0.000000000010000') - }) - - // TODO: provide compatibility token prices that breach minimum price due to token decimal differences - it.skip('returns the correct string when the decimal difference brings ratio below the minimum', async () => { - const lowRatio = encodePriceSqrt(88498, 10 ** 35) - expect(await nftDescriptor.fixedPointToDecimalString(lowRatio, 10, 20)).to.eq( - '0.000000000000000000000000000000000000000088498' - ) - }) - - it('does not account for higher token1 precision if difference is more than 18', async () => { - expect(await nftDescriptor.fixedPointToDecimalString(encodePriceSqrt(1, 1), 24, 5)).to.eq('1.0000') - }) - }) - - it('some fuzz', async () => { - const random = (min: number, max: number): number => { - return Math.floor(min + ((Math.random() * 100) % (max + 1 - min))) - } - - const inputs: [BigNumber, number, number][] = [] - let i = 0 - while (i <= 20) { - const ratio = BigNumber.from(`0x${randomBytes(random(7, 20)).toString('hex')}`) - const decimals0 = random(3, 21) - const decimals1 = random(3, 21) - const decimalDiff = Math.abs(decimals0 - decimals1) - - // TODO: Address edgecase out of bounds prices due to decimal differences - if ( - ratio.div(TEN.pow(decimalDiff)).gt(LOWEST_SQRT_RATIO) && - ratio.mul(TEN.pow(decimalDiff)).lt(HIGHEST_SQRT_RATIO) - ) { - inputs.push([ratio, decimals0, decimals1]) - i++ - } - } - - for (let i in inputs) { - let ratio: BigNumber | number - let decimals0: number - let decimals1: number - ;[ratio, decimals0, decimals1] = inputs[i] - let result = await nftDescriptor.fixedPointToDecimalString(ratio, decimals0, decimals1) - expect(formatSqrtRatioX96(ratio, decimals0, decimals1)).to.eq(result) - } - }).timeout(300_000) - }) - }) - - describe('#feeToPercentString', () => { - it('returns the correct fee for 0', async () => { - expect(await nftDescriptor.feeToPercentString(0)).to.eq('0%') - }) - - it('returns the correct fee for 1', async () => { - expect(await nftDescriptor.feeToPercentString(1)).to.eq('0.0001%') - }) - - it('returns the correct fee for 30', async () => { - expect(await nftDescriptor.feeToPercentString(30)).to.eq('0.003%') - }) - - it('returns the correct fee for 33', async () => { - expect(await nftDescriptor.feeToPercentString(33)).to.eq('0.0033%') - }) - - it('returns the correct fee for 500', async () => { - expect(await nftDescriptor.feeToPercentString(500)).to.eq('0.05%') - }) - - it('returns the correct fee for 2500', async () => { - expect(await nftDescriptor.feeToPercentString(2500)).to.eq('0.25%') - }) - - it('returns the correct fee for 3000', async () => { - expect(await nftDescriptor.feeToPercentString(3000)).to.eq('0.3%') - }) - - it('returns the correct fee for 10000', async () => { - expect(await nftDescriptor.feeToPercentString(10000)).to.eq('1%') - }) - - it('returns the correct fee for 17000', async () => { - expect(await nftDescriptor.feeToPercentString(17000)).to.eq('1.7%') - }) - - it('returns the correct fee for 100000', async () => { - expect(await nftDescriptor.feeToPercentString(100000)).to.eq('10%') - }) - - it('returns the correct fee for 150000', async () => { - expect(await nftDescriptor.feeToPercentString(150000)).to.eq('15%') - }) - - it('returns the correct fee for 102000', async () => { - expect(await nftDescriptor.feeToPercentString(102000)).to.eq('10.2%') - }) - - it('returns the correct fee for 10000000', async () => { - expect(await nftDescriptor.feeToPercentString(1000000)).to.eq('100%') - }) - - it('returns the correct fee for 1005000', async () => { - expect(await nftDescriptor.feeToPercentString(1005000)).to.eq('100.5%') - }) - - it('returns the correct fee for 10000000', async () => { - expect(await nftDescriptor.feeToPercentString(10000000)).to.eq('1000%') - }) - - it('returns the correct fee for 12300000', async () => { - expect(await nftDescriptor.feeToPercentString(12300000)).to.eq('1230%') - }) - }) - - describe('#tokenToColorHex', () => { - function tokenToColorHex(tokenAddress: string, startIndex: number): string { - return `${tokenAddress.slice(startIndex, startIndex + 6).toLowerCase()}` - } - - it('returns the correct hash for the first 3 bytes of the token address', async () => { - expect(await nftDescriptor.tokenToColorHex(tokens[0].address, 136)).to.eq(tokenToColorHex(tokens[0].address, 2)) - expect(await nftDescriptor.tokenToColorHex(tokens[1].address, 136)).to.eq(tokenToColorHex(tokens[1].address, 2)) - }) - - it('returns the correct hash for the last 3 bytes of the address', async () => { - expect(await nftDescriptor.tokenToColorHex(tokens[0].address, 0)).to.eq(tokenToColorHex(tokens[0].address, 36)) - expect(await nftDescriptor.tokenToColorHex(tokens[1].address, 0)).to.eq(tokenToColorHex(tokens[1].address, 36)) - }) - }) - - describe('#rangeLocation', () => { - it('returns the correct coordinates when range midpoint under -125_000', async () => { - const coords = await nftDescriptor.rangeLocation(-887_272, -887_100) - expect(coords[0]).to.eq('8') - expect(coords[1]).to.eq('7') - }) - - it('returns the correct coordinates when range midpoint is between -125_000 and -75_000', async () => { - const coords = await nftDescriptor.rangeLocation(-100_000, -90_000) - expect(coords[0]).to.eq('8') - expect(coords[1]).to.eq('10.5') - }) - - it('returns the correct coordinates when range midpoint is between -75_000 and -25_000', async () => { - const coords = await nftDescriptor.rangeLocation(-50_000, -20_000) - expect(coords[0]).to.eq('8') - expect(coords[1]).to.eq('14.25') - }) - - it('returns the correct coordinates when range midpoint is between -25_000 and -5_000', async () => { - const coords = await nftDescriptor.rangeLocation(-10_000, -5_000) - expect(coords[0]).to.eq('10') - expect(coords[1]).to.eq('18') - }) - - it('returns the correct coordinates when range midpoint is between -5_000 and 0', async () => { - const coords = await nftDescriptor.rangeLocation(-5_000, -4_000) - expect(coords[0]).to.eq('11') - expect(coords[1]).to.eq('21') - }) - - it('returns the correct coordinates when range midpoint is between 0 and 5_000', async () => { - const coords = await nftDescriptor.rangeLocation(4_000, 5_000) - expect(coords[0]).to.eq('13') - expect(coords[1]).to.eq('23') - }) - - it('returns the correct coordinates when range midpoint is between 5_000 and 25_000', async () => { - const coords = await nftDescriptor.rangeLocation(10_000, 15_000) - expect(coords[0]).to.eq('15') - expect(coords[1]).to.eq('25') - }) - - it('returns the correct coordinates when range midpoint is between 25_000 and 75_000', async () => { - const coords = await nftDescriptor.rangeLocation(25_000, 50_000) - expect(coords[0]).to.eq('18') - expect(coords[1]).to.eq('26') - }) - - it('returns the correct coordinates when range midpoint is between 75_000 and 125_000', async () => { - const coords = await nftDescriptor.rangeLocation(100_000, 125_000) - expect(coords[0]).to.eq('21') - expect(coords[1]).to.eq('27') - }) - - it('returns the correct coordinates when range midpoint is above 125_000', async () => { - const coords = await nftDescriptor.rangeLocation(200_000, 100_000) - expect(coords[0]).to.eq('24') - expect(coords[1]).to.eq('27') - }) - - it('math does not overflow on max value', async () => { - const coords = await nftDescriptor.rangeLocation(887_272, 887_272) - expect(coords[0]).to.eq('24') - expect(coords[1]).to.eq('27') - }) - }) - - describe('#svgImage', () => { - let tokenId: number - let baseTokenAddress: string - let quoteTokenAddress: string - let baseTokenSymbol: string - let quoteTokenSymbol: string - let baseTokenDecimals: number - let quoteTokenDecimals: number - let flipRatio: boolean - let tickLower: number - let tickUpper: number - let tickCurrent: number - let tickSpacing: number - let fee: number - let poolAddress: string - - beforeEach(async () => { - tokenId = 123 - quoteTokenAddress = '0x1234567890123456789123456789012345678901' - baseTokenAddress = '0xabcdeabcdefabcdefabcdefabcdefabcdefabcdf' - quoteTokenSymbol = 'UNI' - baseTokenSymbol = 'WETH' - tickLower = -1000 - tickUpper = 2000 - tickCurrent = 40 - fee = 500 - baseTokenDecimals = await tokens[0].decimals() - quoteTokenDecimals = await tokens[1].decimals() - flipRatio = false - tickSpacing = TICK_SPACINGS[FeeAmount.MEDIUM] - poolAddress = `0x${'b'.repeat(40)}` - }) - - it('matches the current snapshot', async () => { - const svg = await nftDescriptor.generateSVGImage({ - tokenId, - baseTokenAddress, - quoteTokenAddress, - baseTokenSymbol, - quoteTokenSymbol, - baseTokenDecimals, - quoteTokenDecimals, - flipRatio, - tickLower, - tickUpper, - tickCurrent, - tickSpacing, - fee, - poolAddress, - }) - - expect(svg).toMatchSnapshot() - fs.writeFileSync('./test/__snapshots__/NFTDescriptor.svg', svg) - }) - - it('returns a valid SVG', async () => { - const svg = await nftDescriptor.generateSVGImage({ - tokenId, - baseTokenAddress, - quoteTokenAddress, - baseTokenSymbol, - quoteTokenSymbol, - baseTokenDecimals, - quoteTokenDecimals, - flipRatio, - tickLower, - tickUpper, - tickCurrent, - tickSpacing, - fee, - poolAddress, - }) - expect(isSvg(svg)).to.eq(true) - }) - }) - - describe('#isRare', () => { - it('returns true sometimes', async () => { - expect(await nftDescriptor.isRare(1, `0x${'b'.repeat(40)}`)).to.eq(true) - }) - - it('returns false sometimes', async () => { - expect(await nftDescriptor.isRare(2, `0x${'b'.repeat(40)}`)).to.eq(false) - }) - }) - - function constructTokenMetadata( - tokenId: number, - quoteTokenAddress: string, - baseTokenAddress: string, - poolAddress: string, - quoteTokenSymbol: string, - baseTokenSymbol: string, - flipRatio: boolean, - tickLower: number, - tickUpper: number, - tickCurrent: number, - feeTier: string, - prices: string - ): { name: string; description: string } { - quoteTokenSymbol = quoteTokenSymbol.replace(/"/gi, '"') - baseTokenSymbol = baseTokenSymbol.replace(/"/gi, '"') - return { - name: `Uniswap - ${feeTier} - ${quoteTokenSymbol}/${baseTokenSymbol} - ${prices}`, - description: `This NFT represents a liquidity position in a Uniswap V3 ${quoteTokenSymbol}-${baseTokenSymbol} pool. The owner of this NFT can modify or redeem the position.\n\ -\nPool Address: ${poolAddress}\n${quoteTokenSymbol} Address: ${quoteTokenAddress.toLowerCase()}\n${baseTokenSymbol} Address: ${baseTokenAddress.toLowerCase()}\n\ -Fee Tier: ${feeTier}\nToken ID: ${tokenId}\n\n⚠️ DISCLAIMER: Due diligence is imperative when assessing this NFT. Make sure token addresses match the expected tokens, as \ -token symbols may be imitated.`, - } - } -}) diff --git a/lib/v3-periphery/test/NonfungiblePositionManager.spec.ts b/lib/v3-periphery/test/NonfungiblePositionManager.spec.ts deleted file mode 100644 index 98215ad..0000000 --- a/lib/v3-periphery/test/NonfungiblePositionManager.spec.ts +++ /dev/null @@ -1,1304 +0,0 @@ -import { abi as IUniswapV3PoolABI } from '@uniswap/v3-core/artifacts/contracts/interfaces/IUniswapV3Pool.sol/IUniswapV3Pool.json' -import { Fixture } from 'ethereum-waffle' -import { BigNumberish, constants, Wallet } from 'ethers' -import { ethers, waffle } from 'hardhat' -import { - IUniswapV3Factory, - IWETH9, - MockTimeNonfungiblePositionManager, - NonfungiblePositionManagerPositionsGasTest, - SwapRouter, - TestERC20, - TestPositionNFTOwner, -} from '../typechain' -import completeFixture from './shared/completeFixture' -import { computePoolAddress } from './shared/computePoolAddress' -import { FeeAmount, MaxUint128, TICK_SPACINGS } from './shared/constants' -import { encodePriceSqrt } from './shared/encodePriceSqrt' -import { expandTo18Decimals } from './shared/expandTo18Decimals' -import { expect } from './shared/expect' -import { extractJSONFromURI } from './shared/extractJSONFromURI' -import getPermitNFTSignature from './shared/getPermitNFTSignature' -import { encodePath } from './shared/path' -import poolAtAddress from './shared/poolAtAddress' -import snapshotGasCost from './shared/snapshotGasCost' -import { getMaxTick, getMinTick } from './shared/ticks' -import { sortedTokens } from './shared/tokenSort' - -describe('NonfungiblePositionManager', () => { - let wallets: Wallet[] - let wallet: Wallet, other: Wallet - - const nftFixture: Fixture<{ - nft: MockTimeNonfungiblePositionManager - factory: IUniswapV3Factory - tokens: [TestERC20, TestERC20, TestERC20] - weth9: IWETH9 - router: SwapRouter - }> = async (wallets, provider) => { - const { weth9, factory, tokens, nft, router } = await completeFixture(wallets, provider) - - // approve & fund wallets - for (const token of tokens) { - await token.approve(nft.address, constants.MaxUint256) - await token.connect(other).approve(nft.address, constants.MaxUint256) - await token.transfer(other.address, expandTo18Decimals(1_000_000)) - } - - return { - nft, - factory, - tokens, - weth9, - router, - } - } - - let factory: IUniswapV3Factory - let nft: MockTimeNonfungiblePositionManager - let tokens: [TestERC20, TestERC20, TestERC20] - let weth9: IWETH9 - let router: SwapRouter - - let loadFixture: ReturnType - - before('create fixture loader', async () => { - wallets = await (ethers as any).getSigners() - ;[wallet, other] = wallets - - loadFixture = waffle.createFixtureLoader(wallets) - }) - - beforeEach('load fixture', async () => { - ;({ nft, factory, tokens, weth9, router } = await loadFixture(nftFixture)) - }) - - it('bytecode size', async () => { - expect(((await nft.provider.getCode(nft.address)).length - 2) / 2).to.matchSnapshot() - }) - - describe('#createAndInitializePoolIfNecessary', () => { - it('creates the pool at the expected address', async () => { - const expectedAddress = computePoolAddress( - factory.address, - [tokens[0].address, tokens[1].address], - FeeAmount.MEDIUM - ) - const code = await wallet.provider.getCode(expectedAddress) - expect(code).to.eq('0x') - await nft.createAndInitializePoolIfNecessary( - tokens[0].address, - tokens[1].address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - const codeAfter = await wallet.provider.getCode(expectedAddress) - expect(codeAfter).to.not.eq('0x') - }) - - it('is payable', async () => { - await nft.createAndInitializePoolIfNecessary( - tokens[0].address, - tokens[1].address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1), - { value: 1 } - ) - }) - - it('works if pool is created but not initialized', async () => { - const expectedAddress = computePoolAddress( - factory.address, - [tokens[0].address, tokens[1].address], - FeeAmount.MEDIUM - ) - await factory.createPool(tokens[0].address, tokens[1].address, FeeAmount.MEDIUM) - const code = await wallet.provider.getCode(expectedAddress) - expect(code).to.not.eq('0x') - await nft.createAndInitializePoolIfNecessary( - tokens[0].address, - tokens[1].address, - FeeAmount.MEDIUM, - encodePriceSqrt(2, 1) - ) - }) - - it('works if pool is created and initialized', async () => { - const expectedAddress = computePoolAddress( - factory.address, - [tokens[0].address, tokens[1].address], - FeeAmount.MEDIUM - ) - await factory.createPool(tokens[0].address, tokens[1].address, FeeAmount.MEDIUM) - const pool = new ethers.Contract(expectedAddress, IUniswapV3PoolABI, wallet) - - await pool.initialize(encodePriceSqrt(3, 1)) - const code = await wallet.provider.getCode(expectedAddress) - expect(code).to.not.eq('0x') - await nft.createAndInitializePoolIfNecessary( - tokens[0].address, - tokens[1].address, - FeeAmount.MEDIUM, - encodePriceSqrt(4, 1) - ) - }) - - it('could theoretically use eth via multicall', async () => { - const [token0, token1] = sortedTokens(weth9, tokens[0]) - - const createAndInitializePoolIfNecessaryData = nft.interface.encodeFunctionData( - 'createAndInitializePoolIfNecessary', - [token0.address, token1.address, FeeAmount.MEDIUM, encodePriceSqrt(1, 1)] - ) - - await nft.multicall([createAndInitializePoolIfNecessaryData], { value: expandTo18Decimals(1) }) - }) - - it('gas', async () => { - await snapshotGasCost( - nft.createAndInitializePoolIfNecessary( - tokens[0].address, - tokens[1].address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - ) - }) - }) - - describe('#mint', () => { - it('fails if pool does not exist', async () => { - await expect( - nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - recipient: wallet.address, - deadline: 1, - fee: FeeAmount.MEDIUM, - }) - ).to.be.reverted - }) - - it('fails if cannot transfer', async () => { - await nft.createAndInitializePoolIfNecessary( - tokens[0].address, - tokens[1].address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - await tokens[0].approve(nft.address, 0) - await expect( - nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - recipient: wallet.address, - deadline: 1, - }) - ).to.be.revertedWith('STF') - }) - - it('creates a token', async () => { - await nft.createAndInitializePoolIfNecessary( - tokens[0].address, - tokens[1].address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - fee: FeeAmount.MEDIUM, - recipient: other.address, - amount0Desired: 15, - amount1Desired: 15, - amount0Min: 0, - amount1Min: 0, - deadline: 10, - }) - expect(await nft.balanceOf(other.address)).to.eq(1) - expect(await nft.tokenOfOwnerByIndex(other.address, 0)).to.eq(1) - const { - fee, - token0, - token1, - tickLower, - tickUpper, - liquidity, - tokensOwed0, - tokensOwed1, - feeGrowthInside0LastX128, - feeGrowthInside1LastX128, - } = await nft.positions(1) - expect(token0).to.eq(tokens[0].address) - expect(token1).to.eq(tokens[1].address) - expect(fee).to.eq(FeeAmount.MEDIUM) - expect(tickLower).to.eq(getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM])) - expect(tickUpper).to.eq(getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM])) - expect(liquidity).to.eq(15) - expect(tokensOwed0).to.eq(0) - expect(tokensOwed1).to.eq(0) - expect(feeGrowthInside0LastX128).to.eq(0) - expect(feeGrowthInside1LastX128).to.eq(0) - }) - - it('can use eth via multicall', async () => { - const [token0, token1] = sortedTokens(weth9, tokens[0]) - - // remove any approval - await weth9.approve(nft.address, 0) - - const createAndInitializeData = nft.interface.encodeFunctionData('createAndInitializePoolIfNecessary', [ - token0.address, - token1.address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1), - ]) - - const mintData = nft.interface.encodeFunctionData('mint', [ - { - token0: token0.address, - token1: token1.address, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - fee: FeeAmount.MEDIUM, - recipient: other.address, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - }, - ]) - - const refundETHData = nft.interface.encodeFunctionData('refundETH') - - const balanceBefore = await wallet.getBalance() - const tx = await nft.multicall([createAndInitializeData, mintData, refundETHData], { - value: expandTo18Decimals(1), - }) - const receipt = await tx.wait() - const balanceAfter = await wallet.getBalance() - expect(balanceBefore).to.eq(balanceAfter.add(receipt.gasUsed.mul(tx.gasPrice)).add(100)) - }) - - it('emits an event') - - it('gas first mint for pool', async () => { - await nft.createAndInitializePoolIfNecessary( - tokens[0].address, - tokens[1].address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - - await snapshotGasCost( - nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - fee: FeeAmount.MEDIUM, - recipient: wallet.address, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 10, - }) - ) - }) - - it('gas first mint for pool using eth with zero refund', async () => { - const [token0, token1] = sortedTokens(weth9, tokens[0]) - await nft.createAndInitializePoolIfNecessary( - token0.address, - token1.address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - - await snapshotGasCost( - nft.multicall( - [ - nft.interface.encodeFunctionData('mint', [ - { - token0: token0.address, - token1: token1.address, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - fee: FeeAmount.MEDIUM, - recipient: wallet.address, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 10, - }, - ]), - nft.interface.encodeFunctionData('refundETH'), - ], - { value: 100 } - ) - ) - }) - - it('gas first mint for pool using eth with non-zero refund', async () => { - const [token0, token1] = sortedTokens(weth9, tokens[0]) - await nft.createAndInitializePoolIfNecessary( - token0.address, - token1.address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - - await snapshotGasCost( - nft.multicall( - [ - nft.interface.encodeFunctionData('mint', [ - { - token0: token0.address, - token1: token1.address, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - fee: FeeAmount.MEDIUM, - recipient: wallet.address, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 10, - }, - ]), - nft.interface.encodeFunctionData('refundETH'), - ], - { value: 1000 } - ) - ) - }) - - it('gas mint on same ticks', async () => { - await nft.createAndInitializePoolIfNecessary( - tokens[0].address, - tokens[1].address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - fee: FeeAmount.MEDIUM, - recipient: other.address, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 10, - }) - - await snapshotGasCost( - nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - fee: FeeAmount.MEDIUM, - recipient: wallet.address, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 10, - }) - ) - }) - - it('gas mint for same pool, different ticks', async () => { - await nft.createAndInitializePoolIfNecessary( - tokens[0].address, - tokens[1].address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - fee: FeeAmount.MEDIUM, - recipient: other.address, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 10, - }) - - await snapshotGasCost( - nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]) + TICK_SPACINGS[FeeAmount.MEDIUM], - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]) - TICK_SPACINGS[FeeAmount.MEDIUM], - fee: FeeAmount.MEDIUM, - recipient: wallet.address, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 10, - }) - ) - }) - }) - - describe('#increaseLiquidity', () => { - const tokenId = 1 - beforeEach('create a position', async () => { - await nft.createAndInitializePoolIfNecessary( - tokens[0].address, - tokens[1].address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - fee: FeeAmount.MEDIUM, - recipient: other.address, - amount0Desired: 1000, - amount1Desired: 1000, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - }) - }) - - it('increases position liquidity', async () => { - await nft.increaseLiquidity({ - tokenId: tokenId, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - }) - const { liquidity } = await nft.positions(tokenId) - expect(liquidity).to.eq(1100) - }) - - it('emits an event') - - it('can be paid with ETH', async () => { - const [token0, token1] = sortedTokens(tokens[0], weth9) - - const tokenId = 1 - - await nft.createAndInitializePoolIfNecessary( - token0.address, - token1.address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - - const mintData = nft.interface.encodeFunctionData('mint', [ - { - token0: token0.address, - token1: token1.address, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - recipient: other.address, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - }, - ]) - const refundETHData = nft.interface.encodeFunctionData('unwrapWETH9', [0, other.address]) - await nft.multicall([mintData, refundETHData], { value: expandTo18Decimals(1) }) - - const increaseLiquidityData = nft.interface.encodeFunctionData('increaseLiquidity', [ - { - tokenId: tokenId, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - }, - ]) - await nft.multicall([increaseLiquidityData, refundETHData], { value: expandTo18Decimals(1) }) - }) - - it('gas', async () => { - await snapshotGasCost( - nft.increaseLiquidity({ - tokenId: tokenId, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - }) - ) - }) - }) - - describe('#decreaseLiquidity', () => { - const tokenId = 1 - beforeEach('create a position', async () => { - await nft.createAndInitializePoolIfNecessary( - tokens[0].address, - tokens[1].address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - fee: FeeAmount.MEDIUM, - recipient: other.address, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - }) - }) - - it('emits an event') - - it('fails if past deadline', async () => { - await nft.setTime(2) - await expect( - nft.connect(other).decreaseLiquidity({ tokenId, liquidity: 50, amount0Min: 0, amount1Min: 0, deadline: 1 }) - ).to.be.revertedWith('Transaction too old') - }) - - it('cannot be called by other addresses', async () => { - await expect( - nft.decreaseLiquidity({ tokenId, liquidity: 50, amount0Min: 0, amount1Min: 0, deadline: 1 }) - ).to.be.revertedWith('Not approved') - }) - - it('decreases position liquidity', async () => { - await nft.connect(other).decreaseLiquidity({ tokenId, liquidity: 25, amount0Min: 0, amount1Min: 0, deadline: 1 }) - const { liquidity } = await nft.positions(tokenId) - expect(liquidity).to.eq(75) - }) - - it('is payable', async () => { - await nft - .connect(other) - .decreaseLiquidity({ tokenId, liquidity: 25, amount0Min: 0, amount1Min: 0, deadline: 1 }, { value: 1 }) - }) - - it('accounts for tokens owed', async () => { - await nft.connect(other).decreaseLiquidity({ tokenId, liquidity: 25, amount0Min: 0, amount1Min: 0, deadline: 1 }) - const { tokensOwed0, tokensOwed1 } = await nft.positions(tokenId) - expect(tokensOwed0).to.eq(24) - expect(tokensOwed1).to.eq(24) - }) - - it('can decrease for all the liquidity', async () => { - await nft.connect(other).decreaseLiquidity({ tokenId, liquidity: 100, amount0Min: 0, amount1Min: 0, deadline: 1 }) - const { liquidity } = await nft.positions(tokenId) - expect(liquidity).to.eq(0) - }) - - it('cannot decrease for more than all the liquidity', async () => { - await expect( - nft.connect(other).decreaseLiquidity({ tokenId, liquidity: 101, amount0Min: 0, amount1Min: 0, deadline: 1 }) - ).to.be.reverted - }) - - it('cannot decrease for more than the liquidity of the nft position', async () => { - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - fee: FeeAmount.MEDIUM, - recipient: other.address, - amount0Desired: 200, - amount1Desired: 200, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - }) - await expect( - nft.connect(other).decreaseLiquidity({ tokenId, liquidity: 101, amount0Min: 0, amount1Min: 0, deadline: 1 }) - ).to.be.reverted - }) - - it('gas partial decrease', async () => { - await snapshotGasCost( - nft.connect(other).decreaseLiquidity({ tokenId, liquidity: 50, amount0Min: 0, amount1Min: 0, deadline: 1 }) - ) - }) - - it('gas complete decrease', async () => { - await snapshotGasCost( - nft.connect(other).decreaseLiquidity({ tokenId, liquidity: 100, amount0Min: 0, amount1Min: 0, deadline: 1 }) - ) - }) - }) - - describe('#collect', () => { - const tokenId = 1 - beforeEach('create a position', async () => { - await nft.createAndInitializePoolIfNecessary( - tokens[0].address, - tokens[1].address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - recipient: other.address, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - }) - }) - - it('emits an event') - - it('cannot be called by other addresses', async () => { - await expect( - nft.collect({ - tokenId, - recipient: wallet.address, - amount0Max: MaxUint128, - amount1Max: MaxUint128, - }) - ).to.be.revertedWith('Not approved') - }) - - it('cannot be called with 0 for both amounts', async () => { - await expect( - nft.connect(other).collect({ - tokenId, - recipient: wallet.address, - amount0Max: 0, - amount1Max: 0, - }) - ).to.be.reverted - }) - - it('no op if no tokens are owed', async () => { - await expect( - nft.connect(other).collect({ - tokenId, - recipient: wallet.address, - amount0Max: MaxUint128, - amount1Max: MaxUint128, - }) - ) - .to.not.emit(tokens[0], 'Transfer') - .to.not.emit(tokens[1], 'Transfer') - }) - - it('transfers tokens owed from burn', async () => { - await nft.connect(other).decreaseLiquidity({ tokenId, liquidity: 50, amount0Min: 0, amount1Min: 0, deadline: 1 }) - const poolAddress = computePoolAddress(factory.address, [tokens[0].address, tokens[1].address], FeeAmount.MEDIUM) - await expect( - nft.connect(other).collect({ - tokenId, - recipient: wallet.address, - amount0Max: MaxUint128, - amount1Max: MaxUint128, - }) - ) - .to.emit(tokens[0], 'Transfer') - .withArgs(poolAddress, wallet.address, 49) - .to.emit(tokens[1], 'Transfer') - .withArgs(poolAddress, wallet.address, 49) - }) - - it('gas transfers both', async () => { - await nft.connect(other).decreaseLiquidity({ tokenId, liquidity: 50, amount0Min: 0, amount1Min: 0, deadline: 1 }) - await snapshotGasCost( - nft.connect(other).collect({ - tokenId, - recipient: wallet.address, - amount0Max: MaxUint128, - amount1Max: MaxUint128, - }) - ) - }) - - it('gas transfers token0 only', async () => { - await nft.connect(other).decreaseLiquidity({ tokenId, liquidity: 50, amount0Min: 0, amount1Min: 0, deadline: 1 }) - await snapshotGasCost( - nft.connect(other).collect({ - tokenId, - recipient: wallet.address, - amount0Max: MaxUint128, - amount1Max: 0, - }) - ) - }) - - it('gas transfers token1 only', async () => { - await nft.connect(other).decreaseLiquidity({ tokenId, liquidity: 50, amount0Min: 0, amount1Min: 0, deadline: 1 }) - await snapshotGasCost( - nft.connect(other).collect({ - tokenId, - recipient: wallet.address, - amount0Max: 0, - amount1Max: MaxUint128, - }) - ) - }) - }) - - describe('#burn', () => { - const tokenId = 1 - beforeEach('create a position', async () => { - await nft.createAndInitializePoolIfNecessary( - tokens[0].address, - tokens[1].address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - recipient: other.address, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - }) - }) - - it('emits an event') - - it('cannot be called by other addresses', async () => { - await expect(nft.burn(tokenId)).to.be.revertedWith('Not approved') - }) - - it('cannot be called while there is still liquidity', async () => { - await expect(nft.connect(other).burn(tokenId)).to.be.revertedWith('Not cleared') - }) - - it('cannot be called while there is still partial liquidity', async () => { - await nft.connect(other).decreaseLiquidity({ tokenId, liquidity: 50, amount0Min: 0, amount1Min: 0, deadline: 1 }) - await expect(nft.connect(other).burn(tokenId)).to.be.revertedWith('Not cleared') - }) - - it('cannot be called while there is still tokens owed', async () => { - await nft.connect(other).decreaseLiquidity({ tokenId, liquidity: 100, amount0Min: 0, amount1Min: 0, deadline: 1 }) - await expect(nft.connect(other).burn(tokenId)).to.be.revertedWith('Not cleared') - }) - - it('deletes the token', async () => { - await nft.connect(other).decreaseLiquidity({ tokenId, liquidity: 100, amount0Min: 0, amount1Min: 0, deadline: 1 }) - await nft.connect(other).collect({ - tokenId, - recipient: wallet.address, - amount0Max: MaxUint128, - amount1Max: MaxUint128, - }) - await nft.connect(other).burn(tokenId) - await expect(nft.positions(tokenId)).to.be.revertedWith('Invalid token ID') - }) - - it('gas', async () => { - await nft.connect(other).decreaseLiquidity({ tokenId, liquidity: 100, amount0Min: 0, amount1Min: 0, deadline: 1 }) - await nft.connect(other).collect({ - tokenId, - recipient: wallet.address, - amount0Max: MaxUint128, - amount1Max: MaxUint128, - }) - await snapshotGasCost(nft.connect(other).burn(tokenId)) - }) - }) - - describe('#transferFrom', () => { - const tokenId = 1 - beforeEach('create a position', async () => { - await nft.createAndInitializePoolIfNecessary( - tokens[0].address, - tokens[1].address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - recipient: other.address, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - }) - }) - - it('can only be called by authorized or owner', async () => { - await expect(nft.transferFrom(other.address, wallet.address, tokenId)).to.be.revertedWith( - 'ERC721: transfer caller is not owner nor approved' - ) - }) - - it('changes the owner', async () => { - await nft.connect(other).transferFrom(other.address, wallet.address, tokenId) - expect(await nft.ownerOf(tokenId)).to.eq(wallet.address) - }) - - it('removes existing approval', async () => { - await nft.connect(other).approve(wallet.address, tokenId) - expect(await nft.getApproved(tokenId)).to.eq(wallet.address) - await nft.transferFrom(other.address, wallet.address, tokenId) - expect(await nft.getApproved(tokenId)).to.eq(constants.AddressZero) - }) - - it('gas', async () => { - await snapshotGasCost(nft.connect(other).transferFrom(other.address, wallet.address, tokenId)) - }) - - it('gas comes from approved', async () => { - await nft.connect(other).approve(wallet.address, tokenId) - await snapshotGasCost(nft.transferFrom(other.address, wallet.address, tokenId)) - }) - }) - - describe('#permit', () => { - it('emits an event') - - describe('owned by eoa', () => { - const tokenId = 1 - beforeEach('create a position', async () => { - await nft.createAndInitializePoolIfNecessary( - tokens[0].address, - tokens[1].address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - recipient: other.address, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - }) - }) - - it('changes the operator of the position and increments the nonce', async () => { - const { v, r, s } = await getPermitNFTSignature(other, nft, wallet.address, tokenId, 1) - await nft.permit(wallet.address, tokenId, 1, v, r, s) - expect((await nft.positions(tokenId)).nonce).to.eq(1) - expect((await nft.positions(tokenId)).operator).to.eq(wallet.address) - }) - - it('cannot be called twice with the same signature', async () => { - const { v, r, s } = await getPermitNFTSignature(other, nft, wallet.address, tokenId, 1) - await nft.permit(wallet.address, tokenId, 1, v, r, s) - await expect(nft.permit(wallet.address, tokenId, 1, v, r, s)).to.be.reverted - }) - - it('fails with invalid signature', async () => { - const { v, r, s } = await getPermitNFTSignature(wallet, nft, wallet.address, tokenId, 1) - await expect(nft.permit(wallet.address, tokenId, 1, v + 3, r, s)).to.be.revertedWith('Invalid signature') - }) - - it('fails with signature not from owner', async () => { - const { v, r, s } = await getPermitNFTSignature(wallet, nft, wallet.address, tokenId, 1) - await expect(nft.permit(wallet.address, tokenId, 1, v, r, s)).to.be.revertedWith('Unauthorized') - }) - - it('fails with expired signature', async () => { - await nft.setTime(2) - const { v, r, s } = await getPermitNFTSignature(other, nft, wallet.address, tokenId, 1) - await expect(nft.permit(wallet.address, tokenId, 1, v, r, s)).to.be.revertedWith('Permit expired') - }) - - it('gas', async () => { - const { v, r, s } = await getPermitNFTSignature(other, nft, wallet.address, tokenId, 1) - await snapshotGasCost(nft.permit(wallet.address, tokenId, 1, v, r, s)) - }) - }) - describe('owned by verifying contract', () => { - const tokenId = 1 - let testPositionNFTOwner: TestPositionNFTOwner - - beforeEach('deploy test owner and create a position', async () => { - testPositionNFTOwner = (await ( - await ethers.getContractFactory('TestPositionNFTOwner') - ).deploy()) as TestPositionNFTOwner - - await nft.createAndInitializePoolIfNecessary( - tokens[0].address, - tokens[1].address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - recipient: testPositionNFTOwner.address, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - }) - }) - - it('changes the operator of the position and increments the nonce', async () => { - const { v, r, s } = await getPermitNFTSignature(other, nft, wallet.address, tokenId, 1) - await testPositionNFTOwner.setOwner(other.address) - await nft.permit(wallet.address, tokenId, 1, v, r, s) - expect((await nft.positions(tokenId)).nonce).to.eq(1) - expect((await nft.positions(tokenId)).operator).to.eq(wallet.address) - }) - - it('fails if owner contract is owned by different address', async () => { - const { v, r, s } = await getPermitNFTSignature(other, nft, wallet.address, tokenId, 1) - await testPositionNFTOwner.setOwner(wallet.address) - await expect(nft.permit(wallet.address, tokenId, 1, v, r, s)).to.be.revertedWith('Unauthorized') - }) - - it('fails with signature not from owner', async () => { - const { v, r, s } = await getPermitNFTSignature(wallet, nft, wallet.address, tokenId, 1) - await testPositionNFTOwner.setOwner(other.address) - await expect(nft.permit(wallet.address, tokenId, 1, v, r, s)).to.be.revertedWith('Unauthorized') - }) - - it('fails with expired signature', async () => { - await nft.setTime(2) - const { v, r, s } = await getPermitNFTSignature(other, nft, wallet.address, tokenId, 1) - await testPositionNFTOwner.setOwner(other.address) - await expect(nft.permit(wallet.address, tokenId, 1, v, r, s)).to.be.revertedWith('Permit expired') - }) - - it('gas', async () => { - const { v, r, s } = await getPermitNFTSignature(other, nft, wallet.address, tokenId, 1) - await testPositionNFTOwner.setOwner(other.address) - await snapshotGasCost(nft.permit(wallet.address, tokenId, 1, v, r, s)) - }) - }) - }) - - describe('multicall exit', () => { - const tokenId = 1 - beforeEach('create a position', async () => { - await nft.createAndInitializePoolIfNecessary( - tokens[0].address, - tokens[1].address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - recipient: other.address, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - }) - }) - - async function exit({ - nft, - liquidity, - tokenId, - amount0Min, - amount1Min, - recipient, - }: { - nft: MockTimeNonfungiblePositionManager - tokenId: BigNumberish - liquidity: BigNumberish - amount0Min: BigNumberish - amount1Min: BigNumberish - recipient: string - }) { - const decreaseLiquidityData = nft.interface.encodeFunctionData('decreaseLiquidity', [ - { tokenId, liquidity, amount0Min, amount1Min, deadline: 1 }, - ]) - const collectData = nft.interface.encodeFunctionData('collect', [ - { - tokenId, - recipient, - amount0Max: MaxUint128, - amount1Max: MaxUint128, - }, - ]) - const burnData = nft.interface.encodeFunctionData('burn', [tokenId]) - - return nft.multicall([decreaseLiquidityData, collectData, burnData]) - } - - it('executes all the actions', async () => { - const pool = poolAtAddress( - computePoolAddress(factory.address, [tokens[0].address, tokens[1].address], FeeAmount.MEDIUM), - wallet - ) - await expect( - exit({ - nft: nft.connect(other), - tokenId, - liquidity: 100, - amount0Min: 0, - amount1Min: 0, - recipient: wallet.address, - }) - ) - .to.emit(pool, 'Burn') - .to.emit(pool, 'Collect') - }) - - it('gas', async () => { - await snapshotGasCost( - exit({ - nft: nft.connect(other), - tokenId, - liquidity: 100, - amount0Min: 0, - amount1Min: 0, - recipient: wallet.address, - }) - ) - }) - }) - - describe('#tokenURI', async () => { - const tokenId = 1 - beforeEach('create a position', async () => { - await nft.createAndInitializePoolIfNecessary( - tokens[0].address, - tokens[1].address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - recipient: other.address, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - }) - }) - - it('reverts for invalid token id', async () => { - await expect(nft.tokenURI(tokenId + 1)).to.be.reverted - }) - - it('returns a data URI with correct mime type', async () => { - expect(await nft.tokenURI(tokenId)).to.match(/data:application\/json;base64,.+/) - }) - - it('content is valid JSON and structure', async () => { - const content = extractJSONFromURI(await nft.tokenURI(tokenId)) - expect(content).to.haveOwnProperty('name').is.a('string') - expect(content).to.haveOwnProperty('description').is.a('string') - expect(content).to.haveOwnProperty('image').is.a('string') - }) - }) - - describe('fees accounting', () => { - beforeEach('create two positions', async () => { - await nft.createAndInitializePoolIfNecessary( - tokens[0].address, - tokens[1].address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - // nft 1 earns 25% of fees - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(FeeAmount.MEDIUM), - tickUpper: getMaxTick(FeeAmount.MEDIUM), - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - recipient: wallet.address, - }) - // nft 2 earns 75% of fees - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(FeeAmount.MEDIUM), - tickUpper: getMaxTick(FeeAmount.MEDIUM), - - amount0Desired: 300, - amount1Desired: 300, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - recipient: wallet.address, - }) - }) - - describe('10k of token0 fees collect', () => { - beforeEach('swap for ~10k of fees', async () => { - const swapAmount = 3_333_333 - await tokens[0].approve(router.address, swapAmount) - await router.exactInput({ - recipient: wallet.address, - deadline: 1, - path: encodePath([tokens[0].address, tokens[1].address], [FeeAmount.MEDIUM]), - amountIn: swapAmount, - amountOutMinimum: 0, - }) - }) - it('expected amounts', async () => { - const { amount0: nft1Amount0, amount1: nft1Amount1 } = await nft.callStatic.collect({ - tokenId: 1, - recipient: wallet.address, - amount0Max: MaxUint128, - amount1Max: MaxUint128, - }) - const { amount0: nft2Amount0, amount1: nft2Amount1 } = await nft.callStatic.collect({ - tokenId: 2, - recipient: wallet.address, - amount0Max: MaxUint128, - amount1Max: MaxUint128, - }) - expect(nft1Amount0).to.eq(2501) - expect(nft1Amount1).to.eq(0) - expect(nft2Amount0).to.eq(7503) - expect(nft2Amount1).to.eq(0) - }) - - it('actually collected', async () => { - const poolAddress = computePoolAddress( - factory.address, - [tokens[0].address, tokens[1].address], - FeeAmount.MEDIUM - ) - - await expect( - nft.collect({ - tokenId: 1, - recipient: wallet.address, - amount0Max: MaxUint128, - amount1Max: MaxUint128, - }) - ) - .to.emit(tokens[0], 'Transfer') - .withArgs(poolAddress, wallet.address, 2501) - .to.not.emit(tokens[1], 'Transfer') - await expect( - nft.collect({ - tokenId: 2, - recipient: wallet.address, - amount0Max: MaxUint128, - amount1Max: MaxUint128, - }) - ) - .to.emit(tokens[0], 'Transfer') - .withArgs(poolAddress, wallet.address, 7503) - .to.not.emit(tokens[1], 'Transfer') - }) - }) - }) - - describe('#positions', async () => { - it('gas', async () => { - const positionsGasTestFactory = await ethers.getContractFactory('NonfungiblePositionManagerPositionsGasTest') - const positionsGasTest = (await positionsGasTestFactory.deploy( - nft.address - )) as NonfungiblePositionManagerPositionsGasTest - - await nft.createAndInitializePoolIfNecessary( - tokens[0].address, - tokens[1].address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - fee: FeeAmount.MEDIUM, - recipient: other.address, - amount0Desired: 15, - amount1Desired: 15, - amount0Min: 0, - amount1Min: 0, - deadline: 10, - }) - - await snapshotGasCost(positionsGasTest.getGasCostOfPositions(1)) - }) - }) -}) diff --git a/lib/v3-periphery/test/NonfungibleTokenPositionDescriptor.spec.ts b/lib/v3-periphery/test/NonfungibleTokenPositionDescriptor.spec.ts deleted file mode 100644 index 783ce4a..0000000 --- a/lib/v3-periphery/test/NonfungibleTokenPositionDescriptor.spec.ts +++ /dev/null @@ -1,217 +0,0 @@ -import { constants, Wallet } from 'ethers' -import { waffle, ethers } from 'hardhat' -import { expect } from './shared/expect' -import { Fixture } from 'ethereum-waffle' -import { NonfungibleTokenPositionDescriptor, MockTimeNonfungiblePositionManager, TestERC20 } from '../typechain' -import completeFixture from './shared/completeFixture' -import { encodePriceSqrt } from './shared/encodePriceSqrt' -import { FeeAmount, TICK_SPACINGS } from './shared/constants' -import { getMaxTick, getMinTick } from './shared/ticks' -import { sortedTokens } from './shared/tokenSort' -import { extractJSONFromURI } from './shared/extractJSONFromURI' - -const DAI = '0x6B175474E89094C44Da98b954EedeAC495271d0F' -const USDC = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48' -const USDT = '0xdAC17F958D2ee523a2206206994597C13D831ec7' -const TBTC = '0x8dAEBADE922dF735c38C80C7eBD708Af50815fAa' -const WBTC = '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599' - -describe('NonfungibleTokenPositionDescriptor', () => { - let wallets: Wallet[] - - const nftPositionDescriptorCompleteFixture: Fixture<{ - nftPositionDescriptor: NonfungibleTokenPositionDescriptor - tokens: [TestERC20, TestERC20, TestERC20] - nft: MockTimeNonfungiblePositionManager - }> = async (wallets, provider) => { - const { factory, nft, router, nftDescriptor } = await completeFixture(wallets, provider) - const tokenFactory = await ethers.getContractFactory('TestERC20') - const tokens: [TestERC20, TestERC20, TestERC20] = [ - (await tokenFactory.deploy(constants.MaxUint256.div(2))) as TestERC20, // do not use maxu256 to avoid overflowing - (await tokenFactory.deploy(constants.MaxUint256.div(2))) as TestERC20, - (await tokenFactory.deploy(constants.MaxUint256.div(2))) as TestERC20, - ] - tokens.sort((a, b) => (a.address.toLowerCase() < b.address.toLowerCase() ? -1 : 1)) - - return { - nftPositionDescriptor: nftDescriptor, - tokens, - nft, - } - } - - let nftPositionDescriptor: NonfungibleTokenPositionDescriptor - let tokens: [TestERC20, TestERC20, TestERC20] - let nft: MockTimeNonfungiblePositionManager - let weth9: TestERC20 - - let loadFixture: ReturnType - - before('create fixture loader', async () => { - wallets = await (ethers as any).getSigners() - - loadFixture = waffle.createFixtureLoader(wallets) - }) - - beforeEach('load fixture', async () => { - ;({ tokens, nft, nftPositionDescriptor } = await loadFixture(nftPositionDescriptorCompleteFixture)) - const tokenFactory = await ethers.getContractFactory('TestERC20') - weth9 = tokenFactory.attach(await nftPositionDescriptor.WETH9()) as TestERC20 - }) - - describe('#tokenRatioPriority', () => { - it('returns -100 for WETH9', async () => { - expect(await nftPositionDescriptor.tokenRatioPriority(weth9.address, 1)).to.eq(-100) - }) - - it('returns 200 for USDC', async () => { - expect(await nftPositionDescriptor.tokenRatioPriority(USDC, 1)).to.eq(300) - }) - - it('returns 100 for DAI', async () => { - expect(await nftPositionDescriptor.tokenRatioPriority(DAI, 1)).to.eq(100) - }) - - it('returns 150 for USDT', async () => { - expect(await nftPositionDescriptor.tokenRatioPriority(USDT, 1)).to.eq(200) - }) - - it('returns -200 for TBTC', async () => { - expect(await nftPositionDescriptor.tokenRatioPriority(TBTC, 1)).to.eq(-200) - }) - - it('returns -250 for WBTC', async () => { - expect(await nftPositionDescriptor.tokenRatioPriority(WBTC, 1)).to.eq(-300) - }) - - it('returns 0 for any non-ratioPriority token', async () => { - expect(await nftPositionDescriptor.tokenRatioPriority(tokens[0].address, 1)).to.eq(0) - }) - }) - - describe('#flipRatio', () => { - it('returns false if neither token has priority ordering', async () => { - expect(await nftPositionDescriptor.flipRatio(tokens[0].address, tokens[2].address, 1)).to.eq(false) - }) - - it('returns true if both tokens are numerators but token0 has a higher priority ordering', async () => { - expect(await nftPositionDescriptor.flipRatio(USDC, DAI, 1)).to.eq(true) - }) - - it('returns true if both tokens are denominators but token1 has lower priority ordering', async () => { - expect(await nftPositionDescriptor.flipRatio(weth9.address, WBTC, 1)).to.eq(true) - }) - - it('returns true if token0 is a numerator and token1 is a denominator', async () => { - expect(await nftPositionDescriptor.flipRatio(DAI, WBTC, 1)).to.eq(true) - }) - - it('returns false if token1 is a numerator and token0 is a denominator', async () => { - expect(await nftPositionDescriptor.flipRatio(WBTC, DAI, 1)).to.eq(false) - }) - }) - - describe('#tokenURI', () => { - it('displays ETH as token symbol for WETH token', async () => { - const [token0, token1] = sortedTokens(weth9, tokens[1]) - await nft.createAndInitializePoolIfNecessary( - token0.address, - token1.address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - await weth9.approve(nft.address, 100) - await tokens[1].approve(nft.address, 100) - await nft.mint({ - token0: token0.address, - token1: token1.address, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - recipient: wallets[0].address, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - }) - - const metadata = extractJSONFromURI(await nft.tokenURI(1)) - expect(metadata.name).to.match(/(\sETH\/TEST|TEST\/ETH)/) - expect(metadata.description).to.match(/(TEST-ETH|\sETH-TEST)/) - expect(metadata.description).to.match(/(\nETH\sAddress)/) - }) - - it('displays returned token symbols when neither token is WETH ', async () => { - const [token0, token1] = sortedTokens(tokens[2], tokens[1]) - await nft.createAndInitializePoolIfNecessary( - token0.address, - token1.address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - await tokens[1].approve(nft.address, 100) - await tokens[2].approve(nft.address, 100) - await nft.mint({ - token0: token0.address, - token1: token1.address, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - recipient: wallets[0].address, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - }) - - const metadata = extractJSONFromURI(await nft.tokenURI(1)) - expect(metadata.name).to.match(/TEST\/TEST/) - expect(metadata.description).to.match(/TEST-TEST/) - }) - - it('can render a different label for native currencies', async () => { - const [token0, token1] = sortedTokens(weth9, tokens[1]) - await nft.createAndInitializePoolIfNecessary( - token0.address, - token1.address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - await weth9.approve(nft.address, 100) - await tokens[1].approve(nft.address, 100) - await nft.mint({ - token0: token0.address, - token1: token1.address, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - recipient: wallets[0].address, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - }) - - const nftDescriptorLibraryFactory = await ethers.getContractFactory('NFTDescriptor') - const nftDescriptorLibrary = await nftDescriptorLibraryFactory.deploy() - const positionDescriptorFactory = await ethers.getContractFactory('NonfungibleTokenPositionDescriptor', { - libraries: { - NFTDescriptor: nftDescriptorLibrary.address, - }, - }) - const nftDescriptor = (await positionDescriptorFactory.deploy( - weth9.address, - // 'FUNNYMONEY' as a bytes32 string - '0x46554e4e594d4f4e455900000000000000000000000000000000000000000000' - )) as NonfungibleTokenPositionDescriptor - - const metadata = extractJSONFromURI(await nftDescriptor.tokenURI(nft.address, 1)) - expect(metadata.name).to.match(/(\sFUNNYMONEY\/TEST|TEST\/FUNNYMONEY)/) - expect(metadata.description).to.match(/(TEST-FUNNYMONEY|\sFUNNYMONEY-TEST)/) - expect(metadata.description).to.match(/(\nFUNNYMONEY\sAddress)/) - }) - }) -}) diff --git a/lib/v3-periphery/test/OracleLibrary.spec.ts b/lib/v3-periphery/test/OracleLibrary.spec.ts deleted file mode 100644 index d15864e..0000000 --- a/lib/v3-periphery/test/OracleLibrary.spec.ts +++ /dev/null @@ -1,675 +0,0 @@ -import { expect } from 'chai' -import { ethers, waffle } from 'hardhat' -import { BigNumber, BigNumberish, constants, ContractFactory, Contract } from 'ethers' -import { OracleTest, TestERC20 } from '../typechain' -import { expandTo18Decimals } from './shared/expandTo18Decimals' -import snapshotGasCost from './shared/snapshotGasCost' - -describe('OracleLibrary', () => { - let loadFixture: ReturnType - let tokens: TestERC20[] - let oracle: OracleTest - - const BN0 = BigNumber.from(0) - - const oracleTestFixture = async () => { - const tokenFactory = await ethers.getContractFactory('TestERC20') - const tokens: [TestERC20, TestERC20, TestERC20] = [ - (await tokenFactory.deploy(constants.MaxUint256.div(2))) as TestERC20, // do not use maxu256 to avoid overflowing - (await tokenFactory.deploy(constants.MaxUint256.div(2))) as TestERC20, - (await tokenFactory.deploy(constants.MaxUint256.div(2))) as TestERC20, - ] - - tokens.sort((a, b) => (a.address.toLowerCase() < b.address.toLowerCase() ? -1 : 1)) - - const oracleFactory = await ethers.getContractFactory('OracleTest') - const oracle = await oracleFactory.deploy() - - return { - tokens: tokens as TestERC20[], - oracle: oracle as OracleTest, - } - } - - before('create fixture loader', async () => { - loadFixture = waffle.createFixtureLoader(await (ethers as any).getSigners()) - }) - - beforeEach('deploy fixture', async () => { - const fixtures = await loadFixture(oracleTestFixture) - tokens = fixtures['tokens'] - oracle = fixtures['oracle'] - }) - - describe('#consult', () => { - let mockObservableFactory: ContractFactory - - before('create mockObservableFactory', async () => { - mockObservableFactory = await ethers.getContractFactory('MockObservable') - }) - - it('reverts when period is 0', async () => { - await expect(oracle.consult(oracle.address, 0)).to.be.revertedWith('BP') - }) - - it('correct output when tick is 0', async () => { - const period = 3 - const secondsPerLiqCumulatives: [BigNumberish, BigNumberish] = [10, 20] - const mockObservable = await observableWith({ - period, - tickCumulatives: [12, 12], - secondsPerLiqCumulatives, - }) - const { arithmeticMeanTick, harmonicMeanLiquidity } = await oracle.consult(mockObservable.address, period) - - expect(arithmeticMeanTick).to.equal(0) - expect(harmonicMeanLiquidity).to.equal(calculateHarmonicAvgLiq(period, secondsPerLiqCumulatives)) - }) - - it('correct rounding for .5 negative tick', async () => { - const period = 4 - - const secondsPerLiqCumulatives: [BigNumberish, BigNumberish] = [10, 15] - const mockObservable = await observableWith({ - period, - tickCumulatives: [-10, -12], - secondsPerLiqCumulatives, - }) - - const { arithmeticMeanTick, harmonicMeanLiquidity } = await oracle.consult(mockObservable.address, period) - - // Always round to negative infinity - // In this case, we need to subtract one because integer division rounds to 0 - expect(arithmeticMeanTick).to.equal(-1) - expect(harmonicMeanLiquidity).to.equal(calculateHarmonicAvgLiq(period, secondsPerLiqCumulatives)) - }) - - it('correct output for liquidity overflow', async () => { - const period = 1 - - const secondsPerLiqCumulatives: [BigNumberish, BigNumberish] = [10, 11] - const mockObservable = await observableWith({ - period, - tickCumulatives: [12, 12], - secondsPerLiqCumulatives, - }) - - const { arithmeticMeanTick, harmonicMeanLiquidity } = await oracle.consult(mockObservable.address, period) - - expect(arithmeticMeanTick).to.equal(0) - // Make sure liquidity doesn't overflow uint128 - expect(harmonicMeanLiquidity).to.equal(BigNumber.from(2).pow(128).sub(1)) - }) - - function calculateHarmonicAvgLiq(period: number, secondsPerLiqCumulatives: [BigNumberish, BigNumberish]) { - const [secondsPerLiq0, secondsPerLiq1] = secondsPerLiqCumulatives.map(BigNumber.from) - const delta = secondsPerLiq1.sub(secondsPerLiq0) - - const maxUint160 = BigNumber.from(2).pow(160).sub(1) - return maxUint160.mul(period).div(delta.shl(32)) - } - - function observableWith({ - period, - tickCumulatives, - secondsPerLiqCumulatives, - }: { - period: number - tickCumulatives: [BigNumberish, BigNumberish] - secondsPerLiqCumulatives: [BigNumberish, BigNumberish] - }) { - return mockObservableFactory.deploy( - [period, 0], - tickCumulatives.map(BigNumber.from), - secondsPerLiqCumulatives.map(BigNumber.from) - ) - } - }) - - describe('#getQuoteAtTick', () => { - // sanity check - it('token0: returns correct value when tick = 0', async () => { - const quoteAmount = await oracle.getQuoteAtTick(BN0, expandTo18Decimals(1), tokens[0].address, tokens[1].address) - - expect(quoteAmount).to.equal(expandTo18Decimals(1)) - }) - - // sanity check - it('token1: returns correct value when tick = 0', async () => { - const quoteAmount = await oracle.getQuoteAtTick(BN0, expandTo18Decimals(1), tokens[1].address, tokens[0].address) - - expect(quoteAmount).to.equal(expandTo18Decimals(1)) - }) - - it('token0: returns correct value when at min tick | 0 < sqrtRatioX96 <= type(uint128).max', async () => { - const quoteAmount = await oracle.getQuoteAtTick( - BigNumber.from(-887272), - BigNumber.from(2).pow(128).sub(1), - tokens[0].address, - tokens[1].address - ) - expect(quoteAmount).to.equal(BigNumber.from('1')) - }) - - it('token1: returns correct value when at min tick | 0 < sqrtRatioX96 <= type(uint128).max', async () => { - const quoteAmount = await oracle.getQuoteAtTick( - BigNumber.from(-887272), - BigNumber.from(2).pow(128).sub(1), - tokens[1].address, - tokens[0].address - ) - expect(quoteAmount).to.equal( - BigNumber.from('115783384738768196242144082653949453838306988932806144552194799290216044976282') - ) - }) - - it('token0: returns correct value when at max tick | sqrtRatioX96 > type(uint128).max', async () => { - const quoteAmount = await oracle.getQuoteAtTick( - BigNumber.from(887272), - BigNumber.from(2).pow(128).sub(1), - tokens[0].address, - tokens[1].address - ) - expect(quoteAmount).to.equal( - BigNumber.from('115783384785599357996676985412062652720342362943929506828539444553934033845703') - ) - }) - - it('token1: returns correct value when at max tick | sqrtRatioX96 > type(uint128).max', async () => { - const quoteAmount = await oracle.getQuoteAtTick( - BigNumber.from(887272), - BigNumber.from(2).pow(128).sub(1), - tokens[1].address, - tokens[0].address - ) - expect(quoteAmount).to.equal(BigNumber.from('1')) - }) - - it('gas test', async () => { - await snapshotGasCost( - oracle.getGasCostOfGetQuoteAtTick( - BigNumber.from(10), - expandTo18Decimals(1), - tokens[0].address, - tokens[1].address - ) - ) - }) - }) - - describe('#getOldestObservationSecondsAgo', () => { - let mockObservationsFactory: ContractFactory - - // some empty tick values as this function does not use them - const emptySPL = [0, 0, 0, 0] - const emptyTickCumulatives = [0, 0, 0, 0] - const emptyTick = 0 - const emptyLiquidity = 0 - - // helper function to run each test case identically - const runOldestObservationsTest = async ( - blockTimestamps: number[], - initializeds: boolean[], - observationCardinality: number, - observationIndex: number - ) => { - const mockObservations = await mockObservationsFactory.deploy( - blockTimestamps, - emptyTickCumulatives, - emptySPL, - initializeds, - emptyTick, - observationCardinality, - observationIndex, - false, - emptyLiquidity - ) - - var result = await oracle.getOldestObservationSecondsAgo(mockObservations.address) - - //calculate seconds ago - var secondsAgo - if (initializeds[(observationIndex + 1) % observationCardinality]) { - secondsAgo = result['currentTimestamp'] - blockTimestamps[(observationIndex + 1) % observationCardinality] - } else { - secondsAgo = result['currentTimestamp'] - blockTimestamps[0] - } - - if (secondsAgo < 0) { - secondsAgo += 2 ** 32 - } - - expect(result['secondsAgo']).to.equal(secondsAgo) - } - - before('create mockObservationsFactory', async () => { - mockObservationsFactory = await ethers.getContractFactory('MockObservations') - }) - - it('fetches the oldest timestamp from the slot after observationIndex', async () => { - // set up test case - const blockTimestamps = [2, 3, 1, 0] - const initializeds = [true, true, true, false] - const observationCardinality = 3 - const observationIndex = 1 - - // run test - await runOldestObservationsTest(blockTimestamps, initializeds, observationCardinality, observationIndex) - }) - - it('loops to fetches the oldest timestamp from index 0', async () => { - // set up test case - const blockTimestamps = [1, 2, 3, 0] - const initializeds = [true, true, true, false] - const observationCardinality = 3 - const observationIndex = 2 - - // run test - await runOldestObservationsTest(blockTimestamps, initializeds, observationCardinality, observationIndex) - }) - - it('fetches from index 0 if the next index is uninitialized', async () => { - // set up test case - const blockTimestamps = [1, 2, 0, 0] - const initializeds = [true, true, false, false] - const observationCardinality = 4 - const observationIndex = 1 - - // run test - await runOldestObservationsTest(blockTimestamps, initializeds, observationCardinality, observationIndex) - }) - - it('reverts if the pool is not initialized', async () => { - const blockTimestamps = [0, 0, 0, 0] - const initializeds = [false, false, false, false] - const observationCardinality = 0 - const observationIndex = 0 - const mockObservations = await mockObservationsFactory.deploy( - blockTimestamps, - emptyTickCumulatives, - emptySPL, - initializeds, - emptyTick, - observationCardinality, - observationIndex, - false, - emptyLiquidity - ) - - await expect(oracle.getOldestObservationSecondsAgo(mockObservations.address)).to.be.revertedWith('NI') - }) - - it('fetches the correct timestamp when the timestamps overflow', async () => { - // set up test case - const maxUint32 = 2 ** 32 - 1 - const blockTimestamps = [maxUint32, 3, maxUint32 - 2, 0] - const initializeds = [true, true, true, false] - const observationCardinality = 3 - const observationIndex = 1 - - // run test - await runOldestObservationsTest(blockTimestamps, initializeds, observationCardinality, observationIndex) - }) - }) - - describe('#getBlockStartingTickAndLiquidity', () => { - let mockObservationsFactory: ContractFactory - let mockObservations: Contract - let blockTimestamps: number[] - let tickCumulatives: number[] - let liquidityValues: BigNumber[] - let initializeds: boolean[] - let slot0Tick: number - let observationCardinality: number - let observationIndex: number - let lastObservationCurrentTimestamp: boolean - let liquidity: number - - before('create mockObservationsFactory', async () => { - mockObservationsFactory = await ethers.getContractFactory('MockObservations') - }) - - const deployMockObservationsContract = async () => { - mockObservations = await mockObservationsFactory.deploy( - blockTimestamps, - tickCumulatives, - liquidityValues, - initializeds, - slot0Tick, - observationCardinality, - observationIndex, - lastObservationCurrentTimestamp, - liquidity - ) - } - - it('reverts if the pool is not initialized', async () => { - blockTimestamps = [0, 0, 0, 0] - tickCumulatives = [0, 0, 0, 0] - liquidityValues = [BN0, BN0, BN0, BN0] - initializeds = [false, false, false, false] - slot0Tick = 0 - observationCardinality = 0 - observationIndex = 0 - lastObservationCurrentTimestamp = false - liquidity = 0 - - await deployMockObservationsContract() - - await expect(oracle.getBlockStartingTickAndLiquidity(mockObservations.address)).to.be.revertedWith('NEO') - }) - - it('returns the tick and liquidity in storage if the latest observation was in a previous block', async () => { - blockTimestamps = [1, 3, 4, 0] - // 0 - // 8: 0 + (4*(3-1)) - // 13: 8 + (5*(4-3)) - tickCumulatives = [0, 8, 13, 0] - // 0 - // (1): 0 + ((3-1)*2**128)/5000 - // (1) + ((4-3)*2**128)/7000 - liquidityValues = [ - BN0, - BigNumber.from('136112946768375385385349842972707284'), - BigNumber.from('184724713471366594451546215462959885'), - BN0, - ] - initializeds = [true, true, true, false] - observationCardinality = 3 - observationIndex = 2 - slot0Tick = 6 - lastObservationCurrentTimestamp = false - liquidity = 10000 - - await deployMockObservationsContract() - - var result = await oracle.getBlockStartingTickAndLiquidity(mockObservations.address) - expect(result[0]).to.equal(slot0Tick) - expect(result[1]).to.equal(liquidity) - }) - - it('reverts if it needs 2 observations and doesnt have them', async () => { - blockTimestamps = [1, 0, 0, 0] - tickCumulatives = [8, 0, 0, 0] - liquidityValues = [BigNumber.from('136112946768375385385349842972707284'), BN0, BN0, BN0] - initializeds = [true, false, false, false] - observationCardinality = 1 - observationIndex = 0 - slot0Tick = 4 - lastObservationCurrentTimestamp = true - liquidity = 10000 - - await deployMockObservationsContract() - - await expect(oracle.getBlockStartingTickAndLiquidity(mockObservations.address)).to.be.revertedWith('NEO') - }) - - it('reverts if the prior observation needed is not initialized', async () => { - blockTimestamps = [1, 0, 0, 0] - observationCardinality = 2 - observationIndex = 0 - liquidityValues = [BigNumber.from('136112946768375385385349842972707284'), BN0, BN0, BN0] - initializeds = [true, false, false, false] - tickCumulatives = [8, 0, 0, 0] - slot0Tick = 4 - lastObservationCurrentTimestamp = true - - await deployMockObservationsContract() - - await expect(oracle.getBlockStartingTickAndLiquidity(mockObservations.address)).to.be.revertedWith('ONI') - }) - - it('calculates the prior tick and liquidity from the prior observations', async () => { - blockTimestamps = [9, 5, 8, 0] - observationCardinality = 3 - observationIndex = 0 - initializeds = [true, true, true, false] - // 99: 95 + (4*1) - // 80: 72 + (4*2) - // 95: 80 + (5*3) - tickCumulatives = [99, 80, 95, 0] - // prev: 784724713471366594451546215462959885 - // (3): (2) + (1*2**128)/13212 - // (1): prev + (2*2**128)/12345 - // (2): (1) + (3*2**128)/10238 - liquidityValues = [ - BigNumber.from('965320616647837491242414421221086683'), - BigNumber.from('839853488995212437053956034406948254'), - BigNumber.from('939565063595995342933046073701273770'), - BN0, - ] - slot0Tick = 3 - lastObservationCurrentTimestamp = true - - await deployMockObservationsContract() - - var result = await oracle.getBlockStartingTickAndLiquidity(mockObservations.address) - - var actualStartingTick = (tickCumulatives[0] - tickCumulatives[2]) / (blockTimestamps[0] - blockTimestamps[2]) - expect(result[0]).to.equal(actualStartingTick) - - var actualStartingLiquidity = 13212 // see comments above - expect(result[1]).to.equal(actualStartingLiquidity) - }) - }) - - describe('#getWeightedArithmeticMeanTick', () => { - it('single observation returns average tick', async () => { - const observation = { tick: 10, weight: 10 } - - const oracleTick = await oracle.getWeightedArithmeticMeanTick([observation]) - - expect(oracleTick).to.equal(10) - }) - - it('multiple observations with same weight result in average across tiers', async () => { - const observation1 = { tick: 10, weight: 10 } - const observation2 = { tick: 20, weight: 10 } - - const oracleTick = await oracle.getWeightedArithmeticMeanTick([observation1, observation2]) - - expect(oracleTick).to.equal(15) - }) - - it('multiple observations with different weights are weighted correctly', async () => { - const observation2 = { tick: 20, weight: 15 } - const observation1 = { tick: 10, weight: 10 } - - const oracleTick = await oracle.getWeightedArithmeticMeanTick([observation1, observation2]) - - expect(oracleTick).to.equal(16) - }) - - it('correct rounding for .5 negative tick', async () => { - const observation1 = { tick: -10, weight: 10 } - const observation2 = { tick: -11, weight: 10 } - - const oracleTick = await oracle.getWeightedArithmeticMeanTick([observation1, observation2]) - - expect(oracleTick).to.equal(-11) - }) - }) - describe('#getChainedPrice', () => { - let ticks: number[] - - it('fails with discrepant length', async () => { - const tokenAddresses = [tokens[0].address, tokens[2].address] - ticks = [5, 5] - - expect(oracle.getChainedPrice(tokenAddresses, ticks)).to.be.revertedWith('DL') - }) - it('add two positive ticks, sorted order', async () => { - const tokenAddresses = [tokens[0].address, tokens[1].address, tokens[2].address] - ticks = [5, 5] - const oracleTick = await oracle.getChainedPrice(tokenAddresses, ticks) - - expect(oracleTick).to.equal(10) - }) - it('add one positive and one negative tick, sorted order', async () => { - const tokenAddresses = [tokens[0].address, tokens[1].address, tokens[2].address] - ticks = [5, -5] - const oracleTick = await oracle.getChainedPrice(tokenAddresses, ticks) - - expect(oracleTick).to.equal(0) - }) - it('add one negative and one positive tick, sorted order', async () => { - const tokenAddresses = [tokens[0].address, tokens[1].address, tokens[2].address] - ticks = [-5, 5] - const oracleTick = await oracle.getChainedPrice(tokenAddresses, ticks) - - expect(oracleTick).to.equal(0) - }) - it('add two negative ticks, sorted order', async () => { - const tokenAddresses = [tokens[0].address, tokens[1].address, tokens[2].address] - ticks = [-5, -5] - const oracleTick = await oracle.getChainedPrice(tokenAddresses, ticks) - - expect(oracleTick).to.equal(-10) - }) - - it('add two positive ticks, token0/token1 + token1/token0', async () => { - const tokenAddresses = [tokens[0].address, tokens[2].address, tokens[1].address] - ticks = [5, 5] - const oracleTick = await oracle.getChainedPrice(tokenAddresses, ticks) - - expect(oracleTick).to.equal(0) - }) - it('add one positive tick and one negative tick, token0/token1 + token1/token0', async () => { - const tokenAddresses = [tokens[0].address, tokens[2].address, tokens[1].address] - ticks = [5, -5] - const oracleTick = await oracle.getChainedPrice(tokenAddresses, ticks) - - expect(oracleTick).to.equal(10) - }) - it('add one negative tick and one positive tick, token0/token1 + token1/token0', async () => { - const tokenAddresses = [tokens[0].address, tokens[2].address, tokens[1].address] - ticks = [-5, 5] - const oracleTick = await oracle.getChainedPrice(tokenAddresses, ticks) - - expect(oracleTick).to.equal(-10) - }) - it('add two negative ticks, token0/token1 + token1/token0', async () => { - const tokenAddresses = [tokens[0].address, tokens[2].address, tokens[1].address] - ticks = [-5, -5] - const oracleTick = await oracle.getChainedPrice(tokenAddresses, ticks) - - expect(oracleTick).to.equal(0) - }) - - it('add two positive ticks, token1/token0 + token0/token1', async () => { - const tokenAddresses = [tokens[1].address, tokens[0].address, tokens[2].address] - ticks = [5, 5] - const oracleTick = await oracle.getChainedPrice(tokenAddresses, ticks) - - expect(oracleTick).to.equal(0) - }) - it('add one positive tick and one negative tick, token1/token0 + token0/token1', async () => { - const tokenAddresses = [tokens[1].address, tokens[0].address, tokens[2].address] - ticks = [5, -5] - const oracleTick = await oracle.getChainedPrice(tokenAddresses, ticks) - - expect(oracleTick).to.equal(-10) - }) - it('add one negative tick and one positive tick, token1/token0 + token0/token1', async () => { - const tokenAddresses = [tokens[1].address, tokens[0].address, tokens[2].address] - ticks = [-5, 5] - const oracleTick = await oracle.getChainedPrice(tokenAddresses, ticks) - - expect(oracleTick).to.equal(10) - }) - it('add two negative ticks, token1/token0 + token0/token1', async () => { - const tokenAddresses = [tokens[1].address, tokens[0].address, tokens[2].address] - ticks = [-5, -5] - const oracleTick = await oracle.getChainedPrice(tokenAddresses, ticks) - - expect(oracleTick).to.equal(0) - }) - - it('add two positive ticks, token0/token1 + token1/token0', async () => { - const tokenAddresses = [tokens[1].address, tokens[2].address, tokens[0].address] - ticks = [5, 5] - const oracleTick = await oracle.getChainedPrice(tokenAddresses, ticks) - - expect(oracleTick).to.equal(0) - }) - it('add one positive tick and one negative tick, token0/token1 + token1/token0', async () => { - const tokenAddresses = [tokens[1].address, tokens[2].address, tokens[0].address] - ticks = [5, -5] - const oracleTick = await oracle.getChainedPrice(tokenAddresses, ticks) - - expect(oracleTick).to.equal(10) - }) - it('add one negative tick and one positive tick, token0/token1 + token1/token0', async () => { - const tokenAddresses = [tokens[1].address, tokens[2].address, tokens[0].address] - ticks = [-5, 5] - const oracleTick = await oracle.getChainedPrice(tokenAddresses, ticks) - - expect(oracleTick).to.equal(-10) - }) - it('add two negative ticks, token0/token1 + token1/token0', async () => { - const tokenAddresses = [tokens[1].address, tokens[2].address, tokens[0].address] - ticks = [-5, -5] - const oracleTick = await oracle.getChainedPrice(tokenAddresses, ticks) - - expect(oracleTick).to.equal(0) - }) - - it('add two positive ticks, token1/token0 + token0/token1', async () => { - const tokenAddresses = [tokens[2].address, tokens[0].address, tokens[1].address] - ticks = [5, 5] - const oracleTick = await oracle.getChainedPrice(tokenAddresses, ticks) - - expect(oracleTick).to.equal(0) - }) - it('add one positive tick and one negative tick, token1/token0 + token0/token1', async () => { - const tokenAddresses = [tokens[2].address, tokens[0].address, tokens[1].address] - ticks = [5, -5] - const oracleTick = await oracle.getChainedPrice(tokenAddresses, ticks) - - expect(oracleTick).to.equal(-10) - }) - it('add one negative tick and one positive tick, token1/token0 + token0/token1', async () => { - const tokenAddresses = [tokens[2].address, tokens[0].address, tokens[1].address] - ticks = [-5, 5] - const oracleTick = await oracle.getChainedPrice(tokenAddresses, ticks) - - expect(oracleTick).to.equal(10) - }) - it('add two negative ticks, token1/token0 + token0/token1', async () => { - const tokenAddresses = [tokens[2].address, tokens[0].address, tokens[1].address] - ticks = [-5, -5] - const oracleTick = await oracle.getChainedPrice(tokenAddresses, ticks) - - expect(oracleTick).to.equal(0) - }) - - it('add two positive ticks, token1/token0 + token1/token0', async () => { - const tokenAddresses = [tokens[2].address, tokens[1].address, tokens[0].address] - ticks = [5, 5] - const oracleTick = await oracle.getChainedPrice(tokenAddresses, ticks) - - expect(oracleTick).to.equal(-10) - }) - it('add one positive tick and one negative tick, token1/token0 + token1/token0', async () => { - const tokenAddresses = [tokens[2].address, tokens[1].address, tokens[0].address] - ticks = [5, -5] - const oracleTick = await oracle.getChainedPrice(tokenAddresses, ticks) - - expect(oracleTick).to.equal(0) - }) - it('add one negative tick and one positive tick, token1/token0 + token1/token0', async () => { - const tokenAddresses = [tokens[2].address, tokens[1].address, tokens[0].address] - ticks = [-5, 5] - const oracleTick = await oracle.getChainedPrice(tokenAddresses, ticks) - - expect(oracleTick).to.equal(0) - }) - it('add two negative ticks, token1/token0 + token1/token0', async () => { - const tokenAddresses = [tokens[2].address, tokens[1].address, tokens[0].address] - ticks = [-5, -5] - const oracleTick = await oracle.getChainedPrice(tokenAddresses, ticks) - - expect(oracleTick).to.equal(10) - }) - }) -}) diff --git a/lib/v3-periphery/test/PairFlash.spec.ts b/lib/v3-periphery/test/PairFlash.spec.ts deleted file mode 100644 index b6084ed..0000000 --- a/lib/v3-periphery/test/PairFlash.spec.ts +++ /dev/null @@ -1,168 +0,0 @@ -import { ethers, waffle } from 'hardhat' -import { BigNumber, constants, Contract, ContractTransaction } from 'ethers' -import { - IWETH9, - MockTimeNonfungiblePositionManager, - MockTimeSwapRouter, - PairFlash, - IUniswapV3Pool, - TestERC20, - TestERC20Metadata, - IUniswapV3Factory, - NFTDescriptor, - Quoter, - SwapRouter, -} from '../typechain' -import completeFixture from './shared/completeFixture' -import { FeeAmount, MaxUint128, TICK_SPACINGS } from './shared/constants' -import { encodePriceSqrt } from './shared/encodePriceSqrt' -import snapshotGasCost from './shared/snapshotGasCost' - -import { expect } from './shared/expect' -import { getMaxTick, getMinTick } from './shared/ticks' -import { computePoolAddress } from './shared/computePoolAddress' - -describe('PairFlash test', () => { - const provider = waffle.provider - const wallets = waffle.provider.getWallets() - const wallet = wallets[0] - - let flash: PairFlash - let nft: MockTimeNonfungiblePositionManager - let token0: TestERC20 - let token1: TestERC20 - let factory: IUniswapV3Factory - let quoter: Quoter - - async function createPool(tokenAddressA: string, tokenAddressB: string, fee: FeeAmount, price: BigNumber) { - if (tokenAddressA.toLowerCase() > tokenAddressB.toLowerCase()) - [tokenAddressA, tokenAddressB] = [tokenAddressB, tokenAddressA] - - await nft.createAndInitializePoolIfNecessary(tokenAddressA, tokenAddressB, fee, price) - - const liquidityParams = { - token0: tokenAddressA, - token1: tokenAddressB, - fee: fee, - tickLower: getMinTick(TICK_SPACINGS[fee]), - tickUpper: getMaxTick(TICK_SPACINGS[fee]), - recipient: wallet.address, - amount0Desired: 1000000, - amount1Desired: 1000000, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - } - - return nft.mint(liquidityParams) - } - - const flashFixture = async () => { - const { router, tokens, factory, weth9, nft } = await completeFixture(wallets, provider) - const token0 = tokens[0] - const token1 = tokens[1] - - const flashContractFactory = await ethers.getContractFactory('PairFlash') - const flash = (await flashContractFactory.deploy(router.address, factory.address, weth9.address)) as PairFlash - - const quoterFactory = await ethers.getContractFactory('Quoter') - const quoter = (await quoterFactory.deploy(factory.address, weth9.address)) as Quoter - - return { - token0, - token1, - flash, - factory, - weth9, - nft, - quoter, - router, - } - } - - let loadFixture: ReturnType - - before('create fixture loader', async () => { - loadFixture = waffle.createFixtureLoader(wallets) - }) - - beforeEach('load fixture', async () => { - ;({ factory, token0, token1, flash, nft, quoter } = await loadFixture(flashFixture)) - - await token0.approve(nft.address, MaxUint128) - await token1.approve(nft.address, MaxUint128) - await createPool(token0.address, token1.address, FeeAmount.LOW, encodePriceSqrt(5, 10)) - await createPool(token0.address, token1.address, FeeAmount.MEDIUM, encodePriceSqrt(1, 1)) - await createPool(token0.address, token1.address, FeeAmount.HIGH, encodePriceSqrt(20, 10)) - }) - - describe('flash', () => { - it('test correct transfer events', async () => { - //choose amountIn to test - const amount0In = 1000 - const amount1In = 1000 - - const fee0 = Math.ceil((amount0In * FeeAmount.MEDIUM) / 1000000) - const fee1 = Math.ceil((amount1In * FeeAmount.MEDIUM) / 1000000) - - const flashParams = { - token0: token0.address, - token1: token1.address, - fee1: FeeAmount.MEDIUM, - amount0: amount0In, - amount1: amount1In, - fee2: FeeAmount.LOW, - fee3: FeeAmount.HIGH, - } - // pool1 is the borrow pool - const pool1 = computePoolAddress(factory.address, [token0.address, token1.address], FeeAmount.MEDIUM) - const pool2 = computePoolAddress(factory.address, [token0.address, token1.address], FeeAmount.LOW) - const pool3 = computePoolAddress(factory.address, [token0.address, token1.address], FeeAmount.HIGH) - - const expectedAmountOut0 = await quoter.callStatic.quoteExactInputSingle( - token1.address, - token0.address, - FeeAmount.LOW, - amount1In, - encodePriceSqrt(20, 10) - ) - const expectedAmountOut1 = await quoter.callStatic.quoteExactInputSingle( - token0.address, - token1.address, - FeeAmount.HIGH, - amount0In, - encodePriceSqrt(5, 10) - ) - - await expect(flash.initFlash(flashParams)) - .to.emit(token0, 'Transfer') - .withArgs(pool1, flash.address, amount0In) - .to.emit(token1, 'Transfer') - .withArgs(pool1, flash.address, amount1In) - .to.emit(token0, 'Transfer') - .withArgs(pool2, flash.address, expectedAmountOut0) - .to.emit(token1, 'Transfer') - .withArgs(pool3, flash.address, expectedAmountOut1) - .to.emit(token0, 'Transfer') - .withArgs(flash.address, wallet.address, expectedAmountOut0.toNumber() - amount0In - fee0) - .to.emit(token1, 'Transfer') - .withArgs(flash.address, wallet.address, expectedAmountOut1.toNumber() - amount1In - fee1) - }) - - it('gas', async () => { - const amount0In = 1000 - const amount1In = 1000 - - const flashParams = { - token0: token0.address, - token1: token1.address, - fee1: FeeAmount.MEDIUM, - amount0: amount0In, - amount1: amount1In, - fee2: FeeAmount.LOW, - fee3: FeeAmount.HIGH, - } - await snapshotGasCost(flash.initFlash(flashParams)) - }) - }) -}) diff --git a/lib/v3-periphery/test/Path.spec.ts b/lib/v3-periphery/test/Path.spec.ts deleted file mode 100644 index ba6dc95..0000000 --- a/lib/v3-periphery/test/Path.spec.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { waffle, ethers } from 'hardhat' -import { FeeAmount } from './shared/constants' - -import { expect } from './shared/expect' - -import { PathTest } from '../typechain' -import { decodePath, encodePath } from './shared/path' - -import snapshotGasCost from './shared/snapshotGasCost' - -describe('Path', () => { - let path: PathTest - - let tokenAddresses = [ - '0x5FC8d32690cc91D4c39d9d3abcBD16989F875707', - '0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9', - '0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9', - ] - let fees = [FeeAmount.MEDIUM, FeeAmount.MEDIUM] - - const pathTestFixture = async () => { - const pathTestFactory = await ethers.getContractFactory('PathTest') - return (await pathTestFactory.deploy()) as PathTest - } - - let loadFixture: ReturnType - - before('create fixture loader', async () => { - loadFixture = waffle.createFixtureLoader(await (ethers as any).getSigners()) - }) - - beforeEach('deploy PathTest', async () => { - path = await loadFixture(pathTestFixture) - }) - - it('js encoding works as expected', async () => { - let expectedPath = - '0x' + - tokenAddresses - .slice(0, 2) - .map((tokenAddress) => tokenAddress.slice(2).toLowerCase()) - .join('000bb8') - expect(encodePath(tokenAddresses.slice(0, 2), fees.slice(0, 1))).to.eq(expectedPath) - - expectedPath = '0x' + tokenAddresses.map((tokenAddress) => tokenAddress.slice(2).toLowerCase()).join('000bb8') - expect(encodePath(tokenAddresses, fees)).to.eq(expectedPath) - }) - - it('js decoding works as expected', async () => { - const encodedPath = encodePath(tokenAddresses, fees) - const [decodedTokens, decodedFees] = decodePath(encodedPath) - expect(decodedTokens).to.deep.eq(tokenAddresses) - expect(decodedFees).to.deep.eq(fees) - }) - - describe('#hasMultiplePools / #decodeFirstPool / #skipToken / #getFirstPool', () => { - const encodedPath = encodePath(tokenAddresses, fees) - - it('works on first pool', async () => { - expect(await path.hasMultiplePools(encodedPath)).to.be.true - - const firstPool = await path.decodeFirstPool(encodedPath) - expect(firstPool.tokenA).to.be.eq(tokenAddresses[0]) - expect(firstPool.tokenB).to.be.eq(tokenAddresses[1]) - expect(firstPool.fee).to.be.eq(FeeAmount.MEDIUM) - - expect(await path.decodeFirstPool(await path.getFirstPool(encodedPath))).to.deep.eq(firstPool) - }) - - const offset = 20 + 3 - - it('skips 1 item', async () => { - const skipped = await path.skipToken(encodedPath) - expect(skipped).to.be.eq('0x' + encodedPath.slice(2 + offset * 2)) - - expect(await path.hasMultiplePools(skipped)).to.be.false - - const { tokenA, tokenB, fee: decodedFee } = await path.decodeFirstPool(skipped) - expect(tokenA).to.be.eq(tokenAddresses[1]) - expect(tokenB).to.be.eq(tokenAddresses[2]) - expect(decodedFee).to.be.eq(FeeAmount.MEDIUM) - }) - }) - - it('gas cost', async () => { - await snapshotGasCost( - path.getGasCostOfDecodeFirstPool(encodePath([tokenAddresses[0], tokenAddresses[1]], [FeeAmount.MEDIUM])) - ) - }) -}) diff --git a/lib/v3-periphery/test/PeripheryImmutableState.spec.ts b/lib/v3-periphery/test/PeripheryImmutableState.spec.ts deleted file mode 100644 index f077e3a..0000000 --- a/lib/v3-periphery/test/PeripheryImmutableState.spec.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Contract } from 'ethers' -import { waffle, ethers } from 'hardhat' - -import { Fixture } from 'ethereum-waffle' -import { PeripheryImmutableStateTest, IWETH9 } from '../typechain' -import { expect } from './shared/expect' -import { v3RouterFixture } from './shared/externalFixtures' - -describe('PeripheryImmutableState', () => { - const nonfungiblePositionManagerFixture: Fixture<{ - weth9: IWETH9 - factory: Contract - state: PeripheryImmutableStateTest - }> = async (wallets, provider) => { - const { weth9, factory } = await v3RouterFixture(wallets, provider) - - const stateFactory = await ethers.getContractFactory('PeripheryImmutableStateTest') - const state = (await stateFactory.deploy(factory.address, weth9.address)) as PeripheryImmutableStateTest - - return { - weth9, - factory, - state, - } - } - - let factory: Contract - let weth9: IWETH9 - let state: PeripheryImmutableStateTest - - let loadFixture: ReturnType - - before('create fixture loader', async () => { - loadFixture = waffle.createFixtureLoader(await (ethers as any).getSigners()) - }) - - beforeEach('load fixture', async () => { - ;({ state, weth9, factory } = await loadFixture(nonfungiblePositionManagerFixture)) - }) - - it('bytecode size', async () => { - expect(((await state.provider.getCode(state.address)).length - 2) / 2).to.matchSnapshot() - }) - - describe('#WETH9', () => { - it('points to WETH9', async () => { - expect(await state.WETH9()).to.eq(weth9.address) - }) - }) - - describe('#factory', () => { - it('points to v3 core factory', async () => { - expect(await state.factory()).to.eq(factory.address) - }) - }) -}) diff --git a/lib/v3-periphery/test/PoolAddress.spec.ts b/lib/v3-periphery/test/PoolAddress.spec.ts deleted file mode 100644 index 9c83481..0000000 --- a/lib/v3-periphery/test/PoolAddress.spec.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { constants } from 'ethers' -import { waffle, ethers } from 'hardhat' - -import { PoolAddressTest } from '../typechain' -import { POOL_BYTECODE_HASH } from './shared/computePoolAddress' -import { expect } from './shared/expect' -import snapshotGasCost from './shared/snapshotGasCost' - -describe('PoolAddress', () => { - let poolAddress: PoolAddressTest - - const poolAddressTestFixture = async () => { - const poolAddressTestFactory = await ethers.getContractFactory('PoolAddressTest') - return (await poolAddressTestFactory.deploy()) as PoolAddressTest - } - - let loadFixture: ReturnType - - before('create fixture loader', async () => { - loadFixture = waffle.createFixtureLoader(await (ethers as any).getSigners()) - }) - - beforeEach('deploy PoolAddressTest', async () => { - poolAddress = await loadFixture(poolAddressTestFixture) - }) - - describe('#POOL_INIT_CODE_HASH', () => { - it('equals the hash of the pool bytecode', async () => { - expect(await poolAddress.POOL_INIT_CODE_HASH()).to.eq(POOL_BYTECODE_HASH) - }) - }) - - describe('#computeAddress', () => { - it('all arguments equal zero', async () => { - await expect(poolAddress.computeAddress(constants.AddressZero, constants.AddressZero, constants.AddressZero, 0)) - .to.be.reverted - }) - - it('matches example from core repo', async () => { - expect( - await poolAddress.computeAddress( - '0x5FbDB2315678afecb367f032d93F642f64180aa3', - '0x1000000000000000000000000000000000000000', - '0x2000000000000000000000000000000000000000', - 250 - ) - ).to.matchSnapshot() - }) - - it('token argument order cannot be in reverse', async () => { - await expect( - poolAddress.computeAddress( - '0x5FbDB2315678afecb367f032d93F642f64180aa3', - '0x2000000000000000000000000000000000000000', - '0x1000000000000000000000000000000000000000', - 3000 - ) - ).to.be.reverted - }) - - it('gas cost', async () => { - await snapshotGasCost( - poolAddress.getGasCostOfComputeAddress( - '0x5FbDB2315678afecb367f032d93F642f64180aa3', - '0x1000000000000000000000000000000000000000', - '0x2000000000000000000000000000000000000000', - 3000 - ) - ) - }) - }) -}) diff --git a/lib/v3-periphery/test/PoolTicksCounter.spec.ts b/lib/v3-periphery/test/PoolTicksCounter.spec.ts deleted file mode 100644 index 5be0ce0..0000000 --- a/lib/v3-periphery/test/PoolTicksCounter.spec.ts +++ /dev/null @@ -1,280 +0,0 @@ -import { waffle, ethers, artifacts } from 'hardhat' - -import { expect } from './shared/expect' - -import { PoolTicksCounterTest } from '../typechain' -import { deployMockContract, Fixture, MockContract } from 'ethereum-waffle' -import { Artifact } from 'hardhat/types' - -describe('PoolTicksCounter', () => { - const TICK_SPACINGS = [200, 60, 10] - - TICK_SPACINGS.forEach((TICK_SPACING) => { - let PoolTicksCounter: PoolTicksCounterTest - let pool: MockContract - let PoolAbi: Artifact - - // Bit index to tick - const bitIdxToTick = (idx: number, page = 0) => { - return idx * TICK_SPACING + page * 256 * TICK_SPACING - } - - before(async () => { - const wallets = await (ethers as any).getSigners() - PoolAbi = await artifacts.readArtifact('IUniswapV3Pool') - const poolTicksHelperFactory = await ethers.getContractFactory('PoolTicksCounterTest') - PoolTicksCounter = (await poolTicksHelperFactory.deploy()) as PoolTicksCounterTest - pool = await deployMockContract(wallets[0], PoolAbi.abi) - await pool.mock.tickSpacing.returns(TICK_SPACING) - }) - - describe(`[Tick Spacing: ${TICK_SPACING}]: tick after is bigger`, async () => { - it('same tick initialized', async () => { - await pool.mock.tickBitmap.withArgs(0).returns(0b1100) // 1100 - const result = await PoolTicksCounter.countInitializedTicksCrossed( - pool.address, - bitIdxToTick(2), - bitIdxToTick(2) - ) - expect(result).to.be.eq(1) - }) - - it('same tick not-initialized', async () => { - await pool.mock.tickBitmap.withArgs(0).returns(0b1100) // 1100 - const result = await PoolTicksCounter.countInitializedTicksCrossed( - pool.address, - bitIdxToTick(1), - bitIdxToTick(1) - ) - expect(result).to.be.eq(0) - }) - - it('same page', async () => { - await pool.mock.tickBitmap.withArgs(0).returns(0b1100) // 1100 - const result = await PoolTicksCounter.countInitializedTicksCrossed( - pool.address, - bitIdxToTick(0), - bitIdxToTick(255) - ) - expect(result).to.be.eq(2) - }) - - it('multiple pages', async () => { - await pool.mock.tickBitmap.withArgs(0).returns(0b1100) // 1100 - await pool.mock.tickBitmap.withArgs(1).returns(0b1101) // 1101 - const result = await PoolTicksCounter.countInitializedTicksCrossed( - pool.address, - bitIdxToTick(0), - bitIdxToTick(255, 1) - ) - expect(result).to.be.eq(5) - }) - - it('counts all ticks in a page except ending tick', async () => { - await pool.mock.tickBitmap.withArgs(0).returns(ethers.constants.MaxUint256) - await pool.mock.tickBitmap.withArgs(1).returns(0x0) - const result = await PoolTicksCounter.countInitializedTicksCrossed( - pool.address, - bitIdxToTick(0), - bitIdxToTick(255, 1) - ) - expect(result).to.be.eq(255) - }) - - it('counts ticks to left of start and right of end on same page', async () => { - await pool.mock.tickBitmap.withArgs(0).returns(0b1111000100001111) - const result = await PoolTicksCounter.countInitializedTicksCrossed( - pool.address, - bitIdxToTick(8), - bitIdxToTick(255) - ) - expect(result).to.be.eq(4) - }) - - it('counts ticks to left of start and right of end across on multiple pages', async () => { - await pool.mock.tickBitmap.withArgs(0).returns(0b1111000100001111) - await pool.mock.tickBitmap.withArgs(1).returns(0b1111000100001111) - const result = await PoolTicksCounter.countInitializedTicksCrossed( - pool.address, - bitIdxToTick(8), - bitIdxToTick(8, 1) - ) - expect(result).to.be.eq(9) - }) - - it('counts ticks when before and after are initialized on same page', async () => { - await pool.mock.tickBitmap.withArgs(0).returns(0b11111100) - const startingTickInit = await PoolTicksCounter.countInitializedTicksCrossed( - pool.address, - bitIdxToTick(2), - bitIdxToTick(255) - ) - expect(startingTickInit).to.be.eq(5) - const endingTickInit = await PoolTicksCounter.countInitializedTicksCrossed( - pool.address, - bitIdxToTick(0), - bitIdxToTick(3) - ) - expect(endingTickInit).to.be.eq(2) - const bothInit = await PoolTicksCounter.countInitializedTicksCrossed( - pool.address, - bitIdxToTick(2), - bitIdxToTick(5) - ) - expect(bothInit).to.be.eq(3) - }) - - it('counts ticks when before and after are initialized on multiple page', async () => { - await pool.mock.tickBitmap.withArgs(0).returns(0b11111100) - await pool.mock.tickBitmap.withArgs(1).returns(0b11111100) - const startingTickInit = await PoolTicksCounter.countInitializedTicksCrossed( - pool.address, - bitIdxToTick(2), - bitIdxToTick(255) - ) - expect(startingTickInit).to.be.eq(5) - const endingTickInit = await PoolTicksCounter.countInitializedTicksCrossed( - pool.address, - bitIdxToTick(0), - bitIdxToTick(3, 1) - ) - expect(endingTickInit).to.be.eq(8) - const bothInit = await PoolTicksCounter.countInitializedTicksCrossed( - pool.address, - bitIdxToTick(2), - bitIdxToTick(5, 1) - ) - expect(bothInit).to.be.eq(9) - }) - - it('counts ticks with lots of pages', async () => { - await pool.mock.tickBitmap.withArgs(0).returns(0b11111100) - await pool.mock.tickBitmap.withArgs(1).returns(0b11111111) - await pool.mock.tickBitmap.withArgs(2).returns(0x0) - await pool.mock.tickBitmap.withArgs(3).returns(0x0) - await pool.mock.tickBitmap.withArgs(4).returns(0b11111100) - - const bothInit = await PoolTicksCounter.countInitializedTicksCrossed( - pool.address, - bitIdxToTick(4), - bitIdxToTick(5, 4) - ) - expect(bothInit).to.be.eq(15) - }) - }) - - describe(`[Tick Spacing: ${TICK_SPACING}]: tick after is smaller`, async () => { - it('same page', async () => { - await pool.mock.tickBitmap.withArgs(0).returns(0b1100) - const result = await PoolTicksCounter.countInitializedTicksCrossed( - pool.address, - bitIdxToTick(255), - bitIdxToTick(0) - ) - expect(result).to.be.eq(2) - }) - - it('multiple pages', async () => { - await pool.mock.tickBitmap.withArgs(0).returns(0b1100) - await pool.mock.tickBitmap.withArgs(-1).returns(0b1100) - const result = await PoolTicksCounter.countInitializedTicksCrossed( - pool.address, - bitIdxToTick(255), - bitIdxToTick(0, -1) - ) - expect(result).to.be.eq(4) - }) - - it('counts all ticks in a page', async () => { - await pool.mock.tickBitmap.withArgs(0).returns(ethers.constants.MaxUint256) - await pool.mock.tickBitmap.withArgs(-1).returns(0x0) - const result = await PoolTicksCounter.countInitializedTicksCrossed( - pool.address, - bitIdxToTick(255), - bitIdxToTick(0, -1) - ) - expect(result).to.be.eq(256) - }) - - it('counts ticks to right of start and left of end on same page', async () => { - await pool.mock.tickBitmap.withArgs(0).returns(0b1111000100001111) - const result = await PoolTicksCounter.countInitializedTicksCrossed( - pool.address, - bitIdxToTick(15), - bitIdxToTick(2) - ) - expect(result).to.be.eq(6) - }) - - it('counts ticks to right of start and left of end on multiple pages', async () => { - await pool.mock.tickBitmap.withArgs(0).returns(0b1111000100001111) - await pool.mock.tickBitmap.withArgs(-1).returns(0b1111000100001111) - const result = await PoolTicksCounter.countInitializedTicksCrossed( - pool.address, - bitIdxToTick(8), - bitIdxToTick(8, -1) - ) - expect(result).to.be.eq(9) - }) - - it('counts ticks when before and after are initialized on same page', async () => { - await pool.mock.tickBitmap.withArgs(0).returns(0b11111100) - const startingTickInit = await PoolTicksCounter.countInitializedTicksCrossed( - pool.address, - bitIdxToTick(3), - bitIdxToTick(0) - ) - expect(startingTickInit).to.be.eq(2) - const endingTickInit = await PoolTicksCounter.countInitializedTicksCrossed( - pool.address, - bitIdxToTick(255), - bitIdxToTick(2) - ) - expect(endingTickInit).to.be.eq(5) - const bothInit = await PoolTicksCounter.countInitializedTicksCrossed( - pool.address, - bitIdxToTick(5), - bitIdxToTick(2) - ) - expect(bothInit).to.be.eq(3) - }) - - it('counts ticks when before and after are initialized on multiple page', async () => { - await pool.mock.tickBitmap.withArgs(0).returns(0b11111100) - await pool.mock.tickBitmap.withArgs(-1).returns(0b11111100) - const startingTickInit = await PoolTicksCounter.countInitializedTicksCrossed( - pool.address, - bitIdxToTick(2), - bitIdxToTick(3, -1) - ) - expect(startingTickInit).to.be.eq(5) - const endingTickInit = await PoolTicksCounter.countInitializedTicksCrossed( - pool.address, - bitIdxToTick(5), - bitIdxToTick(255, -1) - ) - expect(endingTickInit).to.be.eq(4) - const bothInit = await PoolTicksCounter.countInitializedTicksCrossed( - pool.address, - bitIdxToTick(2), - bitIdxToTick(5, -1) - ) - expect(bothInit).to.be.eq(3) - }) - - it('counts ticks with lots of pages', async () => { - await pool.mock.tickBitmap.withArgs(0).returns(0b11111100) - await pool.mock.tickBitmap.withArgs(-1).returns(0xff) - await pool.mock.tickBitmap.withArgs(-2).returns(0x0) - await pool.mock.tickBitmap.withArgs(-3).returns(0x0) - await pool.mock.tickBitmap.withArgs(-4).returns(0b11111100) - const bothInit = await PoolTicksCounter.countInitializedTicksCrossed( - pool.address, - bitIdxToTick(3), - bitIdxToTick(6, -4) - ) - expect(bothInit).to.be.eq(11) - }) - }) - }) -}) diff --git a/lib/v3-periphery/test/PositionValue.spec.ts b/lib/v3-periphery/test/PositionValue.spec.ts deleted file mode 100644 index 6bb7ef4..0000000 --- a/lib/v3-periphery/test/PositionValue.spec.ts +++ /dev/null @@ -1,490 +0,0 @@ -import { waffle, ethers } from 'hardhat' -import { constants, BigNumberish, Contract } from 'ethers' -import { Fixture } from 'ethereum-waffle' -import { - PositionValueTest, - SwapRouter, - MockTimeNonfungiblePositionManager, - IUniswapV3Pool, - TestERC20, - IUniswapV3Factory, -} from '../typechain' -import { FeeAmount, MaxUint128, TICK_SPACINGS } from './shared/constants' -import { getMaxTick, getMinTick } from './shared/ticks' -import { encodePriceSqrt } from './shared/encodePriceSqrt' -import { expandTo18Decimals } from './shared/expandTo18Decimals' -import { encodePath } from './shared/path' -import { computePoolAddress } from './shared/computePoolAddress' -import completeFixture from './shared/completeFixture' -import snapshotGasCost from './shared/snapshotGasCost' - -import { expect } from './shared/expect' - -import { abi as IUniswapV3PoolABI } from '@uniswap/v3-core/artifacts/contracts/interfaces/IUniswapV3Pool.sol/IUniswapV3Pool.json' - -describe('PositionValue', async () => { - const [...wallets] = waffle.provider.getWallets() - const positionValueCompleteFixture: Fixture<{ - positionValue: PositionValueTest - tokens: [TestERC20, TestERC20, TestERC20] - nft: MockTimeNonfungiblePositionManager - router: SwapRouter - factory: IUniswapV3Factory - }> = async (wallets, provider) => { - const { nft, router, tokens, factory } = await completeFixture(wallets, provider) - const positionValueFactory = await ethers.getContractFactory('PositionValueTest') - const positionValue = (await positionValueFactory.deploy()) as PositionValueTest - - for (const token of tokens) { - await token.approve(nft.address, constants.MaxUint256) - await token.connect(wallets[0]).approve(nft.address, constants.MaxUint256) - await token.transfer(wallets[0].address, expandTo18Decimals(1_000_000)) - } - - return { - positionValue, - tokens, - nft, - router, - factory, - } - } - - let pool: Contract - let tokens: [TestERC20, TestERC20, TestERC20] - let positionValue: PositionValueTest - let nft: MockTimeNonfungiblePositionManager - let router: SwapRouter - let factory: IUniswapV3Factory - - let amountDesired: BigNumberish - - let loadFixture: ReturnType - before('create fixture loader', async () => { - loadFixture = waffle.createFixtureLoader(wallets) - }) - - beforeEach(async () => { - ;({ positionValue, tokens, nft, router, factory } = await loadFixture(positionValueCompleteFixture)) - await nft.createAndInitializePoolIfNecessary( - tokens[0].address, - tokens[1].address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - - const poolAddress = computePoolAddress(factory.address, [tokens[0].address, tokens[1].address], FeeAmount.MEDIUM) - pool = new ethers.Contract(poolAddress, IUniswapV3PoolABI, wallets[0]) - }) - - describe('#total', () => { - let tokenId: number - let sqrtRatioX96: BigNumberish - - beforeEach(async () => { - amountDesired = expandTo18Decimals(100_000) - - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - fee: FeeAmount.MEDIUM, - recipient: wallets[0].address, - amount0Desired: amountDesired, - amount1Desired: amountDesired, - amount0Min: 0, - amount1Min: 0, - deadline: 10, - }) - - const swapAmount = expandTo18Decimals(1_000) - await tokens[0].approve(router.address, swapAmount) - await tokens[1].approve(router.address, swapAmount) - - // accmuluate token0 fees - await router.exactInput({ - recipient: wallets[0].address, - deadline: 1, - path: encodePath([tokens[0].address, tokens[1].address], [FeeAmount.MEDIUM]), - amountIn: swapAmount, - amountOutMinimum: 0, - }) - - // accmuluate token1 fees - await router.exactInput({ - recipient: wallets[0].address, - deadline: 1, - path: encodePath([tokens[1].address, tokens[0].address], [FeeAmount.MEDIUM]), - amountIn: swapAmount, - amountOutMinimum: 0, - }) - - sqrtRatioX96 = (await pool.slot0()).sqrtPriceX96 - }) - - it('returns the correct amount', async () => { - const principal = await positionValue.principal(nft.address, 1, sqrtRatioX96) - const fees = await positionValue.fees(nft.address, 1) - const total = await positionValue.total(nft.address, 1, sqrtRatioX96) - - expect(total[0]).to.equal(principal[0].add(fees[0])) - expect(total[1]).to.equal(principal[1].add(fees[1])) - }) - - it('gas', async () => { - await snapshotGasCost(positionValue.totalGas(nft.address, 1, sqrtRatioX96)) - }) - }) - - describe('#principal', () => { - let sqrtRatioX96: BigNumberish - - beforeEach(async () => { - amountDesired = expandTo18Decimals(100_000) - sqrtRatioX96 = (await pool.slot0()).sqrtPriceX96 - }) - - it('returns the correct values when price is in the middle of the range', async () => { - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - fee: FeeAmount.MEDIUM, - recipient: wallets[0].address, - amount0Desired: amountDesired, - amount1Desired: amountDesired, - amount0Min: 0, - amount1Min: 0, - deadline: 10, - }) - - const principal = await positionValue.principal(nft.address, 1, sqrtRatioX96) - expect(principal.amount0).to.equal('99999999999999999999999') - expect(principal.amount1).to.equal('99999999999999999999999') - }) - - it('returns the correct values when range is below current price', async () => { - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: -60, - fee: FeeAmount.MEDIUM, - recipient: wallets[0].address, - amount0Desired: amountDesired, - amount1Desired: amountDesired, - amount0Min: 0, - amount1Min: 0, - deadline: 10, - }) - - const principal = await positionValue.principal(nft.address, 1, sqrtRatioX96) - expect(principal.amount0).to.equal('0') - expect(principal.amount1).to.equal('99999999999999999999999') - }) - - it('returns the correct values when range is below current price', async () => { - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - tickLower: 60, - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - fee: FeeAmount.MEDIUM, - recipient: wallets[0].address, - amount0Desired: amountDesired, - amount1Desired: amountDesired, - amount0Min: 0, - amount1Min: 0, - deadline: 10, - }) - - const principal = await positionValue.principal(nft.address, 1, sqrtRatioX96) - expect(principal.amount0).to.equal('99999999999999999999999') - expect(principal.amount1).to.equal('0') - }) - - it('returns the correct values when range is skewed above price', async () => { - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - tickLower: -6_000, - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - fee: FeeAmount.MEDIUM, - recipient: wallets[0].address, - amount0Desired: amountDesired, - amount1Desired: amountDesired, - amount0Min: 0, - amount1Min: 0, - deadline: 10, - }) - - const principal = await positionValue.principal(nft.address, 1, sqrtRatioX96) - expect(principal.amount0).to.equal('99999999999999999999999') - expect(principal.amount1).to.equal('25917066770240321655335') - }) - - it('returns the correct values when range is skewed below price', async () => { - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: 6_000, - fee: FeeAmount.MEDIUM, - recipient: wallets[0].address, - amount0Desired: amountDesired, - amount1Desired: amountDesired, - amount0Min: 0, - amount1Min: 0, - deadline: 10, - }) - - const principal = await positionValue.principal(nft.address, 1, sqrtRatioX96) - expect(principal.amount0).to.equal('25917066770240321655335') - expect(principal.amount1).to.equal('99999999999999999999999') - }) - - it('gas', async () => { - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - fee: FeeAmount.MEDIUM, - recipient: wallets[0].address, - amount0Desired: amountDesired, - amount1Desired: amountDesired, - amount0Min: 0, - amount1Min: 0, - deadline: 10, - }) - - await snapshotGasCost(positionValue.principalGas(nft.address, 1, sqrtRatioX96)) - }) - }) - - describe('#fees', () => { - let tokenId: number - - beforeEach(async () => { - amountDesired = expandTo18Decimals(100_000) - tokenId = 2 - - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - fee: FeeAmount.MEDIUM, - recipient: wallets[0].address, - amount0Desired: amountDesired, - amount1Desired: amountDesired, - amount0Min: 0, - amount1Min: 0, - deadline: 10, - }) - }) - - describe('when price is within the position range', () => { - beforeEach(async () => { - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - tickLower: TICK_SPACINGS[FeeAmount.MEDIUM] * -1_000, - tickUpper: TICK_SPACINGS[FeeAmount.MEDIUM] * 1_000, - fee: FeeAmount.MEDIUM, - recipient: wallets[0].address, - amount0Desired: amountDesired, - amount1Desired: amountDesired, - amount0Min: 0, - amount1Min: 0, - deadline: 10, - }) - - const swapAmount = expandTo18Decimals(1_000) - await tokens[0].approve(router.address, swapAmount) - await tokens[1].approve(router.address, swapAmount) - - // accmuluate token0 fees - await router.exactInput({ - recipient: wallets[0].address, - deadline: 1, - path: encodePath([tokens[0].address, tokens[1].address], [FeeAmount.MEDIUM]), - amountIn: swapAmount, - amountOutMinimum: 0, - }) - - // accmuluate token1 fees - await router.exactInput({ - recipient: wallets[0].address, - deadline: 1, - path: encodePath([tokens[1].address, tokens[0].address], [FeeAmount.MEDIUM]), - amountIn: swapAmount, - amountOutMinimum: 0, - }) - }) - - it('return the correct amount of fees', async () => { - const feesFromCollect = await nft.callStatic.collect({ - tokenId, - recipient: wallets[0].address, - amount0Max: MaxUint128, - amount1Max: MaxUint128, - }) - const feeAmounts = await positionValue.fees(nft.address, tokenId) - - expect(feeAmounts[0]).to.equal(feesFromCollect[0]) - expect(feeAmounts[1]).to.equal(feesFromCollect[1]) - }) - - it('returns the correct amount of fees if tokensOwed fields are greater than 0', async () => { - await nft.increaseLiquidity({ - tokenId: tokenId, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - }) - - const swapAmount = expandTo18Decimals(1_000) - await tokens[0].approve(router.address, swapAmount) - - // accmuluate more token0 fees after clearing initial amount - await router.exactInput({ - recipient: wallets[0].address, - deadline: 1, - path: encodePath([tokens[0].address, tokens[1].address], [FeeAmount.MEDIUM]), - amountIn: swapAmount, - amountOutMinimum: 0, - }) - - const feesFromCollect = await nft.callStatic.collect({ - tokenId, - recipient: wallets[0].address, - amount0Max: MaxUint128, - amount1Max: MaxUint128, - }) - const feeAmounts = await positionValue.fees(nft.address, tokenId) - expect(feeAmounts[0]).to.equal(feesFromCollect[0]) - expect(feeAmounts[1]).to.equal(feesFromCollect[1]) - }) - - it('gas', async () => { - await snapshotGasCost(positionValue.feesGas(nft.address, tokenId)) - }) - }) - - describe('when price is below the position range', async () => { - beforeEach(async () => { - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - tickLower: TICK_SPACINGS[FeeAmount.MEDIUM] * -10, - tickUpper: TICK_SPACINGS[FeeAmount.MEDIUM] * 10, - fee: FeeAmount.MEDIUM, - recipient: wallets[0].address, - amount0Desired: expandTo18Decimals(10_000), - amount1Desired: expandTo18Decimals(10_000), - amount0Min: 0, - amount1Min: 0, - deadline: 10, - }) - - await tokens[0].approve(router.address, constants.MaxUint256) - await tokens[1].approve(router.address, constants.MaxUint256) - - // accumulate token1 fees - await router.exactInput({ - recipient: wallets[0].address, - deadline: 1, - path: encodePath([tokens[1].address, tokens[0].address], [FeeAmount.MEDIUM]), - amountIn: expandTo18Decimals(1_000), - amountOutMinimum: 0, - }) - - // accumulate token0 fees and push price below tickLower - await router.exactInput({ - recipient: wallets[0].address, - deadline: 1, - path: encodePath([tokens[0].address, tokens[1].address], [FeeAmount.MEDIUM]), - amountIn: expandTo18Decimals(50_000), - amountOutMinimum: 0, - }) - }) - - it('returns the correct amount of fees', async () => { - const feesFromCollect = await nft.callStatic.collect({ - tokenId, - recipient: wallets[0].address, - amount0Max: MaxUint128, - amount1Max: MaxUint128, - }) - - const feeAmounts = await positionValue.fees(nft.address, tokenId) - expect(feeAmounts[0]).to.equal(feesFromCollect[0]) - expect(feeAmounts[1]).to.equal(feesFromCollect[1]) - }) - - it('gas', async () => { - await snapshotGasCost(positionValue.feesGas(nft.address, tokenId)) - }) - }) - - describe('when price is above the position range', async () => { - beforeEach(async () => { - await nft.mint({ - token0: tokens[0].address, - token1: tokens[1].address, - tickLower: TICK_SPACINGS[FeeAmount.MEDIUM] * -10, - tickUpper: TICK_SPACINGS[FeeAmount.MEDIUM] * 10, - fee: FeeAmount.MEDIUM, - recipient: wallets[0].address, - amount0Desired: expandTo18Decimals(10_000), - amount1Desired: expandTo18Decimals(10_000), - amount0Min: 0, - amount1Min: 0, - deadline: 10, - }) - - await tokens[0].approve(router.address, constants.MaxUint256) - await tokens[1].approve(router.address, constants.MaxUint256) - - // accumulate token0 fees - await router.exactInput({ - recipient: wallets[0].address, - deadline: 1, - path: encodePath([tokens[0].address, tokens[1].address], [FeeAmount.MEDIUM]), - amountIn: expandTo18Decimals(1_000), - amountOutMinimum: 0, - }) - - // accumulate token1 fees and push price above tickUpper - await router.exactInput({ - recipient: wallets[0].address, - deadline: 1, - path: encodePath([tokens[1].address, tokens[0].address], [FeeAmount.MEDIUM]), - amountIn: expandTo18Decimals(50_000), - amountOutMinimum: 0, - }) - }) - - it('returns the correct amount of fees', async () => { - const feesFromCollect = await nft.callStatic.collect({ - tokenId, - recipient: wallets[0].address, - amount0Max: MaxUint128, - amount1Max: MaxUint128, - }) - const feeAmounts = await positionValue.fees(nft.address, tokenId) - expect(feeAmounts[0]).to.equal(feesFromCollect[0]) - expect(feeAmounts[1]).to.equal(feesFromCollect[1]) - }) - - it('gas', async () => { - await snapshotGasCost(positionValue.feesGas(nft.address, tokenId)) - }) - }) - }) -}) diff --git a/lib/v3-periphery/test/Quoter.spec.ts b/lib/v3-periphery/test/Quoter.spec.ts deleted file mode 100644 index 6236a1f..0000000 --- a/lib/v3-periphery/test/Quoter.spec.ts +++ /dev/null @@ -1,201 +0,0 @@ -import { Fixture } from 'ethereum-waffle' -import { constants, Wallet } from 'ethers' -import { ethers, waffle } from 'hardhat' -import { MockTimeNonfungiblePositionManager, Quoter, TestERC20 } from '../typechain' -import completeFixture from './shared/completeFixture' -import { FeeAmount, MaxUint128, TICK_SPACINGS } from './shared/constants' -import { encodePriceSqrt } from './shared/encodePriceSqrt' -import { expandTo18Decimals } from './shared/expandTo18Decimals' -import { expect } from './shared/expect' -import { encodePath } from './shared/path' -import { createPool } from './shared/quoter' - -describe('Quoter', () => { - let wallet: Wallet - let trader: Wallet - - const swapRouterFixture: Fixture<{ - nft: MockTimeNonfungiblePositionManager - tokens: [TestERC20, TestERC20, TestERC20] - quoter: Quoter - }> = async (wallets, provider) => { - const { weth9, factory, router, tokens, nft } = await completeFixture(wallets, provider) - - // approve & fund wallets - for (const token of tokens) { - await token.approve(router.address, constants.MaxUint256) - await token.approve(nft.address, constants.MaxUint256) - await token.connect(trader).approve(router.address, constants.MaxUint256) - await token.transfer(trader.address, expandTo18Decimals(1_000_000)) - } - - const quoterFactory = await ethers.getContractFactory('Quoter') - quoter = (await quoterFactory.deploy(factory.address, weth9.address)) as Quoter - - return { - tokens, - nft, - quoter, - } - } - - let nft: MockTimeNonfungiblePositionManager - let tokens: [TestERC20, TestERC20, TestERC20] - let quoter: Quoter - - let loadFixture: ReturnType - - before('create fixture loader', async () => { - const wallets = await (ethers as any).getSigners() - ;[wallet, trader] = wallets - loadFixture = waffle.createFixtureLoader(wallets) - }) - - // helper for getting weth and token balances - beforeEach('load fixture', async () => { - ;({ tokens, nft, quoter } = await loadFixture(swapRouterFixture)) - }) - - describe('quotes', () => { - beforeEach(async () => { - await createPool(nft, wallet, tokens[0].address, tokens[1].address) - await createPool(nft, wallet, tokens[1].address, tokens[2].address) - }) - - describe('#quoteExactInput', () => { - it('0 -> 1', async () => { - const quote = await quoter.callStatic.quoteExactInput( - encodePath([tokens[0].address, tokens[1].address], [FeeAmount.MEDIUM]), - 3 - ) - - expect(quote).to.eq(1) - }) - - it('1 -> 0', async () => { - const quote = await quoter.callStatic.quoteExactInput( - encodePath([tokens[1].address, tokens[0].address], [FeeAmount.MEDIUM]), - 3 - ) - - expect(quote).to.eq(1) - }) - - it('0 -> 1 -> 2', async () => { - const quote = await quoter.callStatic.quoteExactInput( - encodePath( - tokens.map((token) => token.address), - [FeeAmount.MEDIUM, FeeAmount.MEDIUM] - ), - 5 - ) - - expect(quote).to.eq(1) - }) - - it('2 -> 1 -> 0', async () => { - const quote = await quoter.callStatic.quoteExactInput( - encodePath(tokens.map((token) => token.address).reverse(), [FeeAmount.MEDIUM, FeeAmount.MEDIUM]), - 5 - ) - - expect(quote).to.eq(1) - }) - }) - - describe('#quoteExactInputSingle', () => { - it('0 -> 1', async () => { - const quote = await quoter.callStatic.quoteExactInputSingle( - tokens[0].address, - tokens[1].address, - FeeAmount.MEDIUM, - MaxUint128, - // -2% - encodePriceSqrt(100, 102) - ) - - expect(quote).to.eq(9852) - }) - - it('1 -> 0', async () => { - const quote = await quoter.callStatic.quoteExactInputSingle( - tokens[1].address, - tokens[0].address, - FeeAmount.MEDIUM, - MaxUint128, - // +2% - encodePriceSqrt(102, 100) - ) - - expect(quote).to.eq(9852) - }) - }) - - describe('#quoteExactOutput', () => { - it('0 -> 1', async () => { - const quote = await quoter.callStatic.quoteExactOutput( - encodePath([tokens[1].address, tokens[0].address], [FeeAmount.MEDIUM]), - 1 - ) - - expect(quote).to.eq(3) - }) - - it('1 -> 0', async () => { - const quote = await quoter.callStatic.quoteExactOutput( - encodePath([tokens[0].address, tokens[1].address], [FeeAmount.MEDIUM]), - 1 - ) - - expect(quote).to.eq(3) - }) - - it('0 -> 1 -> 2', async () => { - const quote = await quoter.callStatic.quoteExactOutput( - encodePath(tokens.map((token) => token.address).reverse(), [FeeAmount.MEDIUM, FeeAmount.MEDIUM]), - 1 - ) - - expect(quote).to.eq(5) - }) - - it('2 -> 1 -> 0', async () => { - const quote = await quoter.callStatic.quoteExactOutput( - encodePath( - tokens.map((token) => token.address), - [FeeAmount.MEDIUM, FeeAmount.MEDIUM] - ), - 1 - ) - - expect(quote).to.eq(5) - }) - }) - - describe('#quoteExactOutputSingle', () => { - it('0 -> 1', async () => { - const quote = await quoter.callStatic.quoteExactOutputSingle( - tokens[0].address, - tokens[1].address, - FeeAmount.MEDIUM, - MaxUint128, - encodePriceSqrt(100, 102) - ) - - expect(quote).to.eq(9981) - }) - - it('1 -> 0', async () => { - const quote = await quoter.callStatic.quoteExactOutputSingle( - tokens[1].address, - tokens[0].address, - FeeAmount.MEDIUM, - MaxUint128, - encodePriceSqrt(102, 100) - ) - - expect(quote).to.eq(9981) - }) - }) - }) -}) diff --git a/lib/v3-periphery/test/QuoterV2.spec.ts b/lib/v3-periphery/test/QuoterV2.spec.ts deleted file mode 100644 index 8d1b567..0000000 --- a/lib/v3-periphery/test/QuoterV2.spec.ts +++ /dev/null @@ -1,578 +0,0 @@ -import { Fixture } from 'ethereum-waffle' -import { constants, Wallet } from 'ethers' -import { ethers, waffle } from 'hardhat' -import { MockTimeNonfungiblePositionManager, QuoterV2, TestERC20 } from '../typechain' -import completeFixture from './shared/completeFixture' -import { FeeAmount, MaxUint128 } from './shared/constants' -import { encodePriceSqrt } from './shared/encodePriceSqrt' -import { expandTo18Decimals } from './shared/expandTo18Decimals' -import { expect } from './shared/expect' -import { encodePath } from './shared/path' -import { createPool, createPoolWithMultiplePositions, createPoolWithZeroTickInitialized } from './shared/quoter' -import snapshotGasCost from './shared/snapshotGasCost' - -describe('QuoterV2', function () { - this.timeout(40000) - let wallet: Wallet - let trader: Wallet - - const swapRouterFixture: Fixture<{ - nft: MockTimeNonfungiblePositionManager - tokens: [TestERC20, TestERC20, TestERC20] - quoter: QuoterV2 - }> = async (wallets, provider) => { - const { weth9, factory, router, tokens, nft } = await completeFixture(wallets, provider) - - // approve & fund wallets - for (const token of tokens) { - await token.approve(router.address, constants.MaxUint256) - await token.approve(nft.address, constants.MaxUint256) - await token.connect(trader).approve(router.address, constants.MaxUint256) - await token.transfer(trader.address, expandTo18Decimals(1_000_000)) - } - - const quoterFactory = await ethers.getContractFactory('QuoterV2') - quoter = (await quoterFactory.deploy(factory.address, weth9.address)) as QuoterV2 - - return { - tokens, - nft, - quoter, - } - } - - let nft: MockTimeNonfungiblePositionManager - let tokens: [TestERC20, TestERC20, TestERC20] - let quoter: QuoterV2 - - let loadFixture: ReturnType - - before('create fixture loader', async () => { - const wallets = await (ethers as any).getSigners() - ;[wallet, trader] = wallets - loadFixture = waffle.createFixtureLoader(wallets) - }) - - // helper for getting weth and token balances - beforeEach('load fixture', async () => { - ;({ tokens, nft, quoter } = await loadFixture(swapRouterFixture)) - }) - - describe('quotes', () => { - beforeEach(async () => { - await createPool(nft, wallet, tokens[0].address, tokens[1].address) - await createPool(nft, wallet, tokens[1].address, tokens[2].address) - await createPoolWithMultiplePositions(nft, wallet, tokens[0].address, tokens[2].address) - }) - - describe('#quoteExactInput', () => { - it('0 -> 2 cross 2 tick', async () => { - const { - amountOut, - sqrtPriceX96AfterList, - initializedTicksCrossedList, - gasEstimate, - } = await quoter.callStatic.quoteExactInput( - encodePath([tokens[0].address, tokens[2].address], [FeeAmount.MEDIUM]), - 10000 - ) - - await snapshotGasCost(gasEstimate) - expect(sqrtPriceX96AfterList.length).to.eq(1) - expect(sqrtPriceX96AfterList[0]).to.eq('78461846509168490764501028180') - expect(initializedTicksCrossedList[0]).to.eq(2) - expect(amountOut).to.eq(9871) - }) - - it('0 -> 2 cross 2 tick where after is initialized', async () => { - // The swap amount is set such that the active tick after the swap is -120. - // -120 is an initialized tick for this pool. We check that we don't count it. - const { - amountOut, - sqrtPriceX96AfterList, - initializedTicksCrossedList, - gasEstimate, - } = await quoter.callStatic.quoteExactInput( - encodePath([tokens[0].address, tokens[2].address], [FeeAmount.MEDIUM]), - 6200 - ) - - await snapshotGasCost(gasEstimate) - expect(sqrtPriceX96AfterList.length).to.eq(1) - expect(sqrtPriceX96AfterList[0]).to.eq('78757224507315167622282810783') - expect(initializedTicksCrossedList.length).to.eq(1) - expect(initializedTicksCrossedList[0]).to.eq(1) - expect(amountOut).to.eq(6143) - }) - - it('0 -> 2 cross 1 tick', async () => { - const { - amountOut, - sqrtPriceX96AfterList, - initializedTicksCrossedList, - gasEstimate, - } = await quoter.callStatic.quoteExactInput( - encodePath([tokens[0].address, tokens[2].address], [FeeAmount.MEDIUM]), - 4000 - ) - - await snapshotGasCost(gasEstimate) - expect(initializedTicksCrossedList[0]).to.eq(1) - expect(sqrtPriceX96AfterList.length).to.eq(1) - expect(sqrtPriceX96AfterList[0]).to.eq('78926452400586371254602774705') - expect(amountOut).to.eq(3971) - }) - - it('0 -> 2 cross 0 tick, starting tick not initialized', async () => { - // Tick before 0, tick after -1. - const { - amountOut, - sqrtPriceX96AfterList, - initializedTicksCrossedList, - gasEstimate, - } = await quoter.callStatic.quoteExactInput( - encodePath([tokens[0].address, tokens[2].address], [FeeAmount.MEDIUM]), - 10 - ) - - await snapshotGasCost(gasEstimate) - expect(initializedTicksCrossedList[0]).to.eq(0) - expect(sqrtPriceX96AfterList.length).to.eq(1) - expect(sqrtPriceX96AfterList[0]).to.eq('79227483487511329217250071027') - expect(amountOut).to.eq(8) - }) - - it('0 -> 2 cross 0 tick, starting tick initialized', async () => { - // Tick before 0, tick after -1. Tick 0 initialized. - await createPoolWithZeroTickInitialized(nft, wallet, tokens[0].address, tokens[2].address) - - const { - amountOut, - sqrtPriceX96AfterList, - initializedTicksCrossedList, - gasEstimate, - } = await quoter.callStatic.quoteExactInput( - encodePath([tokens[0].address, tokens[2].address], [FeeAmount.MEDIUM]), - 10 - ) - - await snapshotGasCost(gasEstimate) - expect(initializedTicksCrossedList[0]).to.eq(1) - expect(sqrtPriceX96AfterList.length).to.eq(1) - expect(sqrtPriceX96AfterList[0]).to.eq('79227817515327498931091950511') - expect(amountOut).to.eq(8) - }) - - it('2 -> 0 cross 2', async () => { - const { - amountOut, - sqrtPriceX96AfterList, - initializedTicksCrossedList, - gasEstimate, - } = await quoter.callStatic.quoteExactInput( - encodePath([tokens[2].address, tokens[0].address], [FeeAmount.MEDIUM]), - 10000 - ) - - await snapshotGasCost(gasEstimate) - expect(initializedTicksCrossedList[0]).to.eq(2) - expect(sqrtPriceX96AfterList.length).to.eq(1) - expect(sqrtPriceX96AfterList[0]).to.eq('80001962924147897865541384515') - expect(initializedTicksCrossedList.length).to.eq(1) - expect(amountOut).to.eq(9871) - }) - - it('2 -> 0 cross 2 where tick after is initialized', async () => { - // The swap amount is set such that the active tick after the swap is 120. - // 120 is an initialized tick for this pool. We check we don't count it. - const { - amountOut, - sqrtPriceX96AfterList, - initializedTicksCrossedList, - gasEstimate, - } = await quoter.callStatic.quoteExactInput( - encodePath([tokens[2].address, tokens[0].address], [FeeAmount.MEDIUM]), - 6250 - ) - - await snapshotGasCost(gasEstimate) - expect(initializedTicksCrossedList[0]).to.eq(2) - expect(sqrtPriceX96AfterList.length).to.eq(1) - expect(sqrtPriceX96AfterList[0]).to.eq('79705728824507063507279123685') - expect(initializedTicksCrossedList.length).to.eq(1) - expect(amountOut).to.eq(6190) - }) - - it('2 -> 0 cross 0 tick, starting tick initialized', async () => { - // Tick 0 initialized. Tick after = 1 - await createPoolWithZeroTickInitialized(nft, wallet, tokens[0].address, tokens[2].address) - - const { - amountOut, - sqrtPriceX96AfterList, - initializedTicksCrossedList, - gasEstimate, - } = await quoter.callStatic.quoteExactInput( - encodePath([tokens[2].address, tokens[0].address], [FeeAmount.MEDIUM]), - 200 - ) - - await snapshotGasCost(gasEstimate) - expect(initializedTicksCrossedList[0]).to.eq(0) - expect(sqrtPriceX96AfterList.length).to.eq(1) - expect(sqrtPriceX96AfterList[0]).to.eq('79235729830182478001034429156') - expect(initializedTicksCrossedList.length).to.eq(1) - expect(amountOut).to.eq(198) - }) - - it('2 -> 0 cross 0 tick, starting tick not initialized', async () => { - // Tick 0 initialized. Tick after = 1 - const { - amountOut, - sqrtPriceX96AfterList, - initializedTicksCrossedList, - gasEstimate, - } = await quoter.callStatic.quoteExactInput( - encodePath([tokens[2].address, tokens[0].address], [FeeAmount.MEDIUM]), - 103 - ) - - await snapshotGasCost(gasEstimate) - expect(initializedTicksCrossedList[0]).to.eq(0) - expect(sqrtPriceX96AfterList.length).to.eq(1) - expect(sqrtPriceX96AfterList[0]).to.eq('79235858216754624215638319723') - expect(initializedTicksCrossedList.length).to.eq(1) - expect(amountOut).to.eq(101) - }) - - it('2 -> 1', async () => { - const { - amountOut, - sqrtPriceX96AfterList, - initializedTicksCrossedList, - gasEstimate, - } = await quoter.callStatic.quoteExactInput( - encodePath([tokens[2].address, tokens[1].address], [FeeAmount.MEDIUM]), - 10000 - ) - - await snapshotGasCost(gasEstimate) - expect(sqrtPriceX96AfterList.length).to.eq(1) - expect(sqrtPriceX96AfterList[0]).to.eq('80018067294531553039351583520') - expect(initializedTicksCrossedList[0]).to.eq(0) - expect(amountOut).to.eq(9871) - }) - - it('0 -> 2 -> 1', async () => { - const { - amountOut, - sqrtPriceX96AfterList, - initializedTicksCrossedList, - gasEstimate, - } = await quoter.callStatic.quoteExactInput( - encodePath([tokens[0].address, tokens[2].address, tokens[1].address], [FeeAmount.MEDIUM, FeeAmount.MEDIUM]), - 10000 - ) - - await snapshotGasCost(gasEstimate) - expect(sqrtPriceX96AfterList.length).to.eq(2) - expect(sqrtPriceX96AfterList[0]).to.eq('78461846509168490764501028180') - expect(sqrtPriceX96AfterList[1]).to.eq('80007846861567212939802016351') - expect(initializedTicksCrossedList[0]).to.eq(2) - expect(initializedTicksCrossedList[1]).to.eq(0) - expect(amountOut).to.eq(9745) - }) - }) - - describe('#quoteExactInputSingle', () => { - it('0 -> 2', async () => { - const { - amountOut: quote, - sqrtPriceX96After, - initializedTicksCrossed, - gasEstimate, - } = await quoter.callStatic.quoteExactInputSingle({ - tokenIn: tokens[0].address, - tokenOut: tokens[2].address, - fee: FeeAmount.MEDIUM, - amountIn: 10000, - // -2% - sqrtPriceLimitX96: encodePriceSqrt(100, 102), - }) - - await snapshotGasCost(gasEstimate) - expect(initializedTicksCrossed).to.eq(2) - expect(quote).to.eq(9871) - expect(sqrtPriceX96After).to.eq('78461846509168490764501028180') - }) - - it('2 -> 0', async () => { - const { - amountOut: quote, - sqrtPriceX96After, - initializedTicksCrossed, - gasEstimate, - } = await quoter.callStatic.quoteExactInputSingle({ - tokenIn: tokens[2].address, - tokenOut: tokens[0].address, - fee: FeeAmount.MEDIUM, - amountIn: 10000, - // +2% - sqrtPriceLimitX96: encodePriceSqrt(102, 100), - }) - - await snapshotGasCost(gasEstimate) - expect(initializedTicksCrossed).to.eq(2) - expect(quote).to.eq(9871) - expect(sqrtPriceX96After).to.eq('80001962924147897865541384515') - }) - }) - - describe('#quoteExactOutput', () => { - it('0 -> 2 cross 2 tick', async () => { - const { - amountIn, - sqrtPriceX96AfterList, - initializedTicksCrossedList, - gasEstimate, - } = await quoter.callStatic.quoteExactOutput( - encodePath([tokens[2].address, tokens[0].address], [FeeAmount.MEDIUM]), - 15000 - ) - - await snapshotGasCost(gasEstimate) - expect(initializedTicksCrossedList.length).to.eq(1) - expect(initializedTicksCrossedList[0]).to.eq(2) - expect(amountIn).to.eq(15273) - - expect(sqrtPriceX96AfterList.length).to.eq(1) - expect(sqrtPriceX96AfterList[0]).to.eq('78055527257643669242286029831') - }) - - it('0 -> 2 cross 2 where tick after is initialized', async () => { - // The swap amount is set such that the active tick after the swap is -120. - // -120 is an initialized tick for this pool. We check that we count it. - const { - amountIn, - sqrtPriceX96AfterList, - initializedTicksCrossedList, - gasEstimate, - } = await quoter.callStatic.quoteExactOutput( - encodePath([tokens[2].address, tokens[0].address], [FeeAmount.MEDIUM]), - 6143 - ) - - await snapshotGasCost(gasEstimate) - expect(sqrtPriceX96AfterList.length).to.eq(1) - expect(sqrtPriceX96AfterList[0]).to.eq('78757225449310403327341205211') - expect(initializedTicksCrossedList.length).to.eq(1) - expect(initializedTicksCrossedList[0]).to.eq(1) - expect(amountIn).to.eq(6200) - }) - - it('0 -> 2 cross 1 tick', async () => { - const { - amountIn, - sqrtPriceX96AfterList, - initializedTicksCrossedList, - gasEstimate, - } = await quoter.callStatic.quoteExactOutput( - encodePath([tokens[2].address, tokens[0].address], [FeeAmount.MEDIUM]), - 4000 - ) - - await snapshotGasCost(gasEstimate) - expect(initializedTicksCrossedList.length).to.eq(1) - expect(initializedTicksCrossedList[0]).to.eq(1) - expect(amountIn).to.eq(4029) - - expect(sqrtPriceX96AfterList.length).to.eq(1) - expect(sqrtPriceX96AfterList[0]).to.eq('78924219757724709840818372098') - }) - - it('0 -> 2 cross 0 tick starting tick initialized', async () => { - // Tick before 0, tick after 1. Tick 0 initialized. - await createPoolWithZeroTickInitialized(nft, wallet, tokens[0].address, tokens[2].address) - const { - amountIn, - sqrtPriceX96AfterList, - initializedTicksCrossedList, - gasEstimate, - } = await quoter.callStatic.quoteExactOutput( - encodePath([tokens[2].address, tokens[0].address], [FeeAmount.MEDIUM]), - 100 - ) - - await snapshotGasCost(gasEstimate) - expect(initializedTicksCrossedList.length).to.eq(1) - expect(initializedTicksCrossedList[0]).to.eq(1) - expect(amountIn).to.eq(102) - - expect(sqrtPriceX96AfterList.length).to.eq(1) - expect(sqrtPriceX96AfterList[0]).to.eq('79224329176051641448521403903') - }) - - it('0 -> 2 cross 0 tick starting tick not initialized', async () => { - const { - amountIn, - sqrtPriceX96AfterList, - initializedTicksCrossedList, - gasEstimate, - } = await quoter.callStatic.quoteExactOutput( - encodePath([tokens[2].address, tokens[0].address], [FeeAmount.MEDIUM]), - 10 - ) - - await snapshotGasCost(gasEstimate) - expect(initializedTicksCrossedList.length).to.eq(1) - expect(initializedTicksCrossedList[0]).to.eq(0) - expect(amountIn).to.eq(12) - - expect(sqrtPriceX96AfterList.length).to.eq(1) - expect(sqrtPriceX96AfterList[0]).to.eq('79227408033628034983534698435') - }) - - it('2 -> 0 cross 2 ticks', async () => { - const { - amountIn, - sqrtPriceX96AfterList, - initializedTicksCrossedList, - gasEstimate, - } = await quoter.callStatic.quoteExactOutput( - encodePath([tokens[0].address, tokens[2].address], [FeeAmount.MEDIUM]), - 15000 - ) - - await snapshotGasCost(gasEstimate) - expect(initializedTicksCrossedList.length).to.eq(1) - expect(initializedTicksCrossedList[0]).to.eq(2) - expect(amountIn).to.eq(15273) - expect(sqrtPriceX96AfterList.length).to.eq(1) - expect(sqrtPriceX96AfterList[0]).to.eq('80418414376567919517220409857') - }) - - it('2 -> 0 cross 2 where tick after is initialized', async () => { - // The swap amount is set such that the active tick after the swap is 120. - // 120 is an initialized tick for this pool. We check that we don't count it. - const { - amountIn, - sqrtPriceX96AfterList, - initializedTicksCrossedList, - gasEstimate, - } = await quoter.callStatic.quoteExactOutput( - encodePath([tokens[0].address, tokens[2].address], [FeeAmount.MEDIUM]), - 6223 - ) - - await snapshotGasCost(gasEstimate) - expect(initializedTicksCrossedList[0]).to.eq(2) - expect(sqrtPriceX96AfterList.length).to.eq(1) - expect(sqrtPriceX96AfterList[0]).to.eq('79708304437530892332449657932') - expect(initializedTicksCrossedList.length).to.eq(1) - expect(amountIn).to.eq(6283) - }) - - it('2 -> 0 cross 1 tick', async () => { - const { - amountIn, - sqrtPriceX96AfterList, - initializedTicksCrossedList, - gasEstimate, - } = await quoter.callStatic.quoteExactOutput( - encodePath([tokens[0].address, tokens[2].address], [FeeAmount.MEDIUM]), - 6000 - ) - - await snapshotGasCost(gasEstimate) - expect(initializedTicksCrossedList[0]).to.eq(1) - expect(sqrtPriceX96AfterList.length).to.eq(1) - expect(sqrtPriceX96AfterList[0]).to.eq('79690640184021170956740081887') - expect(initializedTicksCrossedList.length).to.eq(1) - expect(amountIn).to.eq(6055) - }) - - it('2 -> 1', async () => { - const { - amountIn, - sqrtPriceX96AfterList, - initializedTicksCrossedList, - gasEstimate, - } = await quoter.callStatic.quoteExactOutput( - encodePath([tokens[1].address, tokens[2].address], [FeeAmount.MEDIUM]), - 9871 - ) - - await snapshotGasCost(gasEstimate) - expect(sqrtPriceX96AfterList.length).to.eq(1) - expect(sqrtPriceX96AfterList[0]).to.eq('80018020393569259756601362385') - expect(initializedTicksCrossedList[0]).to.eq(0) - expect(amountIn).to.eq(10000) - }) - - it('0 -> 2 -> 1', async () => { - const { - amountIn, - sqrtPriceX96AfterList, - initializedTicksCrossedList, - gasEstimate, - } = await quoter.callStatic.quoteExactOutput( - encodePath([tokens[0].address, tokens[2].address, tokens[1].address].reverse(), [ - FeeAmount.MEDIUM, - FeeAmount.MEDIUM, - ]), - 9745 - ) - - await snapshotGasCost(gasEstimate) - expect(sqrtPriceX96AfterList.length).to.eq(2) - expect(sqrtPriceX96AfterList[0]).to.eq('80007838904387594703933785072') - expect(sqrtPriceX96AfterList[1]).to.eq('78461888503179331029803316753') - expect(initializedTicksCrossedList[0]).to.eq(0) - expect(initializedTicksCrossedList[1]).to.eq(2) - expect(amountIn).to.eq(10000) - }) - }) - - describe('#quoteExactOutputSingle', () => { - it('0 -> 1', async () => { - const { - amountIn, - sqrtPriceX96After, - initializedTicksCrossed, - gasEstimate, - } = await quoter.callStatic.quoteExactOutputSingle({ - tokenIn: tokens[0].address, - tokenOut: tokens[1].address, - fee: FeeAmount.MEDIUM, - amount: MaxUint128, - sqrtPriceLimitX96: encodePriceSqrt(100, 102), - }) - - await snapshotGasCost(gasEstimate) - expect(amountIn).to.eq(9981) - expect(initializedTicksCrossed).to.eq(0) - expect(sqrtPriceX96After).to.eq('78447570448055484695608110440') - }) - - it('1 -> 0', async () => { - const { - amountIn, - sqrtPriceX96After, - initializedTicksCrossed, - gasEstimate, - } = await quoter.callStatic.quoteExactOutputSingle({ - tokenIn: tokens[1].address, - tokenOut: tokens[0].address, - fee: FeeAmount.MEDIUM, - amount: MaxUint128, - sqrtPriceLimitX96: encodePriceSqrt(102, 100), - }) - - await snapshotGasCost(gasEstimate) - expect(amountIn).to.eq(9981) - expect(initializedTicksCrossed).to.eq(0) - expect(sqrtPriceX96After).to.eq('80016521857016594389520272648') - }) - }) - }) -}) diff --git a/lib/v3-periphery/test/SelfPermit.spec.ts b/lib/v3-periphery/test/SelfPermit.spec.ts deleted file mode 100644 index a76c505..0000000 --- a/lib/v3-periphery/test/SelfPermit.spec.ts +++ /dev/null @@ -1,198 +0,0 @@ -import { constants, Wallet } from 'ethers' -import { waffle, ethers } from 'hardhat' - -import { Fixture } from 'ethereum-waffle' -import { SelfPermitTest, TestERC20PermitAllowed } from '../typechain' -import { expect } from 'chai' -import { getPermitSignature } from './shared/permit' - -describe('SelfPermit', () => { - let wallet: Wallet - let other: Wallet - - const fixture: Fixture<{ - token: TestERC20PermitAllowed - selfPermitTest: SelfPermitTest - }> = async (wallets, provider) => { - const tokenFactory = await ethers.getContractFactory('TestERC20PermitAllowed') - const token = (await tokenFactory.deploy(0)) as TestERC20PermitAllowed - - const selfPermitTestFactory = await ethers.getContractFactory('SelfPermitTest') - const selfPermitTest = (await selfPermitTestFactory.deploy()) as SelfPermitTest - - return { - token, - selfPermitTest, - } - } - - let token: TestERC20PermitAllowed - let selfPermitTest: SelfPermitTest - - let loadFixture: ReturnType - - before('create fixture loader', async () => { - const wallets = await (ethers as any).getSigners() - ;[wallet, other] = wallets - loadFixture = waffle.createFixtureLoader(wallets) - }) - - beforeEach('load fixture', async () => { - ;({ token, selfPermitTest } = await loadFixture(fixture)) - }) - - it('#permit', async () => { - const value = 123 - - const { v, r, s } = await getPermitSignature(wallet, token, other.address, value) - - expect(await token.allowance(wallet.address, other.address)).to.be.eq(0) - await token['permit(address,address,uint256,uint256,uint8,bytes32,bytes32)']( - wallet.address, - other.address, - value, - constants.MaxUint256, - v, - r, - s - ) - expect(await token.allowance(wallet.address, other.address)).to.be.eq(value) - }) - - describe('#selfPermit', () => { - const value = 456 - - it('works', async () => { - const { v, r, s } = await getPermitSignature(wallet, token, selfPermitTest.address, value) - - expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(0) - await selfPermitTest.selfPermit(token.address, value, constants.MaxUint256, v, r, s) - expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(value) - }) - - it('fails if permit is submitted externally', async () => { - const { v, r, s } = await getPermitSignature(wallet, token, selfPermitTest.address, value) - - expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(0) - await token['permit(address,address,uint256,uint256,uint8,bytes32,bytes32)']( - wallet.address, - selfPermitTest.address, - value, - constants.MaxUint256, - v, - r, - s - ) - expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(value) - - await expect(selfPermitTest.selfPermit(token.address, value, constants.MaxUint256, v, r, s)).to.be.revertedWith( - 'ERC20Permit: invalid signature' - ) - }) - }) - - describe('#selfPermitIfNecessary', () => { - const value = 789 - - it('works', async () => { - const { v, r, s } = await getPermitSignature(wallet, token, selfPermitTest.address, value) - - expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(0) - await selfPermitTest.selfPermitIfNecessary(token.address, value, constants.MaxUint256, v, r, s) - expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(value) - }) - - it('does not fail if permit is submitted externally', async () => { - const { v, r, s } = await getPermitSignature(wallet, token, selfPermitTest.address, value) - - expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(0) - await token['permit(address,address,uint256,uint256,uint8,bytes32,bytes32)']( - wallet.address, - selfPermitTest.address, - value, - constants.MaxUint256, - v, - r, - s - ) - expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(value) - - await selfPermitTest.selfPermitIfNecessary(token.address, value, constants.MaxUint256, v, r, s) - }) - }) - - describe('#selfPermitAllowed', () => { - it('works', async () => { - const { v, r, s } = await getPermitSignature(wallet, token, selfPermitTest.address, constants.MaxUint256) - - expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(0) - await expect(selfPermitTest.selfPermitAllowed(token.address, 0, constants.MaxUint256, v, r, s)) - .to.emit(token, 'Approval') - .withArgs(wallet.address, selfPermitTest.address, constants.MaxUint256) - expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(constants.MaxUint256) - }) - - it('fails if permit is submitted externally', async () => { - const { v, r, s } = await getPermitSignature(wallet, token, selfPermitTest.address, constants.MaxUint256) - - expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(0) - await token['permit(address,address,uint256,uint256,bool,uint8,bytes32,bytes32)']( - wallet.address, - selfPermitTest.address, - 0, - constants.MaxUint256, - true, - v, - r, - s - ) - expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(constants.MaxUint256) - - await expect( - selfPermitTest.selfPermitAllowed(token.address, 0, constants.MaxUint256, v, r, s) - ).to.be.revertedWith('TestERC20PermitAllowed::permit: wrong nonce') - }) - }) - - describe('#selfPermitAllowedIfNecessary', () => { - it('works', async () => { - const { v, r, s } = await getPermitSignature(wallet, token, selfPermitTest.address, constants.MaxUint256) - - expect(await token.allowance(wallet.address, selfPermitTest.address)).to.eq(0) - await expect(selfPermitTest.selfPermitAllowedIfNecessary(token.address, 0, constants.MaxUint256, v, r, s)) - .to.emit(token, 'Approval') - .withArgs(wallet.address, selfPermitTest.address, constants.MaxUint256) - expect(await token.allowance(wallet.address, selfPermitTest.address)).to.eq(constants.MaxUint256) - }) - - it('skips if already max approved', async () => { - const { v, r, s } = await getPermitSignature(wallet, token, selfPermitTest.address, constants.MaxUint256) - - expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(0) - await token.approve(selfPermitTest.address, constants.MaxUint256) - await expect( - selfPermitTest.selfPermitAllowedIfNecessary(token.address, 0, constants.MaxUint256, v, r, s) - ).to.not.emit(token, 'Approval') - expect(await token.allowance(wallet.address, selfPermitTest.address)).to.eq(constants.MaxUint256) - }) - - it('does not fail if permit is submitted externally', async () => { - const { v, r, s } = await getPermitSignature(wallet, token, selfPermitTest.address, constants.MaxUint256) - - expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(0) - await token['permit(address,address,uint256,uint256,bool,uint8,bytes32,bytes32)']( - wallet.address, - selfPermitTest.address, - 0, - constants.MaxUint256, - true, - v, - r, - s - ) - expect(await token.allowance(wallet.address, selfPermitTest.address)).to.be.eq(constants.MaxUint256) - - await selfPermitTest.selfPermitAllowedIfNecessary(token.address, 0, constants.MaxUint256, v, r, s) - }) - }) -}) diff --git a/lib/v3-periphery/test/SwapRouter.gas.spec.ts b/lib/v3-periphery/test/SwapRouter.gas.spec.ts deleted file mode 100644 index fb4a0d0..0000000 --- a/lib/v3-periphery/test/SwapRouter.gas.spec.ts +++ /dev/null @@ -1,453 +0,0 @@ -import { abi as IUniswapV3PoolABI } from '@uniswap/v3-core/artifacts/contracts/interfaces/IUniswapV3Pool.sol/IUniswapV3Pool.json' -import { Fixture } from 'ethereum-waffle' -import { BigNumber, constants, ContractTransaction, Wallet } from 'ethers' -import { ethers, waffle } from 'hardhat' -import { IUniswapV3Pool, IWETH9, MockTimeSwapRouter, TestERC20 } from '../typechain' -import completeFixture from './shared/completeFixture' -import { FeeAmount, TICK_SPACINGS } from './shared/constants' -import { encodePriceSqrt } from './shared/encodePriceSqrt' -import { expandTo18Decimals } from './shared/expandTo18Decimals' -import { expect } from './shared/expect' -import { encodePath } from './shared/path' -import snapshotGasCost from './shared/snapshotGasCost' -import { getMaxTick, getMinTick } from './shared/ticks' - -describe('SwapRouter gas tests', function () { - this.timeout(40000) - let wallet: Wallet - let trader: Wallet - - const swapRouterFixture: Fixture<{ - weth9: IWETH9 - router: MockTimeSwapRouter - tokens: [TestERC20, TestERC20, TestERC20] - pools: [IUniswapV3Pool, IUniswapV3Pool, IUniswapV3Pool] - }> = async (wallets, provider) => { - const { weth9, factory, router, tokens, nft } = await completeFixture(wallets, provider) - - // approve & fund wallets - for (const token of tokens) { - await token.approve(router.address, constants.MaxUint256) - await token.approve(nft.address, constants.MaxUint256) - await token.connect(trader).approve(router.address, constants.MaxUint256) - await token.transfer(trader.address, expandTo18Decimals(1_000_000)) - } - - const liquidity = 1000000 - async function createPool(tokenAddressA: string, tokenAddressB: string) { - if (tokenAddressA.toLowerCase() > tokenAddressB.toLowerCase()) - [tokenAddressA, tokenAddressB] = [tokenAddressB, tokenAddressA] - - await nft.createAndInitializePoolIfNecessary( - tokenAddressA, - tokenAddressB, - FeeAmount.MEDIUM, - encodePriceSqrt(100005, 100000) // we don't want to cross any ticks - ) - - const liquidityParams = { - token0: tokenAddressA, - token1: tokenAddressB, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - recipient: wallet.address, - amount0Desired: 1000000, - amount1Desired: 1000000, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - } - - return nft.mint(liquidityParams) - } - - async function createPoolWETH9(tokenAddress: string) { - await weth9.deposit({ value: liquidity * 2 }) - await weth9.approve(nft.address, constants.MaxUint256) - return createPool(weth9.address, tokenAddress) - } - - // create pools - await createPool(tokens[0].address, tokens[1].address) - await createPool(tokens[1].address, tokens[2].address) - await createPoolWETH9(tokens[0].address) - - const poolAddresses = await Promise.all([ - factory.getPool(tokens[0].address, tokens[1].address, FeeAmount.MEDIUM), - factory.getPool(tokens[1].address, tokens[2].address, FeeAmount.MEDIUM), - factory.getPool(weth9.address, tokens[0].address, FeeAmount.MEDIUM), - ]) - - const pools = poolAddresses.map((poolAddress) => new ethers.Contract(poolAddress, IUniswapV3PoolABI, wallet)) as [ - IUniswapV3Pool, - IUniswapV3Pool, - IUniswapV3Pool - ] - - return { - weth9, - router, - tokens, - pools, - } - } - - let weth9: IWETH9 - let router: MockTimeSwapRouter - let tokens: [TestERC20, TestERC20, TestERC20] - let pools: [IUniswapV3Pool, IUniswapV3Pool, IUniswapV3Pool] - - let loadFixture: ReturnType - - before('create fixture loader', async () => { - const wallets = await (ethers as any).getSigners() - ;[wallet, trader] = wallets - - loadFixture = waffle.createFixtureLoader(wallets) - }) - - beforeEach('load fixture', async () => { - ;({ router, weth9, tokens, pools } = await loadFixture(swapRouterFixture)) - }) - - async function exactInput( - tokens: string[], - amountIn: number = 2, - amountOutMinimum: number = 1 - ): Promise { - const inputIsWETH = weth9.address === tokens[0] - const outputIsWETH9 = tokens[tokens.length - 1] === weth9.address - - const value = inputIsWETH ? amountIn : 0 - - const params = { - path: encodePath(tokens, new Array(tokens.length - 1).fill(FeeAmount.MEDIUM)), - recipient: outputIsWETH9 ? constants.AddressZero : trader.address, - deadline: 1, - amountIn, - amountOutMinimum: outputIsWETH9 ? 0 : amountOutMinimum, // save on calldata, - } - - const data = [router.interface.encodeFunctionData('exactInput', [params])] - if (outputIsWETH9) data.push(router.interface.encodeFunctionData('unwrapWETH9', [amountOutMinimum, trader.address])) - - // optimized for the gas test - return data.length === 1 - ? router.connect(trader).exactInput(params, { value }) - : router.connect(trader).multicall(data, { value }) - } - - async function exactInputSingle( - tokenIn: string, - tokenOut: string, - amountIn: number = 3, - amountOutMinimum: number = 1, - sqrtPriceLimitX96?: BigNumber - ): Promise { - const inputIsWETH = weth9.address === tokenIn - const outputIsWETH9 = tokenOut === weth9.address - - const value = inputIsWETH ? amountIn : 0 - - const params = { - tokenIn, - tokenOut, - fee: FeeAmount.MEDIUM, - sqrtPriceLimitX96: sqrtPriceLimitX96 ?? 0, - recipient: outputIsWETH9 ? constants.AddressZero : trader.address, - deadline: 1, - amountIn, - amountOutMinimum: outputIsWETH9 ? 0 : amountOutMinimum, // save on calldata - } - - const data = [router.interface.encodeFunctionData('exactInputSingle', [params])] - if (outputIsWETH9) data.push(router.interface.encodeFunctionData('unwrapWETH9', [amountOutMinimum, trader.address])) - - // optimized for the gas test - return data.length === 1 - ? router.connect(trader).exactInputSingle(params, { value }) - : router.connect(trader).multicall(data, { value }) - } - - async function exactOutput(tokens: string[]): Promise { - const amountInMaximum = 10 // we don't care - const amountOut = 1 - - const inputIsWETH9 = tokens[0] === weth9.address - const outputIsWETH9 = tokens[tokens.length - 1] === weth9.address - - const value = inputIsWETH9 ? amountInMaximum : 0 - - const params = { - path: encodePath(tokens.slice().reverse(), new Array(tokens.length - 1).fill(FeeAmount.MEDIUM)), - recipient: outputIsWETH9 ? constants.AddressZero : trader.address, - deadline: 1, - amountOut, - amountInMaximum, - } - - const data = [router.interface.encodeFunctionData('exactOutput', [params])] - if (inputIsWETH9) data.push(router.interface.encodeFunctionData('refundETH')) - if (outputIsWETH9) data.push(router.interface.encodeFunctionData('unwrapWETH9', [amountOut, trader.address])) - - return router.connect(trader).multicall(data, { value }) - } - - async function exactOutputSingle( - tokenIn: string, - tokenOut: string, - amountOut: number = 1, - amountInMaximum: number = 3, - sqrtPriceLimitX96?: BigNumber - ): Promise { - const inputIsWETH9 = tokenIn === weth9.address - const outputIsWETH9 = tokenOut === weth9.address - - const value = inputIsWETH9 ? amountInMaximum : 0 - - const params = { - tokenIn, - tokenOut, - fee: FeeAmount.MEDIUM, - recipient: outputIsWETH9 ? constants.AddressZero : trader.address, - deadline: 1, - amountOut, - amountInMaximum, - sqrtPriceLimitX96: sqrtPriceLimitX96 ?? 0, - } - - const data = [router.interface.encodeFunctionData('exactOutputSingle', [params])] - if (inputIsWETH9) data.push(router.interface.encodeFunctionData('unwrapWETH9', [0, trader.address])) - if (outputIsWETH9) data.push(router.interface.encodeFunctionData('unwrapWETH9', [amountOut, trader.address])) - - return router.connect(trader).multicall(data, { value }) - } - - // TODO should really throw this in the fixture - beforeEach('intialize feeGrowthGlobals', async () => { - await exactInput([tokens[0].address, tokens[1].address], 1, 0) - await exactInput([tokens[1].address, tokens[0].address], 1, 0) - await exactInput([tokens[1].address, tokens[2].address], 1, 0) - await exactInput([tokens[2].address, tokens[1].address], 1, 0) - await exactInput([tokens[0].address, weth9.address], 1, 0) - await exactInput([weth9.address, tokens[0].address], 1, 0) - }) - - beforeEach('ensure feeGrowthGlobals are >0', async () => { - const slots = await Promise.all( - pools.map((pool) => - Promise.all([ - pool.feeGrowthGlobal0X128().then((f) => f.toString()), - pool.feeGrowthGlobal1X128().then((f) => f.toString()), - ]) - ) - ) - - expect(slots).to.deep.eq([ - ['340290874192793283295456993856614', '340290874192793283295456993856614'], - ['340290874192793283295456993856614', '340290874192793283295456993856614'], - ['340290874192793283295456993856614', '340290874192793283295456993856614'], - ]) - }) - - beforeEach('ensure ticks are 0 before', async () => { - const slots = await Promise.all(pools.map((pool) => pool.slot0().then(({ tick }) => tick))) - expect(slots).to.deep.eq([0, 0, 0]) - }) - - afterEach('ensure ticks are 0 after', async () => { - const slots = await Promise.all(pools.map((pool) => pool.slot0().then(({ tick }) => tick))) - expect(slots).to.deep.eq([0, 0, 0]) - }) - - describe('#exactInput', () => { - it('0 -> 1', async () => { - await snapshotGasCost(exactInput(tokens.slice(0, 2).map((token) => token.address))) - }) - - it('0 -> 1 minimal', async () => { - const calleeFactory = await ethers.getContractFactory('TestUniswapV3Callee') - const callee = await calleeFactory.deploy() - - await tokens[0].connect(trader).approve(callee.address, constants.MaxUint256) - await snapshotGasCost(callee.connect(trader).swapExact0For1(pools[0].address, 2, trader.address, '4295128740')) - }) - - it('0 -> 1 -> 2', async () => { - await snapshotGasCost( - exactInput( - tokens.map((token) => token.address), - 3 - ) - ) - }) - - it('WETH9 -> 0', async () => { - await snapshotGasCost( - exactInput( - [weth9.address, tokens[0].address], - weth9.address.toLowerCase() < tokens[0].address.toLowerCase() ? 2 : 3 - ) - ) - }) - - it('0 -> WETH9', async () => { - await snapshotGasCost( - exactInput( - [tokens[0].address, weth9.address], - tokens[0].address.toLowerCase() < weth9.address.toLowerCase() ? 2 : 3 - ) - ) - }) - - it('2 trades (via router)', async () => { - await weth9.connect(trader).deposit({ value: 3 }) - await weth9.connect(trader).approve(router.address, constants.MaxUint256) - const swap0 = { - path: encodePath([weth9.address, tokens[0].address], [FeeAmount.MEDIUM]), - recipient: constants.AddressZero, - deadline: 1, - amountIn: 3, - amountOutMinimum: 0, // save on calldata - } - - const swap1 = { - path: encodePath([tokens[1].address, tokens[0].address], [FeeAmount.MEDIUM]), - recipient: constants.AddressZero, - deadline: 1, - amountIn: 3, - amountOutMinimum: 0, // save on calldata - } - - const data = [ - router.interface.encodeFunctionData('exactInput', [swap0]), - router.interface.encodeFunctionData('exactInput', [swap1]), - router.interface.encodeFunctionData('sweepToken', [tokens[0].address, 2, trader.address]), - ] - - await snapshotGasCost(router.connect(trader).multicall(data)) - }) - - it('3 trades (directly to sender)', async () => { - await weth9.connect(trader).deposit({ value: 3 }) - await weth9.connect(trader).approve(router.address, constants.MaxUint256) - const swap0 = { - path: encodePath([weth9.address, tokens[0].address], [FeeAmount.MEDIUM]), - recipient: trader.address, - deadline: 1, - amountIn: 3, - amountOutMinimum: 1, - } - - const swap1 = { - path: encodePath([tokens[0].address, tokens[1].address], [FeeAmount.MEDIUM]), - recipient: trader.address, - deadline: 1, - amountIn: 3, - amountOutMinimum: 1, - } - - const swap2 = { - path: encodePath([tokens[1].address, tokens[2].address], [FeeAmount.MEDIUM]), - recipient: trader.address, - deadline: 1, - amountIn: 3, - amountOutMinimum: 1, - } - - const data = [ - router.interface.encodeFunctionData('exactInput', [swap0]), - router.interface.encodeFunctionData('exactInput', [swap1]), - router.interface.encodeFunctionData('exactInput', [swap2]), - ] - - await snapshotGasCost(router.connect(trader).multicall(data)) - }) - }) - - it('3 trades (directly to sender)', async () => { - await weth9.connect(trader).deposit({ value: 3 }) - await weth9.connect(trader).approve(router.address, constants.MaxUint256) - const swap0 = { - path: encodePath([weth9.address, tokens[0].address], [FeeAmount.MEDIUM]), - recipient: trader.address, - deadline: 1, - amountIn: 3, - amountOutMinimum: 1, - } - - const swap1 = { - path: encodePath([tokens[1].address, tokens[0].address], [FeeAmount.MEDIUM]), - recipient: trader.address, - deadline: 1, - amountIn: 3, - amountOutMinimum: 1, - } - - const data = [ - router.interface.encodeFunctionData('exactInput', [swap0]), - router.interface.encodeFunctionData('exactInput', [swap1]), - ] - - await snapshotGasCost(router.connect(trader).multicall(data)) - }) - - describe('#exactInputSingle', () => { - it('0 -> 1', async () => { - await snapshotGasCost(exactInputSingle(tokens[0].address, tokens[1].address)) - }) - - it('WETH9 -> 0', async () => { - await snapshotGasCost( - exactInputSingle( - weth9.address, - tokens[0].address, - weth9.address.toLowerCase() < tokens[0].address.toLowerCase() ? 2 : 3 - ) - ) - }) - - it('0 -> WETH9', async () => { - await snapshotGasCost( - exactInputSingle( - tokens[0].address, - weth9.address, - tokens[0].address.toLowerCase() < weth9.address.toLowerCase() ? 2 : 3 - ) - ) - }) - }) - - describe('#exactOutput', () => { - it('0 -> 1', async () => { - await snapshotGasCost(exactOutput(tokens.slice(0, 2).map((token) => token.address))) - }) - - it('0 -> 1 -> 2', async () => { - await snapshotGasCost(exactOutput(tokens.map((token) => token.address))) - }) - - it('WETH9 -> 0', async () => { - await snapshotGasCost(exactOutput([weth9.address, tokens[0].address])) - }) - - it('0 -> WETH9', async () => { - await snapshotGasCost(exactOutput([tokens[0].address, weth9.address])) - }) - }) - - describe('#exactOutputSingle', () => { - it('0 -> 1', async () => { - await snapshotGasCost(exactOutputSingle(tokens[0].address, tokens[1].address)) - }) - - it('WETH9 -> 0', async () => { - await snapshotGasCost(exactOutputSingle(weth9.address, tokens[0].address)) - }) - - it('0 -> WETH9', async () => { - await snapshotGasCost(exactOutputSingle(tokens[0].address, weth9.address)) - }) - }) -}) diff --git a/lib/v3-periphery/test/SwapRouter.spec.ts b/lib/v3-periphery/test/SwapRouter.spec.ts deleted file mode 100644 index a3d8f6d..0000000 --- a/lib/v3-periphery/test/SwapRouter.spec.ts +++ /dev/null @@ -1,916 +0,0 @@ -import { Fixture } from 'ethereum-waffle' -import { BigNumber, constants, Contract, ContractTransaction, Wallet } from 'ethers' -import { waffle, ethers } from 'hardhat' -import { IWETH9, MockTimeNonfungiblePositionManager, MockTimeSwapRouter, TestERC20 } from '../typechain' -import completeFixture from './shared/completeFixture' -import { FeeAmount, TICK_SPACINGS } from './shared/constants' -import { encodePriceSqrt } from './shared/encodePriceSqrt' -import { expandTo18Decimals } from './shared/expandTo18Decimals' -import { expect } from './shared/expect' -import { encodePath } from './shared/path' -import { getMaxTick, getMinTick } from './shared/ticks' -import { computePoolAddress } from './shared/computePoolAddress' - -describe('SwapRouter', function () { - this.timeout(40000) - let wallet: Wallet - let trader: Wallet - - const swapRouterFixture: Fixture<{ - weth9: IWETH9 - factory: Contract - router: MockTimeSwapRouter - nft: MockTimeNonfungiblePositionManager - tokens: [TestERC20, TestERC20, TestERC20] - }> = async (wallets, provider) => { - const { weth9, factory, router, tokens, nft } = await completeFixture(wallets, provider) - - // approve & fund wallets - for (const token of tokens) { - await token.approve(router.address, constants.MaxUint256) - await token.approve(nft.address, constants.MaxUint256) - await token.connect(trader).approve(router.address, constants.MaxUint256) - await token.transfer(trader.address, expandTo18Decimals(1_000_000)) - } - - return { - weth9, - factory, - router, - tokens, - nft, - } - } - - let factory: Contract - let weth9: IWETH9 - let router: MockTimeSwapRouter - let nft: MockTimeNonfungiblePositionManager - let tokens: [TestERC20, TestERC20, TestERC20] - let getBalances: ( - who: string - ) => Promise<{ - weth9: BigNumber - token0: BigNumber - token1: BigNumber - token2: BigNumber - }> - - let loadFixture: ReturnType - - before('create fixture loader', async () => { - ;[wallet, trader] = await (ethers as any).getSigners() - loadFixture = waffle.createFixtureLoader([wallet, trader]) - }) - - // helper for getting weth and token balances - beforeEach('load fixture', async () => { - ;({ router, weth9, factory, tokens, nft } = await loadFixture(swapRouterFixture)) - - getBalances = async (who: string) => { - const balances = await Promise.all([ - weth9.balanceOf(who), - tokens[0].balanceOf(who), - tokens[1].balanceOf(who), - tokens[2].balanceOf(who), - ]) - return { - weth9: balances[0], - token0: balances[1], - token1: balances[2], - token2: balances[3], - } - } - }) - - // ensure the swap router never ends up with a balance - afterEach('load fixture', async () => { - const balances = await getBalances(router.address) - expect(Object.values(balances).every((b) => b.eq(0))).to.be.eq(true) - const balance = await waffle.provider.getBalance(router.address) - expect(balance.eq(0)).to.be.eq(true) - }) - - it('bytecode size', async () => { - expect(((await router.provider.getCode(router.address)).length - 2) / 2).to.matchSnapshot() - }) - - describe('swaps', () => { - const liquidity = 1000000 - async function createPool(tokenAddressA: string, tokenAddressB: string) { - if (tokenAddressA.toLowerCase() > tokenAddressB.toLowerCase()) - [tokenAddressA, tokenAddressB] = [tokenAddressB, tokenAddressA] - - await nft.createAndInitializePoolIfNecessary( - tokenAddressA, - tokenAddressB, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - - const liquidityParams = { - token0: tokenAddressA, - token1: tokenAddressB, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - recipient: wallet.address, - amount0Desired: 1000000, - amount1Desired: 1000000, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - } - - return nft.mint(liquidityParams) - } - - async function createPoolWETH9(tokenAddress: string) { - await weth9.deposit({ value: liquidity }) - await weth9.approve(nft.address, constants.MaxUint256) - return createPool(weth9.address, tokenAddress) - } - - beforeEach('create 0-1 and 1-2 pools', async () => { - await createPool(tokens[0].address, tokens[1].address) - await createPool(tokens[1].address, tokens[2].address) - }) - - describe('#exactInput', () => { - async function exactInput( - tokens: string[], - amountIn: number = 3, - amountOutMinimum: number = 1 - ): Promise { - const inputIsWETH = weth9.address === tokens[0] - const outputIsWETH9 = tokens[tokens.length - 1] === weth9.address - - const value = inputIsWETH ? amountIn : 0 - - const params = { - path: encodePath(tokens, new Array(tokens.length - 1).fill(FeeAmount.MEDIUM)), - recipient: outputIsWETH9 ? constants.AddressZero : trader.address, - deadline: 1, - amountIn, - amountOutMinimum, - } - - const data = [router.interface.encodeFunctionData('exactInput', [params])] - if (outputIsWETH9) - data.push(router.interface.encodeFunctionData('unwrapWETH9', [amountOutMinimum, trader.address])) - - // ensure that the swap fails if the limit is any tighter - params.amountOutMinimum += 1 - await expect(router.connect(trader).exactInput(params, { value })).to.be.revertedWith('Too little received') - params.amountOutMinimum -= 1 - - // optimized for the gas test - return data.length === 1 - ? router.connect(trader).exactInput(params, { value }) - : router.connect(trader).multicall(data, { value }) - } - - describe('single-pool', () => { - it('0 -> 1', async () => { - const pool = await factory.getPool(tokens[0].address, tokens[1].address, FeeAmount.MEDIUM) - - // get balances before - const poolBefore = await getBalances(pool) - const traderBefore = await getBalances(trader.address) - - await exactInput(tokens.slice(0, 2).map((token) => token.address)) - - // get balances after - const poolAfter = await getBalances(pool) - const traderAfter = await getBalances(trader.address) - - expect(traderAfter.token0).to.be.eq(traderBefore.token0.sub(3)) - expect(traderAfter.token1).to.be.eq(traderBefore.token1.add(1)) - expect(poolAfter.token0).to.be.eq(poolBefore.token0.add(3)) - expect(poolAfter.token1).to.be.eq(poolBefore.token1.sub(1)) - }) - - it('1 -> 0', async () => { - const pool = await factory.getPool(tokens[1].address, tokens[0].address, FeeAmount.MEDIUM) - - // get balances before - const poolBefore = await getBalances(pool) - const traderBefore = await getBalances(trader.address) - - await exactInput( - tokens - .slice(0, 2) - .reverse() - .map((token) => token.address) - ) - - // get balances after - const poolAfter = await getBalances(pool) - const traderAfter = await getBalances(trader.address) - - expect(traderAfter.token0).to.be.eq(traderBefore.token0.add(1)) - expect(traderAfter.token1).to.be.eq(traderBefore.token1.sub(3)) - expect(poolAfter.token0).to.be.eq(poolBefore.token0.sub(1)) - expect(poolAfter.token1).to.be.eq(poolBefore.token1.add(3)) - }) - }) - - describe('multi-pool', () => { - it('0 -> 1 -> 2', async () => { - const traderBefore = await getBalances(trader.address) - - await exactInput( - tokens.map((token) => token.address), - 5, - 1 - ) - - const traderAfter = await getBalances(trader.address) - - expect(traderAfter.token0).to.be.eq(traderBefore.token0.sub(5)) - expect(traderAfter.token2).to.be.eq(traderBefore.token2.add(1)) - }) - - it('2 -> 1 -> 0', async () => { - const traderBefore = await getBalances(trader.address) - - await exactInput(tokens.map((token) => token.address).reverse(), 5, 1) - - const traderAfter = await getBalances(trader.address) - - expect(traderAfter.token2).to.be.eq(traderBefore.token2.sub(5)) - expect(traderAfter.token0).to.be.eq(traderBefore.token0.add(1)) - }) - - it('events', async () => { - await expect( - exactInput( - tokens.map((token) => token.address), - 5, - 1 - ) - ) - .to.emit(tokens[0], 'Transfer') - .withArgs( - trader.address, - computePoolAddress(factory.address, [tokens[0].address, tokens[1].address], FeeAmount.MEDIUM), - 5 - ) - .to.emit(tokens[1], 'Transfer') - .withArgs( - computePoolAddress(factory.address, [tokens[0].address, tokens[1].address], FeeAmount.MEDIUM), - router.address, - 3 - ) - .to.emit(tokens[1], 'Transfer') - .withArgs( - router.address, - computePoolAddress(factory.address, [tokens[1].address, tokens[2].address], FeeAmount.MEDIUM), - 3 - ) - .to.emit(tokens[2], 'Transfer') - .withArgs( - computePoolAddress(factory.address, [tokens[1].address, tokens[2].address], FeeAmount.MEDIUM), - trader.address, - 1 - ) - }) - }) - - describe('ETH input', () => { - describe('WETH9', () => { - beforeEach(async () => { - await createPoolWETH9(tokens[0].address) - }) - - it('WETH9 -> 0', async () => { - const pool = await factory.getPool(weth9.address, tokens[0].address, FeeAmount.MEDIUM) - - // get balances before - const poolBefore = await getBalances(pool) - const traderBefore = await getBalances(trader.address) - - await expect(exactInput([weth9.address, tokens[0].address])) - .to.emit(weth9, 'Deposit') - .withArgs(router.address, 3) - - // get balances after - const poolAfter = await getBalances(pool) - const traderAfter = await getBalances(trader.address) - - expect(traderAfter.token0).to.be.eq(traderBefore.token0.add(1)) - expect(poolAfter.weth9).to.be.eq(poolBefore.weth9.add(3)) - expect(poolAfter.token0).to.be.eq(poolBefore.token0.sub(1)) - }) - - it('WETH9 -> 0 -> 1', async () => { - const traderBefore = await getBalances(trader.address) - - await expect(exactInput([weth9.address, tokens[0].address, tokens[1].address], 5)) - .to.emit(weth9, 'Deposit') - .withArgs(router.address, 5) - - const traderAfter = await getBalances(trader.address) - - expect(traderAfter.token1).to.be.eq(traderBefore.token1.add(1)) - }) - }) - }) - - describe('ETH output', () => { - describe('WETH9', () => { - beforeEach(async () => { - await createPoolWETH9(tokens[0].address) - await createPoolWETH9(tokens[1].address) - }) - - it('0 -> WETH9', async () => { - const pool = await factory.getPool(tokens[0].address, weth9.address, FeeAmount.MEDIUM) - - // get balances before - const poolBefore = await getBalances(pool) - const traderBefore = await getBalances(trader.address) - - await expect(exactInput([tokens[0].address, weth9.address])) - .to.emit(weth9, 'Withdrawal') - .withArgs(router.address, 1) - - // get balances after - const poolAfter = await getBalances(pool) - const traderAfter = await getBalances(trader.address) - - expect(traderAfter.token0).to.be.eq(traderBefore.token0.sub(3)) - expect(poolAfter.weth9).to.be.eq(poolBefore.weth9.sub(1)) - expect(poolAfter.token0).to.be.eq(poolBefore.token0.add(3)) - }) - - it('0 -> 1 -> WETH9', async () => { - // get balances before - const traderBefore = await getBalances(trader.address) - - await expect(exactInput([tokens[0].address, tokens[1].address, weth9.address], 5)) - .to.emit(weth9, 'Withdrawal') - .withArgs(router.address, 1) - - // get balances after - const traderAfter = await getBalances(trader.address) - - expect(traderAfter.token0).to.be.eq(traderBefore.token0.sub(5)) - }) - }) - }) - }) - - describe('#exactInputSingle', () => { - async function exactInputSingle( - tokenIn: string, - tokenOut: string, - amountIn: number = 3, - amountOutMinimum: number = 1, - sqrtPriceLimitX96?: BigNumber - ): Promise { - const inputIsWETH = weth9.address === tokenIn - const outputIsWETH9 = tokenOut === weth9.address - - const value = inputIsWETH ? amountIn : 0 - - const params = { - tokenIn, - tokenOut, - fee: FeeAmount.MEDIUM, - sqrtPriceLimitX96: - sqrtPriceLimitX96 ?? tokenIn.toLowerCase() < tokenOut.toLowerCase() - ? BigNumber.from('4295128740') - : BigNumber.from('1461446703485210103287273052203988822378723970341'), - recipient: outputIsWETH9 ? constants.AddressZero : trader.address, - deadline: 1, - amountIn, - amountOutMinimum, - } - - const data = [router.interface.encodeFunctionData('exactInputSingle', [params])] - if (outputIsWETH9) - data.push(router.interface.encodeFunctionData('unwrapWETH9', [amountOutMinimum, trader.address])) - - // ensure that the swap fails if the limit is any tighter - params.amountOutMinimum += 1 - await expect(router.connect(trader).exactInputSingle(params, { value })).to.be.revertedWith( - 'Too little received' - ) - params.amountOutMinimum -= 1 - - // optimized for the gas test - return data.length === 1 - ? router.connect(trader).exactInputSingle(params, { value }) - : router.connect(trader).multicall(data, { value }) - } - - it('0 -> 1', async () => { - const pool = await factory.getPool(tokens[0].address, tokens[1].address, FeeAmount.MEDIUM) - - // get balances before - const poolBefore = await getBalances(pool) - const traderBefore = await getBalances(trader.address) - - await exactInputSingle(tokens[0].address, tokens[1].address) - - // get balances after - const poolAfter = await getBalances(pool) - const traderAfter = await getBalances(trader.address) - - expect(traderAfter.token0).to.be.eq(traderBefore.token0.sub(3)) - expect(traderAfter.token1).to.be.eq(traderBefore.token1.add(1)) - expect(poolAfter.token0).to.be.eq(poolBefore.token0.add(3)) - expect(poolAfter.token1).to.be.eq(poolBefore.token1.sub(1)) - }) - - it('1 -> 0', async () => { - const pool = await factory.getPool(tokens[1].address, tokens[0].address, FeeAmount.MEDIUM) - - // get balances before - const poolBefore = await getBalances(pool) - const traderBefore = await getBalances(trader.address) - - await exactInputSingle(tokens[1].address, tokens[0].address) - - // get balances after - const poolAfter = await getBalances(pool) - const traderAfter = await getBalances(trader.address) - - expect(traderAfter.token0).to.be.eq(traderBefore.token0.add(1)) - expect(traderAfter.token1).to.be.eq(traderBefore.token1.sub(3)) - expect(poolAfter.token0).to.be.eq(poolBefore.token0.sub(1)) - expect(poolAfter.token1).to.be.eq(poolBefore.token1.add(3)) - }) - - describe('ETH input', () => { - describe('WETH9', () => { - beforeEach(async () => { - await createPoolWETH9(tokens[0].address) - }) - - it('WETH9 -> 0', async () => { - const pool = await factory.getPool(weth9.address, tokens[0].address, FeeAmount.MEDIUM) - - // get balances before - const poolBefore = await getBalances(pool) - const traderBefore = await getBalances(trader.address) - - await expect(exactInputSingle(weth9.address, tokens[0].address)) - .to.emit(weth9, 'Deposit') - .withArgs(router.address, 3) - - // get balances after - const poolAfter = await getBalances(pool) - const traderAfter = await getBalances(trader.address) - - expect(traderAfter.token0).to.be.eq(traderBefore.token0.add(1)) - expect(poolAfter.weth9).to.be.eq(poolBefore.weth9.add(3)) - expect(poolAfter.token0).to.be.eq(poolBefore.token0.sub(1)) - }) - }) - }) - - describe('ETH output', () => { - describe('WETH9', () => { - beforeEach(async () => { - await createPoolWETH9(tokens[0].address) - await createPoolWETH9(tokens[1].address) - }) - - it('0 -> WETH9', async () => { - const pool = await factory.getPool(tokens[0].address, weth9.address, FeeAmount.MEDIUM) - - // get balances before - const poolBefore = await getBalances(pool) - const traderBefore = await getBalances(trader.address) - - await expect(exactInputSingle(tokens[0].address, weth9.address)) - .to.emit(weth9, 'Withdrawal') - .withArgs(router.address, 1) - - // get balances after - const poolAfter = await getBalances(pool) - const traderAfter = await getBalances(trader.address) - - expect(traderAfter.token0).to.be.eq(traderBefore.token0.sub(3)) - expect(poolAfter.weth9).to.be.eq(poolBefore.weth9.sub(1)) - expect(poolAfter.token0).to.be.eq(poolBefore.token0.add(3)) - }) - }) - }) - }) - - describe('#exactOutput', () => { - async function exactOutput( - tokens: string[], - amountOut: number = 1, - amountInMaximum: number = 3 - ): Promise { - const inputIsWETH9 = tokens[0] === weth9.address - const outputIsWETH9 = tokens[tokens.length - 1] === weth9.address - - const value = inputIsWETH9 ? amountInMaximum : 0 - - const params = { - path: encodePath(tokens.slice().reverse(), new Array(tokens.length - 1).fill(FeeAmount.MEDIUM)), - recipient: outputIsWETH9 ? constants.AddressZero : trader.address, - deadline: 1, - amountOut, - amountInMaximum, - } - - const data = [router.interface.encodeFunctionData('exactOutput', [params])] - if (inputIsWETH9) data.push(router.interface.encodeFunctionData('unwrapWETH9', [0, trader.address])) - if (outputIsWETH9) data.push(router.interface.encodeFunctionData('unwrapWETH9', [amountOut, trader.address])) - - // ensure that the swap fails if the limit is any tighter - params.amountInMaximum -= 1 - await expect(router.connect(trader).exactOutput(params, { value })).to.be.revertedWith('Too much requested') - params.amountInMaximum += 1 - - return router.connect(trader).multicall(data, { value }) - } - - describe('single-pool', () => { - it('0 -> 1', async () => { - const pool = await factory.getPool(tokens[0].address, tokens[1].address, FeeAmount.MEDIUM) - - // get balances before - const poolBefore = await getBalances(pool) - const traderBefore = await getBalances(trader.address) - - await exactOutput(tokens.slice(0, 2).map((token) => token.address)) - - // get balances after - const poolAfter = await getBalances(pool) - const traderAfter = await getBalances(trader.address) - - expect(traderAfter.token0).to.be.eq(traderBefore.token0.sub(3)) - expect(traderAfter.token1).to.be.eq(traderBefore.token1.add(1)) - expect(poolAfter.token0).to.be.eq(poolBefore.token0.add(3)) - expect(poolAfter.token1).to.be.eq(poolBefore.token1.sub(1)) - }) - - it('1 -> 0', async () => { - const pool = await factory.getPool(tokens[1].address, tokens[0].address, FeeAmount.MEDIUM) - - // get balances before - const poolBefore = await getBalances(pool) - const traderBefore = await getBalances(trader.address) - - await exactOutput( - tokens - .slice(0, 2) - .reverse() - .map((token) => token.address) - ) - - // get balances after - const poolAfter = await getBalances(pool) - const traderAfter = await getBalances(trader.address) - - expect(traderAfter.token0).to.be.eq(traderBefore.token0.add(1)) - expect(traderAfter.token1).to.be.eq(traderBefore.token1.sub(3)) - expect(poolAfter.token0).to.be.eq(poolBefore.token0.sub(1)) - expect(poolAfter.token1).to.be.eq(poolBefore.token1.add(3)) - }) - }) - - describe('multi-pool', () => { - it('0 -> 1 -> 2', async () => { - const traderBefore = await getBalances(trader.address) - - await exactOutput( - tokens.map((token) => token.address), - 1, - 5 - ) - - const traderAfter = await getBalances(trader.address) - - expect(traderAfter.token0).to.be.eq(traderBefore.token0.sub(5)) - expect(traderAfter.token2).to.be.eq(traderBefore.token2.add(1)) - }) - - it('2 -> 1 -> 0', async () => { - const traderBefore = await getBalances(trader.address) - - await exactOutput(tokens.map((token) => token.address).reverse(), 1, 5) - - const traderAfter = await getBalances(trader.address) - - expect(traderAfter.token2).to.be.eq(traderBefore.token2.sub(5)) - expect(traderAfter.token0).to.be.eq(traderBefore.token0.add(1)) - }) - - it('events', async () => { - await expect( - exactOutput( - tokens.map((token) => token.address), - 1, - 5 - ) - ) - .to.emit(tokens[2], 'Transfer') - .withArgs( - computePoolAddress(factory.address, [tokens[2].address, tokens[1].address], FeeAmount.MEDIUM), - trader.address, - 1 - ) - .to.emit(tokens[1], 'Transfer') - .withArgs( - computePoolAddress(factory.address, [tokens[1].address, tokens[0].address], FeeAmount.MEDIUM), - computePoolAddress(factory.address, [tokens[2].address, tokens[1].address], FeeAmount.MEDIUM), - 3 - ) - .to.emit(tokens[0], 'Transfer') - .withArgs( - trader.address, - computePoolAddress(factory.address, [tokens[1].address, tokens[0].address], FeeAmount.MEDIUM), - 5 - ) - }) - }) - - describe('ETH input', () => { - describe('WETH9', () => { - beforeEach(async () => { - await createPoolWETH9(tokens[0].address) - }) - - it('WETH9 -> 0', async () => { - const pool = await factory.getPool(weth9.address, tokens[0].address, FeeAmount.MEDIUM) - - // get balances before - const poolBefore = await getBalances(pool) - const traderBefore = await getBalances(trader.address) - - await expect(exactOutput([weth9.address, tokens[0].address])) - .to.emit(weth9, 'Deposit') - .withArgs(router.address, 3) - - // get balances after - const poolAfter = await getBalances(pool) - const traderAfter = await getBalances(trader.address) - - expect(traderAfter.token0).to.be.eq(traderBefore.token0.add(1)) - expect(poolAfter.weth9).to.be.eq(poolBefore.weth9.add(3)) - expect(poolAfter.token0).to.be.eq(poolBefore.token0.sub(1)) - }) - - it('WETH9 -> 0 -> 1', async () => { - const traderBefore = await getBalances(trader.address) - - await expect(exactOutput([weth9.address, tokens[0].address, tokens[1].address], 1, 5)) - .to.emit(weth9, 'Deposit') - .withArgs(router.address, 5) - - const traderAfter = await getBalances(trader.address) - - expect(traderAfter.token1).to.be.eq(traderBefore.token1.add(1)) - }) - }) - }) - - describe('ETH output', () => { - describe('WETH9', () => { - beforeEach(async () => { - await createPoolWETH9(tokens[0].address) - await createPoolWETH9(tokens[1].address) - }) - - it('0 -> WETH9', async () => { - const pool = await factory.getPool(tokens[0].address, weth9.address, FeeAmount.MEDIUM) - - // get balances before - const poolBefore = await getBalances(pool) - const traderBefore = await getBalances(trader.address) - - await expect(exactOutput([tokens[0].address, weth9.address])) - .to.emit(weth9, 'Withdrawal') - .withArgs(router.address, 1) - - // get balances after - const poolAfter = await getBalances(pool) - const traderAfter = await getBalances(trader.address) - - expect(traderAfter.token0).to.be.eq(traderBefore.token0.sub(3)) - expect(poolAfter.weth9).to.be.eq(poolBefore.weth9.sub(1)) - expect(poolAfter.token0).to.be.eq(poolBefore.token0.add(3)) - }) - - it('0 -> 1 -> WETH9', async () => { - // get balances before - const traderBefore = await getBalances(trader.address) - - await expect(exactOutput([tokens[0].address, tokens[1].address, weth9.address], 1, 5)) - .to.emit(weth9, 'Withdrawal') - .withArgs(router.address, 1) - - // get balances after - const traderAfter = await getBalances(trader.address) - - expect(traderAfter.token0).to.be.eq(traderBefore.token0.sub(5)) - }) - }) - }) - }) - - describe('#exactOutputSingle', () => { - async function exactOutputSingle( - tokenIn: string, - tokenOut: string, - amountOut: number = 1, - amountInMaximum: number = 3, - sqrtPriceLimitX96?: BigNumber - ): Promise { - const inputIsWETH9 = tokenIn === weth9.address - const outputIsWETH9 = tokenOut === weth9.address - - const value = inputIsWETH9 ? amountInMaximum : 0 - - const params = { - tokenIn, - tokenOut, - fee: FeeAmount.MEDIUM, - recipient: outputIsWETH9 ? constants.AddressZero : trader.address, - deadline: 1, - amountOut, - amountInMaximum, - sqrtPriceLimitX96: - sqrtPriceLimitX96 ?? tokenIn.toLowerCase() < tokenOut.toLowerCase() - ? BigNumber.from('4295128740') - : BigNumber.from('1461446703485210103287273052203988822378723970341'), - } - - const data = [router.interface.encodeFunctionData('exactOutputSingle', [params])] - if (inputIsWETH9) data.push(router.interface.encodeFunctionData('refundETH')) - if (outputIsWETH9) data.push(router.interface.encodeFunctionData('unwrapWETH9', [amountOut, trader.address])) - - // ensure that the swap fails if the limit is any tighter - params.amountInMaximum -= 1 - await expect(router.connect(trader).exactOutputSingle(params, { value })).to.be.revertedWith( - 'Too much requested' - ) - params.amountInMaximum += 1 - - return router.connect(trader).multicall(data, { value }) - } - - it('0 -> 1', async () => { - const pool = await factory.getPool(tokens[0].address, tokens[1].address, FeeAmount.MEDIUM) - - // get balances before - const poolBefore = await getBalances(pool) - const traderBefore = await getBalances(trader.address) - - await exactOutputSingle(tokens[0].address, tokens[1].address) - - // get balances after - const poolAfter = await getBalances(pool) - const traderAfter = await getBalances(trader.address) - - expect(traderAfter.token0).to.be.eq(traderBefore.token0.sub(3)) - expect(traderAfter.token1).to.be.eq(traderBefore.token1.add(1)) - expect(poolAfter.token0).to.be.eq(poolBefore.token0.add(3)) - expect(poolAfter.token1).to.be.eq(poolBefore.token1.sub(1)) - }) - - it('1 -> 0', async () => { - const pool = await factory.getPool(tokens[1].address, tokens[0].address, FeeAmount.MEDIUM) - - // get balances before - const poolBefore = await getBalances(pool) - const traderBefore = await getBalances(trader.address) - - await exactOutputSingle(tokens[1].address, tokens[0].address) - - // get balances after - const poolAfter = await getBalances(pool) - const traderAfter = await getBalances(trader.address) - - expect(traderAfter.token0).to.be.eq(traderBefore.token0.add(1)) - expect(traderAfter.token1).to.be.eq(traderBefore.token1.sub(3)) - expect(poolAfter.token0).to.be.eq(poolBefore.token0.sub(1)) - expect(poolAfter.token1).to.be.eq(poolBefore.token1.add(3)) - }) - - describe('ETH input', () => { - describe('WETH9', () => { - beforeEach(async () => { - await createPoolWETH9(tokens[0].address) - }) - - it('WETH9 -> 0', async () => { - const pool = await factory.getPool(weth9.address, tokens[0].address, FeeAmount.MEDIUM) - - // get balances before - const poolBefore = await getBalances(pool) - const traderBefore = await getBalances(trader.address) - - await expect(exactOutputSingle(weth9.address, tokens[0].address)) - .to.emit(weth9, 'Deposit') - .withArgs(router.address, 3) - - // get balances after - const poolAfter = await getBalances(pool) - const traderAfter = await getBalances(trader.address) - - expect(traderAfter.token0).to.be.eq(traderBefore.token0.add(1)) - expect(poolAfter.weth9).to.be.eq(poolBefore.weth9.add(3)) - expect(poolAfter.token0).to.be.eq(poolBefore.token0.sub(1)) - }) - }) - }) - - describe('ETH output', () => { - describe('WETH9', () => { - beforeEach(async () => { - await createPoolWETH9(tokens[0].address) - await createPoolWETH9(tokens[1].address) - }) - - it('0 -> WETH9', async () => { - const pool = await factory.getPool(tokens[0].address, weth9.address, FeeAmount.MEDIUM) - - // get balances before - const poolBefore = await getBalances(pool) - const traderBefore = await getBalances(trader.address) - - await expect(exactOutputSingle(tokens[0].address, weth9.address)) - .to.emit(weth9, 'Withdrawal') - .withArgs(router.address, 1) - - // get balances after - const poolAfter = await getBalances(pool) - const traderAfter = await getBalances(trader.address) - - expect(traderAfter.token0).to.be.eq(traderBefore.token0.sub(3)) - expect(poolAfter.weth9).to.be.eq(poolBefore.weth9.sub(1)) - expect(poolAfter.token0).to.be.eq(poolBefore.token0.add(3)) - }) - }) - }) - }) - - describe('*WithFee', () => { - const feeRecipient = '0xfEE0000000000000000000000000000000000000' - - it('#sweepTokenWithFee', async () => { - const amountOutMinimum = 100 - const params = { - path: encodePath([tokens[0].address, tokens[1].address], [FeeAmount.MEDIUM]), - recipient: router.address, - deadline: 1, - amountIn: 102, - amountOutMinimum, - } - - const data = [ - router.interface.encodeFunctionData('exactInput', [params]), - router.interface.encodeFunctionData('sweepTokenWithFee', [ - tokens[1].address, - amountOutMinimum, - trader.address, - 100, - feeRecipient, - ]), - ] - - await router.connect(trader).multicall(data) - - const balance = await tokens[1].balanceOf(feeRecipient) - expect(balance.eq(1)).to.be.eq(true) - }) - - it('#unwrapWETH9WithFee', async () => { - const startBalance = await waffle.provider.getBalance(feeRecipient) - await createPoolWETH9(tokens[0].address) - - const amountOutMinimum = 100 - const params = { - path: encodePath([tokens[0].address, weth9.address], [FeeAmount.MEDIUM]), - recipient: router.address, - deadline: 1, - amountIn: 102, - amountOutMinimum, - } - - const data = [ - router.interface.encodeFunctionData('exactInput', [params]), - router.interface.encodeFunctionData('unwrapWETH9WithFee', [ - amountOutMinimum, - trader.address, - 100, - feeRecipient, - ]), - ] - - await router.connect(trader).multicall(data) - const endBalance = await waffle.provider.getBalance(feeRecipient) - expect(endBalance.sub(startBalance).eq(1)).to.be.eq(true) - }) - }) - }) -}) diff --git a/lib/v3-periphery/test/TickLens.spec.ts b/lib/v3-periphery/test/TickLens.spec.ts deleted file mode 100644 index 4a927d7..0000000 --- a/lib/v3-periphery/test/TickLens.spec.ts +++ /dev/null @@ -1,223 +0,0 @@ -import { Fixture } from 'ethereum-waffle' -import { BigNumber, BigNumberish, constants, Contract, ContractTransaction, Wallet } from 'ethers' -import { ethers, waffle } from 'hardhat' -import { MockTimeNonfungiblePositionManager, TestERC20, TickLensTest } from '../typechain' -import completeFixture from './shared/completeFixture' -import { FeeAmount, TICK_SPACINGS } from './shared/constants' -import { encodePriceSqrt } from './shared/encodePriceSqrt' -import { expect } from './shared/expect' -import { getMaxTick, getMinTick } from './shared/ticks' -import { computePoolAddress } from './shared/computePoolAddress' -import snapshotGasCost from './shared/snapshotGasCost' - -describe('TickLens', () => { - let wallets: Wallet[] - - const nftFixture: Fixture<{ - factory: Contract - nft: MockTimeNonfungiblePositionManager - tokens: [TestERC20, TestERC20, TestERC20] - }> = async (wallets, provider) => { - const { factory, tokens, nft } = await completeFixture(wallets, provider) - - for (const token of tokens) { - await token.approve(nft.address, constants.MaxUint256) - } - - return { - factory, - nft, - tokens, - } - } - - let factory: Contract - let nft: MockTimeNonfungiblePositionManager - let tokens: [TestERC20, TestERC20, TestERC20] - let poolAddress: string - let tickLens: TickLensTest - - let loadFixture: ReturnType - - before('create fixture loader', async () => { - wallets = await (ethers as any).getSigners() - loadFixture = waffle.createFixtureLoader(wallets) - }) - - beforeEach('load fixture', async () => { - ;({ factory, tokens, nft } = await loadFixture(nftFixture)) - }) - - describe('#getPopulatedTicksInWord', () => { - const fullRangeLiquidity = 1000000 - async function createPool(tokenAddressA: string, tokenAddressB: string) { - if (tokenAddressA.toLowerCase() > tokenAddressB.toLowerCase()) - [tokenAddressA, tokenAddressB] = [tokenAddressB, tokenAddressA] - - await nft.createAndInitializePoolIfNecessary( - tokenAddressA, - tokenAddressB, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - - const liquidityParams = { - token0: tokenAddressA, - token1: tokenAddressB, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - recipient: wallets[0].address, - amount0Desired: 1000000, - amount1Desired: 1000000, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - } - - return nft.mint(liquidityParams) - } - - async function mint(tickLower: number, tickUpper: number, amountBothDesired: BigNumberish): Promise { - const mintParams = { - token0: tokens[0].address, - token1: tokens[1].address, - fee: FeeAmount.MEDIUM, - tickLower, - tickUpper, - amount0Desired: amountBothDesired, - amount1Desired: amountBothDesired, - amount0Min: 0, - amount1Min: 0, - recipient: wallets[0].address, - deadline: 1, - } - - const { liquidity } = await nft.callStatic.mint(mintParams) - - await nft.mint(mintParams) - return liquidity.toNumber() - } - - beforeEach(async () => { - await createPool(tokens[0].address, tokens[1].address) - poolAddress = computePoolAddress(factory.address, [tokens[0].address, tokens[1].address], FeeAmount.MEDIUM) - }) - - beforeEach(async () => { - const lensFactory = await ethers.getContractFactory('TickLensTest') - tickLens = (await lensFactory.deploy()) as TickLensTest - }) - - function getTickBitmapIndex(tick: BigNumberish, tickSpacing: number): BigNumber { - const intermediate = BigNumber.from(tick).div(tickSpacing) - // see https://docs.soliditylang.org/en/v0.7.6/types.html#shifts - return intermediate.lt(0) ? intermediate.add(1).div(BigNumber.from(2).pow(8)).sub(1) : intermediate.shr(8) - } - - it('works for min/max', async () => { - const [min] = await tickLens.getPopulatedTicksInWord( - poolAddress, - getTickBitmapIndex(getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), TICK_SPACINGS[FeeAmount.MEDIUM]) - ) - - const [max] = await tickLens.getPopulatedTicksInWord( - poolAddress, - getTickBitmapIndex(getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), TICK_SPACINGS[FeeAmount.MEDIUM]) - ) - - expect(min.tick).to.be.eq(getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM])) - expect(min.liquidityNet).to.be.eq(fullRangeLiquidity) - expect(min.liquidityGross).to.be.eq(fullRangeLiquidity) - - expect(max.tick).to.be.eq(getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM])) - expect(max.liquidityNet).to.be.eq(fullRangeLiquidity * -1) - expect(min.liquidityGross).to.be.eq(fullRangeLiquidity) - }) - - it('works for min/max and -2/-1/0/1', async () => { - const minus = -TICK_SPACINGS[FeeAmount.MEDIUM] - const plus = -minus - - const liquidity0 = await mint(minus * 2, minus, 2) - const liquidity1 = await mint(minus * 2, 0, 3) - const liquidity2 = await mint(minus * 2, plus, 5) - const liquidity3 = await mint(minus, 0, 7) - const liquidity4 = await mint(minus, plus, 11) - const liquidity5 = await mint(0, plus, 13) - - const [min] = await tickLens.getPopulatedTicksInWord( - poolAddress, - getTickBitmapIndex(getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), TICK_SPACINGS[FeeAmount.MEDIUM]) - ) - - const [negativeOne, negativeTwo] = await tickLens.getPopulatedTicksInWord( - poolAddress, - getTickBitmapIndex(minus, TICK_SPACINGS[FeeAmount.MEDIUM]) - ) - - const [one, zero] = await tickLens.getPopulatedTicksInWord( - poolAddress, - getTickBitmapIndex(plus, TICK_SPACINGS[FeeAmount.MEDIUM]) - ) - - const [max] = await tickLens.getPopulatedTicksInWord( - poolAddress, - getTickBitmapIndex(getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), TICK_SPACINGS[FeeAmount.MEDIUM]) - ) - - expect(min.tick).to.be.eq(getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM])) - expect(min.liquidityNet).to.be.eq(fullRangeLiquidity) - expect(min.liquidityGross).to.be.eq(fullRangeLiquidity) - - expect(negativeTwo.tick).to.be.eq(minus * 2) - expect(negativeTwo.liquidityNet).to.be.eq(liquidity0 + liquidity1 + liquidity2) - expect(negativeTwo.liquidityGross).to.be.eq(liquidity0 + liquidity1 + liquidity2) - - expect(negativeOne.tick).to.be.eq(minus) - expect(negativeOne.liquidityNet).to.be.eq(liquidity3 + liquidity4 - liquidity0) - expect(negativeOne.liquidityGross).to.be.eq(liquidity3 + liquidity4 + liquidity0) - - expect(zero.tick).to.be.eq(0) - expect(zero.liquidityNet).to.be.eq(liquidity5 - liquidity1 - liquidity3) - expect(zero.liquidityGross).to.be.eq(liquidity5 + liquidity1 + liquidity3) - - expect(one.tick).to.be.eq(plus) - expect(one.liquidityNet).to.be.eq(-liquidity2 - liquidity4 - liquidity5) - expect(one.liquidityGross).to.be.eq(liquidity2 + liquidity4 + liquidity5) - - expect(max.tick).to.be.eq(getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM])) - expect(max.liquidityNet).to.be.eq(fullRangeLiquidity * -1) - expect(max.liquidityGross).to.be.eq(fullRangeLiquidity) - }) - - it('gas for single populated tick', async () => { - await snapshotGasCost( - tickLens.getGasCostOfGetPopulatedTicksInWord( - poolAddress, - getTickBitmapIndex(getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), TICK_SPACINGS[FeeAmount.MEDIUM]) - ) - ) - }) - - it('fully populated ticks', async () => { - // fully populate a word - for (let i = 0; i < 128; i++) { - await mint(i * TICK_SPACINGS[FeeAmount.MEDIUM], (255 - i) * TICK_SPACINGS[FeeAmount.MEDIUM], 100) - } - - const ticks = await tickLens.getPopulatedTicksInWord( - poolAddress, - getTickBitmapIndex(0, TICK_SPACINGS[FeeAmount.MEDIUM]) - ) - expect(ticks.length).to.be.eq(256) - - await snapshotGasCost( - tickLens.getGasCostOfGetPopulatedTicksInWord( - poolAddress, - getTickBitmapIndex(0, TICK_SPACINGS[FeeAmount.MEDIUM]) - ) - ) - }).timeout(300_000) - }) -}) diff --git a/lib/v3-periphery/test/V3Migrator.spec.ts b/lib/v3-periphery/test/V3Migrator.spec.ts deleted file mode 100644 index f113b27..0000000 --- a/lib/v3-periphery/test/V3Migrator.spec.ts +++ /dev/null @@ -1,446 +0,0 @@ -import { Fixture } from 'ethereum-waffle' -import { constants, Contract, Wallet } from 'ethers' -import { ethers, waffle } from 'hardhat' -import { - IUniswapV2Pair, - IUniswapV3Factory, - IWETH9, - MockTimeNonfungiblePositionManager, - TestERC20, - V3Migrator, -} from '../typechain' -import completeFixture from './shared/completeFixture' -import { v2FactoryFixture } from './shared/externalFixtures' - -import { abi as PAIR_V2_ABI } from '@uniswap/v2-core/build/UniswapV2Pair.json' -import { expect } from 'chai' -import { FeeAmount } from './shared/constants' -import { encodePriceSqrt } from './shared/encodePriceSqrt' -import snapshotGasCost from './shared/snapshotGasCost' -import { sortedTokens } from './shared/tokenSort' -import { getMaxTick, getMinTick } from './shared/ticks' - -describe('V3Migrator', () => { - let wallet: Wallet - - const migratorFixture: Fixture<{ - factoryV2: Contract - factoryV3: IUniswapV3Factory - token: TestERC20 - weth9: IWETH9 - nft: MockTimeNonfungiblePositionManager - migrator: V3Migrator - }> = async (wallets, provider) => { - const { factory, tokens, nft, weth9 } = await completeFixture(wallets, provider) - - const { factory: factoryV2 } = await v2FactoryFixture(wallets, provider) - - const token = tokens[0] - await token.approve(factoryV2.address, constants.MaxUint256) - await weth9.deposit({ value: 10000 }) - await weth9.approve(nft.address, constants.MaxUint256) - - // deploy the migrator - const migrator = (await (await ethers.getContractFactory('V3Migrator')).deploy( - factory.address, - weth9.address, - nft.address - )) as V3Migrator - - return { - factoryV2, - factoryV3: factory, - token, - weth9, - nft, - migrator, - } - } - - let factoryV2: Contract - let factoryV3: IUniswapV3Factory - let token: TestERC20 - let weth9: IWETH9 - let nft: MockTimeNonfungiblePositionManager - let migrator: V3Migrator - let pair: IUniswapV2Pair - - let loadFixture: ReturnType - - const expectedLiquidity = 10000 - 1000 - - before('create fixture loader', async () => { - const wallets = await (ethers as any).getSigners() - wallet = wallets[0] - - loadFixture = waffle.createFixtureLoader(wallets) - }) - - beforeEach('load fixture', async () => { - ;({ factoryV2, factoryV3, token, weth9, nft, migrator } = await loadFixture(migratorFixture)) - }) - - beforeEach('add V2 liquidity', async () => { - await factoryV2.createPair(token.address, weth9.address) - - const pairAddress = await factoryV2.getPair(token.address, weth9.address) - - pair = new ethers.Contract(pairAddress, PAIR_V2_ABI, wallet) as IUniswapV2Pair - - await token.transfer(pair.address, 10000) - await weth9.transfer(pair.address, 10000) - - await pair.mint(wallet.address) - - expect(await pair.balanceOf(wallet.address)).to.be.eq(expectedLiquidity) - }) - - afterEach('ensure allowances are cleared', async () => { - const allowanceToken = await token.allowance(migrator.address, nft.address) - const allowanceWETH9 = await weth9.allowance(migrator.address, nft.address) - expect(allowanceToken).to.be.eq(0) - expect(allowanceWETH9).to.be.eq(0) - }) - - afterEach('ensure balances are cleared', async () => { - const balanceToken = await token.balanceOf(migrator.address) - const balanceWETH9 = await weth9.balanceOf(migrator.address) - expect(balanceToken).to.be.eq(0) - expect(balanceWETH9).to.be.eq(0) - }) - - afterEach('ensure eth balance is cleared', async () => { - const balanceETH = await ethers.provider.getBalance(migrator.address) - expect(balanceETH).to.be.eq(0) - }) - - describe('#migrate', () => { - let tokenLower: boolean - beforeEach(() => { - tokenLower = token.address.toLowerCase() < weth9.address.toLowerCase() - }) - - it('fails if v3 pool is not initialized', async () => { - await pair.approve(migrator.address, expectedLiquidity) - await expect( - migrator.migrate({ - pair: pair.address, - liquidityToMigrate: expectedLiquidity, - percentageToMigrate: 100, - token0: tokenLower ? token.address : weth9.address, - token1: tokenLower ? weth9.address : token.address, - fee: FeeAmount.MEDIUM, - tickLower: -1, - tickUpper: 1, - amount0Min: 9000, - amount1Min: 9000, - recipient: wallet.address, - deadline: 1, - refundAsETH: false, - }) - ).to.be.reverted - }) - - it('works once v3 pool is initialized', async () => { - const [token0, token1] = sortedTokens(weth9, token) - await migrator.createAndInitializePoolIfNecessary( - token0.address, - token1.address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - - await pair.approve(migrator.address, expectedLiquidity) - await migrator.migrate({ - pair: pair.address, - liquidityToMigrate: expectedLiquidity, - percentageToMigrate: 100, - token0: tokenLower ? token.address : weth9.address, - token1: tokenLower ? weth9.address : token.address, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(FeeAmount.MEDIUM), - tickUpper: getMaxTick(FeeAmount.MEDIUM), - amount0Min: 9000, - amount1Min: 9000, - recipient: wallet.address, - deadline: 1, - refundAsETH: false, - }) - - const position = await nft.positions(1) - expect(position.liquidity).to.be.eq(9000) - - const poolAddress = await factoryV3.getPool(token.address, weth9.address, FeeAmount.MEDIUM) - expect(await token.balanceOf(poolAddress)).to.be.eq(9000) - expect(await weth9.balanceOf(poolAddress)).to.be.eq(9000) - }) - - it('works for partial', async () => { - const [token0, token1] = sortedTokens(weth9, token) - await migrator.createAndInitializePoolIfNecessary( - token0.address, - token1.address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - - const tokenBalanceBefore = await token.balanceOf(wallet.address) - const weth9BalanceBefore = await weth9.balanceOf(wallet.address) - - await pair.approve(migrator.address, expectedLiquidity) - await migrator.migrate({ - pair: pair.address, - liquidityToMigrate: expectedLiquidity, - percentageToMigrate: 50, - token0: tokenLower ? token.address : weth9.address, - token1: tokenLower ? weth9.address : token.address, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(FeeAmount.MEDIUM), - tickUpper: getMaxTick(FeeAmount.MEDIUM), - amount0Min: 4500, - amount1Min: 4500, - recipient: wallet.address, - deadline: 1, - refundAsETH: false, - }) - - const tokenBalanceAfter = await token.balanceOf(wallet.address) - const weth9BalanceAfter = await weth9.balanceOf(wallet.address) - - expect(tokenBalanceAfter.sub(tokenBalanceBefore)).to.be.eq(4500) - expect(weth9BalanceAfter.sub(weth9BalanceBefore)).to.be.eq(4500) - - const position = await nft.positions(1) - expect(position.liquidity).to.be.eq(4500) - - const poolAddress = await factoryV3.getPool(token.address, weth9.address, FeeAmount.MEDIUM) - expect(await token.balanceOf(poolAddress)).to.be.eq(4500) - expect(await weth9.balanceOf(poolAddress)).to.be.eq(4500) - }) - - it('double the price', async () => { - const [token0, token1] = sortedTokens(weth9, token) - await migrator.createAndInitializePoolIfNecessary( - token0.address, - token1.address, - FeeAmount.MEDIUM, - encodePriceSqrt(2, 1) - ) - - const tokenBalanceBefore = await token.balanceOf(wallet.address) - const weth9BalanceBefore = await weth9.balanceOf(wallet.address) - - await pair.approve(migrator.address, expectedLiquidity) - await migrator.migrate({ - pair: pair.address, - liquidityToMigrate: expectedLiquidity, - percentageToMigrate: 100, - token0: tokenLower ? token.address : weth9.address, - token1: tokenLower ? weth9.address : token.address, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(FeeAmount.MEDIUM), - tickUpper: getMaxTick(FeeAmount.MEDIUM), - amount0Min: 4500, - amount1Min: 8999, - recipient: wallet.address, - deadline: 1, - refundAsETH: false, - }) - - const tokenBalanceAfter = await token.balanceOf(wallet.address) - const weth9BalanceAfter = await weth9.balanceOf(wallet.address) - - const position = await nft.positions(1) - expect(position.liquidity).to.be.eq(6363) - - const poolAddress = await factoryV3.getPool(token.address, weth9.address, FeeAmount.MEDIUM) - if (token.address.toLowerCase() < weth9.address.toLowerCase()) { - expect(await token.balanceOf(poolAddress)).to.be.eq(4500) - expect(tokenBalanceAfter.sub(tokenBalanceBefore)).to.be.eq(4500) - expect(await weth9.balanceOf(poolAddress)).to.be.eq(8999) - expect(weth9BalanceAfter.sub(weth9BalanceBefore)).to.be.eq(1) - } else { - expect(await token.balanceOf(poolAddress)).to.be.eq(8999) - expect(tokenBalanceAfter.sub(tokenBalanceBefore)).to.be.eq(1) - expect(await weth9.balanceOf(poolAddress)).to.be.eq(4500) - expect(weth9BalanceAfter.sub(weth9BalanceBefore)).to.be.eq(4500) - } - }) - - it('half the price', async () => { - const [token0, token1] = sortedTokens(weth9, token) - await migrator.createAndInitializePoolIfNecessary( - token0.address, - token1.address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 2) - ) - - const tokenBalanceBefore = await token.balanceOf(wallet.address) - const weth9BalanceBefore = await weth9.balanceOf(wallet.address) - - await pair.approve(migrator.address, expectedLiquidity) - await migrator.migrate({ - pair: pair.address, - liquidityToMigrate: expectedLiquidity, - percentageToMigrate: 100, - token0: tokenLower ? token.address : weth9.address, - token1: tokenLower ? weth9.address : token.address, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(FeeAmount.MEDIUM), - tickUpper: getMaxTick(FeeAmount.MEDIUM), - amount0Min: 8999, - amount1Min: 4500, - recipient: wallet.address, - deadline: 1, - refundAsETH: false, - }) - - const tokenBalanceAfter = await token.balanceOf(wallet.address) - const weth9BalanceAfter = await weth9.balanceOf(wallet.address) - - const position = await nft.positions(1) - expect(position.liquidity).to.be.eq(6363) - - const poolAddress = await factoryV3.getPool(token.address, weth9.address, FeeAmount.MEDIUM) - if (token.address.toLowerCase() < weth9.address.toLowerCase()) { - expect(await token.balanceOf(poolAddress)).to.be.eq(8999) - expect(tokenBalanceAfter.sub(tokenBalanceBefore)).to.be.eq(1) - expect(await weth9.balanceOf(poolAddress)).to.be.eq(4500) - expect(weth9BalanceAfter.sub(weth9BalanceBefore)).to.be.eq(4500) - } else { - expect(await token.balanceOf(poolAddress)).to.be.eq(4500) - expect(tokenBalanceAfter.sub(tokenBalanceBefore)).to.be.eq(4500) - expect(await weth9.balanceOf(poolAddress)).to.be.eq(8999) - expect(weth9BalanceAfter.sub(weth9BalanceBefore)).to.be.eq(1) - } - }) - - it('double the price - as ETH', async () => { - const [token0, token1] = sortedTokens(weth9, token) - await migrator.createAndInitializePoolIfNecessary( - token0.address, - token1.address, - FeeAmount.MEDIUM, - encodePriceSqrt(2, 1) - ) - - const tokenBalanceBefore = await token.balanceOf(wallet.address) - - await pair.approve(migrator.address, expectedLiquidity) - await expect( - migrator.migrate({ - pair: pair.address, - liquidityToMigrate: expectedLiquidity, - percentageToMigrate: 100, - token0: tokenLower ? token.address : weth9.address, - token1: tokenLower ? weth9.address : token.address, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(FeeAmount.MEDIUM), - tickUpper: getMaxTick(FeeAmount.MEDIUM), - amount0Min: 4500, - amount1Min: 8999, - recipient: wallet.address, - deadline: 1, - refundAsETH: true, - }) - ) - .to.emit(weth9, 'Withdrawal') - .withArgs(migrator.address, tokenLower ? 1 : 4500) - - const tokenBalanceAfter = await token.balanceOf(wallet.address) - - const position = await nft.positions(1) - expect(position.liquidity).to.be.eq(6363) - - const poolAddress = await factoryV3.getPool(token.address, weth9.address, FeeAmount.MEDIUM) - if (tokenLower) { - expect(await token.balanceOf(poolAddress)).to.be.eq(4500) - expect(tokenBalanceAfter.sub(tokenBalanceBefore)).to.be.eq(4500) - expect(await weth9.balanceOf(poolAddress)).to.be.eq(8999) - } else { - expect(await token.balanceOf(poolAddress)).to.be.eq(8999) - expect(tokenBalanceAfter.sub(tokenBalanceBefore)).to.be.eq(1) - expect(await weth9.balanceOf(poolAddress)).to.be.eq(4500) - } - }) - - it('half the price - as ETH', async () => { - const [token0, token1] = sortedTokens(weth9, token) - await migrator.createAndInitializePoolIfNecessary( - token0.address, - token1.address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 2) - ) - - const tokenBalanceBefore = await token.balanceOf(wallet.address) - - await pair.approve(migrator.address, expectedLiquidity) - await expect( - migrator.migrate({ - pair: pair.address, - liquidityToMigrate: expectedLiquidity, - percentageToMigrate: 100, - token0: tokenLower ? token.address : weth9.address, - token1: tokenLower ? weth9.address : token.address, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(FeeAmount.MEDIUM), - tickUpper: getMaxTick(FeeAmount.MEDIUM), - amount0Min: 8999, - amount1Min: 4500, - recipient: wallet.address, - deadline: 1, - refundAsETH: true, - }) - ) - .to.emit(weth9, 'Withdrawal') - .withArgs(migrator.address, tokenLower ? 4500 : 1) - - const tokenBalanceAfter = await token.balanceOf(wallet.address) - - const position = await nft.positions(1) - expect(position.liquidity).to.be.eq(6363) - - const poolAddress = await factoryV3.getPool(token.address, weth9.address, FeeAmount.MEDIUM) - if (tokenLower) { - expect(await token.balanceOf(poolAddress)).to.be.eq(8999) - expect(tokenBalanceAfter.sub(tokenBalanceBefore)).to.be.eq(1) - expect(await weth9.balanceOf(poolAddress)).to.be.eq(4500) - } else { - expect(await token.balanceOf(poolAddress)).to.be.eq(4500) - expect(tokenBalanceAfter.sub(tokenBalanceBefore)).to.be.eq(4500) - expect(await weth9.balanceOf(poolAddress)).to.be.eq(8999) - } - }) - - it('gas', async () => { - const [token0, token1] = sortedTokens(weth9, token) - await migrator.createAndInitializePoolIfNecessary( - token0.address, - token1.address, - FeeAmount.MEDIUM, - encodePriceSqrt(1, 1) - ) - - await pair.approve(migrator.address, expectedLiquidity) - await snapshotGasCost( - migrator.migrate({ - pair: pair.address, - liquidityToMigrate: expectedLiquidity, - percentageToMigrate: 100, - token0: tokenLower ? token.address : weth9.address, - token1: tokenLower ? weth9.address : token.address, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(FeeAmount.MEDIUM), - tickUpper: getMaxTick(FeeAmount.MEDIUM), - amount0Min: 9000, - amount1Min: 9000, - recipient: wallet.address, - deadline: 1, - refundAsETH: false, - }) - ) - }) - }) -}) diff --git a/lib/v3-periphery/test/__snapshots__/Base64.spec.ts.snap b/lib/v3-periphery/test/__snapshots__/Base64.spec.ts.snap deleted file mode 100644 index fd54e5c..0000000 --- a/lib/v3-periphery/test/__snapshots__/Base64.spec.ts.snap +++ /dev/null @@ -1,32 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Base64 #encode gas cost of encode() 1`] = `1497`; - -exports[`Base64 #encode gas cost of encode(aLpHaBeT) 1`] = `1256`; - -exports[`Base64 #encode gas cost of encode(alphabet soup) 1`] = `1727`; - -exports[`Base64 #encode gas cost of encode(f) 1`] = `763`; - -exports[`Base64 #encode gas cost of encode(fo) 1`] = `774`; - -exports[`Base64 #encode gas cost of encode(foo) 1`] = `769`; - -exports[`Base64 #encode gas cost of encode(foob) 1`] = `1004`; - -exports[`Base64 #encode gas cost of encode(fooba) 1`] = `1015`; - -exports[`Base64 #encode gas cost of encode(foobar) 1`] = `1010`; - -exports[`Base64 #encode gas cost of encode(includes -newlines) 1`] = `1979`; - -exports[`Base64 #encode gas cost of encode(test string) 1`] = `1497`; - -exports[`Base64 #encode gas cost of encode(this is a test) 1`] = `1738`; - -exports[`Base64 #encode gas cost of encode(this is a very long string that should cost a lot of gas to encode :)) 1`] = `6083`; - -exports[`Base64 #encode gas cost of encode(😀) 1`] = `1004`; - -exports[`Base64 #encode max size string (24kB) gas cost 1`] = `3731900`; diff --git a/lib/v3-periphery/test/__snapshots__/LiquidityAmounts.spec.ts.snap b/lib/v3-periphery/test/__snapshots__/LiquidityAmounts.spec.ts.snap deleted file mode 100644 index 8f420b7..0000000 --- a/lib/v3-periphery/test/__snapshots__/LiquidityAmounts.spec.ts.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`LiquidityAmounts #getAmount0ForLiquidity gas 1`] = `352`; - -exports[`LiquidityAmounts #getAmountsForLiquidity gas for price above 1`] = `481`; - -exports[`LiquidityAmounts #getAmountsForLiquidity gas for price below 1`] = `502`; - -exports[`LiquidityAmounts #getAmountsForLiquidity gas for price inside 1`] = `840`; - -exports[`LiquidityAmounts #getLiquidityForAmount0 gas 1`] = `565`; - -exports[`LiquidityAmounts #getLiquidityForAmount1 gas 1`] = `362`; - -exports[`LiquidityAmounts #getLiquidityForAmount1 gas 2`] = `368`; - -exports[`LiquidityAmounts #getLiquidityForAmounts gas for price above 1`] = `537`; - -exports[`LiquidityAmounts #getLiquidityForAmounts gas for price below 1`] = `712`; - -exports[`LiquidityAmounts #getLiquidityForAmounts gas for price inside 1`] = `1162`; diff --git a/lib/v3-periphery/test/__snapshots__/Multicall.spec.ts.snap b/lib/v3-periphery/test/__snapshots__/Multicall.spec.ts.snap deleted file mode 100644 index 636167d..0000000 --- a/lib/v3-periphery/test/__snapshots__/Multicall.spec.ts.snap +++ /dev/null @@ -1,5 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Multicall gas cost of pay w/ multicall 1`] = `45845`; - -exports[`Multicall gas cost of pay w/o multicall 1`] = `43342`; diff --git a/lib/v3-periphery/test/__snapshots__/NFTDescriptor.spec.ts.snap b/lib/v3-periphery/test/__snapshots__/NFTDescriptor.spec.ts.snap deleted file mode 100644 index 72b006f..0000000 --- a/lib/v3-periphery/test/__snapshots__/NFTDescriptor.spec.ts.snap +++ /dev/null @@ -1,7 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`NFTDescriptor #constructTokenURI gas 1`] = `1632898`; - -exports[`NFTDescriptor #constructTokenURI snapshot matches 1`] = `"data:application/json;base64,eyJuYW1lIjoiVW5pc3dhcCAtIDAuMDUlIC0gVU5JL1dFVEggLSAxLjAwMDA8PjEuMTA1MiIsICJkZXNjcmlwdGlvbiI6IlRoaXMgTkZUIHJlcHJlc2VudHMgYSBsaXF1aWRpdHkgcG9zaXRpb24gaW4gYSBVbmlzd2FwIFYzIFVOSS1XRVRIIHBvb2wuIFRoZSBvd25lciBvZiB0aGlzIE5GVCBjYW4gbW9kaWZ5IG9yIHJlZGVlbSB0aGUgcG9zaXRpb24uXG5cblBvb2wgQWRkcmVzczogMHhiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiXG5VTkkgQWRkcmVzczogMHhhYmNkZWFiY2RlZmFiY2RlZmFiY2RlZmFiY2RlZmFiY2RlZmFiY2RmXG5XRVRIIEFkZHJlc3M6IDB4MTIzNDU2Nzg5MDEyMzQ1Njc4OTEyMzQ1Njc4OTAxMjM0NTY3ODkwMVxuRmVlIFRpZXI6IDAuMDUlXG5Ub2tlbiBJRDogMVxuXG7imqDvuI8gRElTQ0xBSU1FUjogRHVlIGRpbGlnZW5jZSBpcyBpbXBlcmF0aXZlIHdoZW4gYXNzZXNzaW5nIHRoaXMgTkZULiBNYWtlIHN1cmUgdG9rZW4gYWRkcmVzc2VzIG1hdGNoIHRoZSBleHBlY3RlZCB0b2tlbnMsIGFzIHRva2VuIHN5bWJvbHMgbWF5IGJlIGltaXRhdGVkLiIsICJpbWFnZSI6ICJkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBITjJaeUIzYVdSMGFEMGlNamt3SWlCb1pXbG5hSFE5SWpVd01DSWdkbWxsZDBKdmVEMGlNQ0F3SURJNU1DQTFNREFpSUhodGJHNXpQU0pvZEhSd09pOHZkM2QzTG5jekxtOXlaeTh5TURBd0wzTjJaeUlnZUcxc2JuTTZlR3hwYm1zOUoyaDBkSEE2THk5M2QzY3Vkek11YjNKbkx6RTVPVGt2ZUd4cGJtc25QanhrWldaelBqeG1hV3gwWlhJZ2FXUTlJbVl4SWo0OFptVkpiV0ZuWlNCeVpYTjFiSFE5SW5Bd0lpQjRiR2x1YXpwb2NtVm1QU0prWVhSaE9tbHRZV2RsTDNOMlp5dDRiV3c3WW1GelpUWTBMRkJJVGpKYWVVSXpZVmRTTUdGRU1HNU5hbXQzU25sQ2IxcFhiRzVoU0ZFNVNucFZkMDFEWTJka2JXeHNaREJLZG1WRU1HNU5RMEYzU1VSSk5VMURRVEZOUkVGdVNVaG9kR0pITlhwUVUyUnZaRWhTZDA5cE9IWmtNMlF6VEc1amVreHRPWGxhZVRoNVRVUkJkMHd6VGpKYWVXTXJVRWhLYkZrelVXZGtNbXhyWkVkbk9VcDZTVFZOU0VJMFNubENiMXBYYkc1aFNGRTVTbnBWZDAxSVFqUktlVUp0WVZkNGMxQlRZMnBaVjBwcVdrZFdhRXA1T0N0UVF6bDZaRzFqS3lJdlBqeG1aVWx0WVdkbElISmxjM1ZzZEQwaWNERWlJSGhzYVc1ck9taHlaV1k5SW1SaGRHRTZhVzFoWjJVdmMzWm5LM2h0YkR0aVlYTmxOalFzVUVoT01scDVRak5oVjFJd1lVUXdiazFxYTNkS2VVSnZXbGRzYm1GSVVUbEtlbFYzVFVOaloyUnRiR3hrTUVwMlpVUXdiazFEUVhkSlJFazFUVU5CTVUxRVFXNUpTR2gwWWtjMWVsQlRaRzlrU0ZKM1QyazRkbVF6WkROTWJtTjZURzA1ZVZwNU9IbE5SRUYzVEROT01scDVZeXRRUjA1d1kyMU9jMXBUUW1wbFJEQnVUV3BaTkVwNVFtcGxWREJ1VFdwVk1VcDVRbmxRVTJONFRXcENkMlZEWTJkYWJXeHpZa1F3YmtsNlJYbE5lbEV4VG1samRsQnFkM1pqTTFwdVVHYzlQU0l2UGp4bVpVbHRZV2RsSUhKbGMzVnNkRDBpY0RJaUlIaHNhVzVyT21oeVpXWTlJbVJoZEdFNmFXMWhaMlV2YzNabkszaHRiRHRpWVhObE5qUXNVRWhPTWxwNVFqTmhWMUl3WVVRd2JrMXFhM2RLZVVKdldsZHNibUZJVVRsS2VsVjNUVU5qWjJSdGJHeGtNRXAyWlVRd2JrMURRWGRKUkVrMVRVTkJNVTFFUVc1SlNHaDBZa2MxZWxCVFpHOWtTRkozVDJrNGRtUXpaRE5NYm1ONlRHMDVlVnA1T0hsTlJFRjNURE5PTWxwNVl5dFFSMDV3WTIxT2MxcFRRbXBsUkRCdVRXcEJNa3A1UW1wbFZEQnVUVlJWZVVwNVFubFFVMk40VFdwQ2QyVkRZMmRhYld4ellrUXdia2t5V21oWmJVNXJXbWxqZGxCcWQzWmpNMXB1VUdjOVBTSWdMejQ4Wm1WSmJXRm5aU0J5WlhOMWJIUTlJbkF6SWlCNGJHbHVhenBvY21WbVBTSmtZWFJoT21sdFlXZGxMM04yWnl0NGJXdzdZbUZ6WlRZMExGQklUakphZVVJellWZFNNR0ZFTUc1TmFtdDNTbmxDYjFwWGJHNWhTRkU1U25wVmQwMURZMmRrYld4c1pEQktkbVZFTUc1TlEwRjNTVVJKTlUxRFFURk5SRUZ1U1Vob2RHSkhOWHBRVTJSdlpFaFNkMDlwT0haa00yUXpURzVqZWt4dE9YbGFlVGg1VFVSQmQwd3pUakphZVdNclVFZE9jR050VG5OYVUwSnFaVVF3YmsxcVVYZEtlVUpxWlZRd2JrMTZRVEpLZVVKNVVGTmplRTFFUW5kbFEyTm5XbTFzYzJKRU1HNUplbGt6VDBScmQwMVRZM1pRYW5kMll6TmFibEJuUFQwaUlDOCtQR1psUW14bGJtUWdiVzlrWlQwaWIzWmxjbXhoZVNJZ2FXNDlJbkF3SWlCcGJqSTlJbkF4SWlBdlBqeG1aVUpzWlc1a0lHMXZaR1U5SW1WNFkyeDFjMmx2YmlJZ2FXNHlQU0p3TWlJZ0x6NDhabVZDYkdWdVpDQnRiMlJsUFNKdmRtVnliR0Y1SWlCcGJqSTlJbkF6SWlCeVpYTjFiSFE5SW1Kc1pXNWtUM1YwSWlBdlBqeG1aVWRoZFhOemFXRnVRbXgxY2lCcGJqMGlZbXhsYm1SUGRYUWlJSE4wWkVSbGRtbGhkR2x2YmowaU5ESWlJQzgrUEM5bWFXeDBaWEkrSUR4amJHbHdVR0YwYUNCcFpEMGlZMjl5Ym1WeWN5SStQSEpsWTNRZ2QybGtkR2c5SWpJNU1DSWdhR1ZwWjJoMFBTSTFNREFpSUhKNFBTSTBNaUlnY25rOUlqUXlJaUF2UGp3dlkyeHBjRkJoZEdnK1BIQmhkR2dnYVdROUluUmxlSFF0Y0dGMGFDMWhJaUJrUFNKTk5EQWdNVElnU0RJMU1DQkJNamdnTWpnZ01DQXdJREVnTWpjNElEUXdJRlkwTmpBZ1FUSTRJREk0SURBZ01DQXhJREkxTUNBME9EZ2dTRFF3SUVFeU9DQXlPQ0F3SURBZ01TQXhNaUEwTmpBZ1ZqUXdJRUV5T0NBeU9DQXdJREFnTVNBME1DQXhNaUI2SWlBdlBqeHdZWFJvSUdsa1BTSnRhVzVwYldGd0lpQmtQU0pOTWpNMElEUTBORU15TXpRZ05EVTNMamswT1NBeU5ESXVNakVnTkRZeklESTFNeUEwTmpNaUlDOCtQR1pwYkhSbGNpQnBaRDBpZEc5d0xYSmxaMmx2YmkxaWJIVnlJajQ4Wm1WSFlYVnpjMmxoYmtKc2RYSWdhVzQ5SWxOdmRYSmpaVWR5WVhCb2FXTWlJSE4wWkVSbGRtbGhkR2x2YmowaU1qUWlJQzgrUEM5bWFXeDBaWEkrUEd4cGJtVmhja2R5WVdScFpXNTBJR2xrUFNKbmNtRmtMWFZ3SWlCNE1UMGlNU0lnZURJOUlqQWlJSGt4UFNJeElpQjVNajBpTUNJK1BITjBiM0FnYjJabWMyVjBQU0l3TGpBaUlITjBiM0F0WTI5c2IzSTlJbmRvYVhSbElpQnpkRzl3TFc5d1lXTnBkSGs5SWpFaUlDOCtQSE4wYjNBZ2IyWm1jMlYwUFNJdU9TSWdjM1J2Y0MxamIyeHZjajBpZDJocGRHVWlJSE4wYjNBdGIzQmhZMmwwZVQwaU1DSWdMejQ4TDJ4cGJtVmhja2R5WVdScFpXNTBQanhzYVc1bFlYSkhjbUZrYVdWdWRDQnBaRDBpWjNKaFpDMWtiM2R1SWlCNE1UMGlNQ0lnZURJOUlqRWlJSGt4UFNJd0lpQjVNajBpTVNJK1BITjBiM0FnYjJabWMyVjBQU0l3TGpBaUlITjBiM0F0WTI5c2IzSTlJbmRvYVhSbElpQnpkRzl3TFc5d1lXTnBkSGs5SWpFaUlDOCtQSE4wYjNBZ2IyWm1jMlYwUFNJd0xqa2lJSE4wYjNBdFkyOXNiM0k5SW5kb2FYUmxJaUJ6ZEc5d0xXOXdZV05wZEhrOUlqQWlJQzgrUEM5c2FXNWxZWEpIY21Ga2FXVnVkRDQ4YldGemF5QnBaRDBpWm1Ga1pTMTFjQ0lnYldGemEwTnZiblJsYm5SVmJtbDBjejBpYjJKcVpXTjBRbTkxYm1ScGJtZENiM2dpUGp4eVpXTjBJSGRwWkhSb1BTSXhJaUJvWldsbmFIUTlJakVpSUdacGJHdzlJblZ5YkNnalozSmhaQzExY0NraUlDOCtQQzl0WVhOclBqeHRZWE5ySUdsa1BTSm1ZV1JsTFdSdmQyNGlJRzFoYzJ0RGIyNTBaVzUwVlc1cGRITTlJbTlpYW1WamRFSnZkVzVrYVc1blFtOTRJajQ4Y21WamRDQjNhV1IwYUQwaU1TSWdhR1ZwWjJoMFBTSXhJaUJtYVd4c1BTSjFjbXdvSTJkeVlXUXRaRzkzYmlraUlDOCtQQzl0WVhOclBqeHRZWE5ySUdsa1BTSnViMjVsSWlCdFlYTnJRMjl1ZEdWdWRGVnVhWFJ6UFNKdlltcGxZM1JDYjNWdVpHbHVaMEp2ZUNJK1BISmxZM1FnZDJsa2RHZzlJakVpSUdobGFXZG9kRDBpTVNJZ1ptbHNiRDBpZDJocGRHVWlJQzgrUEM5dFlYTnJQanhzYVc1bFlYSkhjbUZrYVdWdWRDQnBaRDBpWjNKaFpDMXplVzFpYjJ3aVBqeHpkRzl3SUc5bVpuTmxkRDBpTUM0M0lpQnpkRzl3TFdOdmJHOXlQU0ozYUdsMFpTSWdjM1J2Y0MxdmNHRmphWFI1UFNJeElpQXZQanh6ZEc5d0lHOW1abk5sZEQwaUxqazFJaUJ6ZEc5d0xXTnZiRzl5UFNKM2FHbDBaU0lnYzNSdmNDMXZjR0ZqYVhSNVBTSXdJaUF2UGp3dmJHbHVaV0Z5UjNKaFpHbGxiblErUEcxaGMyc2dhV1E5SW1aaFpHVXRjM2x0WW05c0lpQnRZWE5yUTI5dWRHVnVkRlZ1YVhSelBTSjFjMlZ5VTNCaFkyVlBibFZ6WlNJK1BISmxZM1FnZDJsa2RHZzlJakk1TUhCNElpQm9aV2xuYUhROUlqSXdNSEI0SWlCbWFXeHNQU0oxY213b0kyZHlZV1F0YzNsdFltOXNLU0lnTHo0OEwyMWhjMnMrUEM5a1pXWnpQanhuSUdOc2FYQXRjR0YwYUQwaWRYSnNLQ05qYjNKdVpYSnpLU0krUEhKbFkzUWdabWxzYkQwaVlXSmpaR1ZoSWlCNFBTSXdjSGdpSUhrOUlqQndlQ0lnZDJsa2RHZzlJakk1TUhCNElpQm9aV2xuYUhROUlqVXdNSEI0SWlBdlBqeHlaV04wSUhOMGVXeGxQU0ptYVd4MFpYSTZJSFZ5YkNnalpqRXBJaUI0UFNJd2NIZ2lJSGs5SWpCd2VDSWdkMmxrZEdnOUlqSTVNSEI0SWlCb1pXbG5hSFE5SWpVd01IQjRJaUF2UGlBOFp5QnpkSGxzWlQwaVptbHNkR1Z5T25WeWJDZ2pkRzl3TFhKbFoybHZiaTFpYkhWeUtUc2dkSEpoYm5ObWIzSnRPbk5qWVd4bEtERXVOU2s3SUhSeVlXNXpabTl5YlMxdmNtbG5hVzQ2WTJWdWRHVnlJSFJ2Y0RzaVBqeHlaV04wSUdacGJHdzlJbTV2Ym1VaUlIZzlJakJ3ZUNJZ2VUMGlNSEI0SWlCM2FXUjBhRDBpTWprd2NIZ2lJR2hsYVdkb2REMGlOVEF3Y0hnaUlDOCtQR1ZzYkdsd2MyVWdZM2c5SWpVd0pTSWdZM2s5SWpCd2VDSWdjbmc5SWpFNE1IQjRJaUJ5ZVQwaU1USXdjSGdpSUdacGJHdzlJaU13TURBaUlHOXdZV05wZEhrOUlqQXVPRFVpSUM4K1BDOW5Qanh5WldOMElIZzlJakFpSUhrOUlqQWlJSGRwWkhSb1BTSXlPVEFpSUdobGFXZG9kRDBpTlRBd0lpQnllRDBpTkRJaUlISjVQU0kwTWlJZ1ptbHNiRDBpY21kaVlTZ3dMREFzTUN3d0tTSWdjM1J5YjJ0bFBTSnlaMkpoS0RJMU5Td3lOVFVzTWpVMUxEQXVNaWtpSUM4K1BDOW5QangwWlhoMElIUmxlSFF0Y21WdVpHVnlhVzVuUFNKdmNIUnBiV2w2WlZOd1pXVmtJajQ4ZEdWNGRGQmhkR2dnYzNSaGNuUlBabVp6WlhROUlpMHhNREFsSWlCbWFXeHNQU0ozYUdsMFpTSWdabTl1ZEMxbVlXMXBiSGs5SWlkRGIzVnlhV1Z5SUU1bGR5Y3NJRzF2Ym05emNHRmpaU0lnWm05dWRDMXphWHBsUFNJeE1IQjRJaUI0YkdsdWF6cG9jbVZtUFNJamRHVjRkQzF3WVhSb0xXRWlQakI0TVRJek5EVTJOemc1TURFeU16UTFOamM0T1RFeU16UTFOamM0T1RBeE1qTTBOVFkzT0Rrd01TRGlnS0lnVjBWVVNDQThZVzVwYldGMFpTQmhaR1JwZEdsMlpUMGljM1Z0SWlCaGRIUnlhV0oxZEdWT1lXMWxQU0p6ZEdGeWRFOW1abk5sZENJZ1puSnZiVDBpTUNVaUlIUnZQU0l4TURBbElpQmlaV2RwYmowaU1ITWlJR1IxY2owaU16QnpJaUJ5WlhCbFlYUkRiM1Z1ZEQwaWFXNWtaV1pwYm1sMFpTSWdMejQ4TDNSbGVIUlFZWFJvUGlBOGRHVjRkRkJoZEdnZ2MzUmhjblJQWm1aelpYUTlJakFsSWlCbWFXeHNQU0ozYUdsMFpTSWdabTl1ZEMxbVlXMXBiSGs5SWlkRGIzVnlhV1Z5SUU1bGR5Y3NJRzF2Ym05emNHRmpaU0lnWm05dWRDMXphWHBsUFNJeE1IQjRJaUI0YkdsdWF6cG9jbVZtUFNJamRHVjRkQzF3WVhSb0xXRWlQakI0TVRJek5EVTJOemc1TURFeU16UTFOamM0T1RFeU16UTFOamM0T1RBeE1qTTBOVFkzT0Rrd01TRGlnS0lnVjBWVVNDQThZVzVwYldGMFpTQmhaR1JwZEdsMlpUMGljM1Z0SWlCaGRIUnlhV0oxZEdWT1lXMWxQU0p6ZEdGeWRFOW1abk5sZENJZ1puSnZiVDBpTUNVaUlIUnZQU0l4TURBbElpQmlaV2RwYmowaU1ITWlJR1IxY2owaU16QnpJaUJ5WlhCbFlYUkRiM1Z1ZEQwaWFXNWtaV1pwYm1sMFpTSWdMejRnUEM5MFpYaDBVR0YwYUQ0OGRHVjRkRkJoZEdnZ2MzUmhjblJQWm1aelpYUTlJalV3SlNJZ1ptbHNiRDBpZDJocGRHVWlJR1p2Ym5RdFptRnRhV3g1UFNJblEyOTFjbWxsY2lCT1pYY25MQ0J0YjI1dmMzQmhZMlVpSUdadmJuUXRjMmw2WlQwaU1UQndlQ0lnZUd4cGJtczZhSEpsWmowaUkzUmxlSFF0Y0dGMGFDMWhJajR3ZUdGaVkyUmxZV0pqWkdWbVlXSmpaR1ZtWVdKalpHVm1ZV0pqWkdWbVlXSmpaR1ZtWVdKalpHWWc0b0NpSUZWT1NTQThZVzVwYldGMFpTQmhaR1JwZEdsMlpUMGljM1Z0SWlCaGRIUnlhV0oxZEdWT1lXMWxQU0p6ZEdGeWRFOW1abk5sZENJZ1puSnZiVDBpTUNVaUlIUnZQU0l4TURBbElpQmlaV2RwYmowaU1ITWlJR1IxY2owaU16QnpJaUJ5WlhCbFlYUkRiM1Z1ZEQwaWFXNWtaV1pwYm1sMFpTSWdMejQ4TDNSbGVIUlFZWFJvUGp4MFpYaDBVR0YwYUNCemRHRnlkRTltWm5ObGREMGlMVFV3SlNJZ1ptbHNiRDBpZDJocGRHVWlJR1p2Ym5RdFptRnRhV3g1UFNJblEyOTFjbWxsY2lCT1pYY25MQ0J0YjI1dmMzQmhZMlVpSUdadmJuUXRjMmw2WlQwaU1UQndlQ0lnZUd4cGJtczZhSEpsWmowaUkzUmxlSFF0Y0dGMGFDMWhJajR3ZUdGaVkyUmxZV0pqWkdWbVlXSmpaR1ZtWVdKalpHVm1ZV0pqWkdWbVlXSmpaR1ZtWVdKalpHWWc0b0NpSUZWT1NTQThZVzVwYldGMFpTQmhaR1JwZEdsMlpUMGljM1Z0SWlCaGRIUnlhV0oxZEdWT1lXMWxQU0p6ZEdGeWRFOW1abk5sZENJZ1puSnZiVDBpTUNVaUlIUnZQU0l4TURBbElpQmlaV2RwYmowaU1ITWlJR1IxY2owaU16QnpJaUJ5WlhCbFlYUkRiM1Z1ZEQwaWFXNWtaV1pwYm1sMFpTSWdMejQ4TDNSbGVIUlFZWFJvUGp3dmRHVjRkRDQ4WnlCdFlYTnJQU0oxY213b0kyWmhaR1V0YzNsdFltOXNLU0krUEhKbFkzUWdabWxzYkQwaWJtOXVaU0lnZUQwaU1IQjRJaUI1UFNJd2NIZ2lJSGRwWkhSb1BTSXlPVEJ3ZUNJZ2FHVnBaMmgwUFNJeU1EQndlQ0lnTHo0Z1BIUmxlSFFnZVQwaU56QndlQ0lnZUQwaU16SndlQ0lnWm1sc2JEMGlkMmhwZEdVaUlHWnZiblF0Wm1GdGFXeDVQU0luUTI5MWNtbGxjaUJPWlhjbkxDQnRiMjV2YzNCaFkyVWlJR1p2Ym5RdGQyVnBaMmgwUFNJeU1EQWlJR1p2Ym5RdGMybDZaVDBpTXpad2VDSStWVTVKTDFkRlZFZzhMM1JsZUhRK1BIUmxlSFFnZVQwaU1URTFjSGdpSUhnOUlqTXljSGdpSUdacGJHdzlJbmRvYVhSbElpQm1iMjUwTFdaaGJXbHNlVDBpSjBOdmRYSnBaWElnVG1WM0p5d2diVzl1YjNOd1lXTmxJaUJtYjI1MExYZGxhV2RvZEQwaU1qQXdJaUJtYjI1MExYTnBlbVU5SWpNMmNIZ2lQakF1TURVbFBDOTBaWGgwUGp3dlp6NDhjbVZqZENCNFBTSXhOaUlnZVQwaU1UWWlJSGRwWkhSb1BTSXlOVGdpSUdobGFXZG9kRDBpTkRZNElpQnllRDBpTWpZaUlISjVQU0l5TmlJZ1ptbHNiRDBpY21kaVlTZ3dMREFzTUN3d0tTSWdjM1J5YjJ0bFBTSnlaMkpoS0RJMU5Td3lOVFVzTWpVMUxEQXVNaWtpSUM4K1BHY2diV0Z6YXowaWRYSnNLQ05tWVdSbExXUnZkMjRwSWlCemRIbHNaVDBpZEhKaGJuTm1iM0p0T25SeVlXNXpiR0YwWlNnM01uQjRMREU0T1hCNEtTSStQSEpsWTNRZ2VEMGlMVEUyY0hnaUlIazlJaTB4Tm5CNElpQjNhV1IwYUQwaU1UZ3djSGdpSUdobGFXZG9kRDBpTVRnd2NIZ2lJR1pwYkd3OUltNXZibVVpSUM4K1BIQmhkR2dnWkQwaVRURWdNVU01SURneElEWTFJREV6TnlBeE5EVWdNVFExSWlCemRISnZhMlU5SW5KblltRW9NQ3d3TERBc01DNHpLU0lnYzNSeWIydGxMWGRwWkhSb1BTSXpNbkI0SWlCbWFXeHNQU0p1YjI1bElpQnpkSEp2YTJVdGJHbHVaV05oY0QwaWNtOTFibVFpSUM4K1BDOW5QanhuSUcxaGMyczlJblZ5YkNnalptRmtaUzFrYjNkdUtTSWdjM1I1YkdVOUluUnlZVzV6Wm05eWJUcDBjbUZ1YzJ4aGRHVW9Oekp3ZUN3eE9EbHdlQ2tpUGp4eVpXTjBJSGc5SWkweE5uQjRJaUI1UFNJdE1UWndlQ0lnZDJsa2RHZzlJakU0TUhCNElpQm9aV2xuYUhROUlqRTRNSEI0SWlCbWFXeHNQU0p1YjI1bElpQXZQanh3WVhSb0lHUTlJazB4SURGRE9TQTRNU0EyTlNBeE16Y2dNVFExSURFME5TSWdjM1J5YjJ0bFBTSnlaMkpoS0RJMU5Td3lOVFVzTWpVMUxERXBJaUJtYVd4c1BTSnViMjVsSWlCemRISnZhMlV0YkdsdVpXTmhjRDBpY205MWJtUWlJQzgrUEM5blBqeGphWEpqYkdVZ1kzZzlJamN6Y0hnaUlHTjVQU0l4T1RCd2VDSWdjajBpTkhCNElpQm1hV3hzUFNKM2FHbDBaU0lnTHo0OFkybHlZMnhsSUdONFBTSTNNM0I0SWlCamVUMGlNVGt3Y0hnaUlISTlJakkwY0hnaUlHWnBiR3c5SW01dmJtVWlJSE4wY205clpUMGlkMmhwZEdVaUlDOCtJRHhuSUhOMGVXeGxQU0owY21GdWMyWnZjbTA2ZEhKaGJuTnNZWFJsS0RJNWNIZ3NJRE00TkhCNEtTSStQSEpsWTNRZ2QybGtkR2c5SWpZemNIZ2lJR2hsYVdkb2REMGlNalp3ZUNJZ2NuZzlJamh3ZUNJZ2NuazlJamh3ZUNJZ1ptbHNiRDBpY21kaVlTZ3dMREFzTUN3d0xqWXBJaUF2UGp4MFpYaDBJSGc5SWpFeWNIZ2lJSGs5SWpFM2NIZ2lJR1p2Ym5RdFptRnRhV3g1UFNJblEyOTFjbWxsY2lCT1pYY25MQ0J0YjI1dmMzQmhZMlVpSUdadmJuUXRjMmw2WlQwaU1USndlQ0lnWm1sc2JEMGlkMmhwZEdVaVBqeDBjM0JoYmlCbWFXeHNQU0p5WjJKaEtESTFOU3d5TlRVc01qVTFMREF1TmlraVBrbEVPaUE4TDNSemNHRnVQakU4TDNSbGVIUStQQzluUGlBOFp5QnpkSGxzWlQwaWRISmhibk5tYjNKdE9uUnlZVzV6YkdGMFpTZ3lPWEI0TENBME1UUndlQ2tpUGp4eVpXTjBJSGRwWkhSb1BTSXhNRFZ3ZUNJZ2FHVnBaMmgwUFNJeU5uQjRJaUJ5ZUQwaU9IQjRJaUJ5ZVQwaU9IQjRJaUJtYVd4c1BTSnlaMkpoS0RBc01Dd3dMREF1TmlraUlDOCtQSFJsZUhRZ2VEMGlNVEp3ZUNJZ2VUMGlNVGR3ZUNJZ1ptOXVkQzFtWVcxcGJIazlJaWREYjNWeWFXVnlJRTVsZHljc0lHMXZibTl6Y0dGalpTSWdabTl1ZEMxemFYcGxQU0l4TW5CNElpQm1hV3hzUFNKM2FHbDBaU0krUEhSemNHRnVJR1pwYkd3OUluSm5ZbUVvTWpVMUxESTFOU3d5TlRVc01DNDJLU0krVFdsdUlGUnBZMnM2SUR3dmRITndZVzQrTUR3dmRHVjRkRDQ4TDJjK0lEeG5JSE4wZVd4bFBTSjBjbUZ1YzJadmNtMDZkSEpoYm5Oc1lYUmxLREk1Y0hnc0lEUTBOSEI0S1NJK1BISmxZM1FnZDJsa2RHZzlJakV5Tm5CNElpQm9aV2xuYUhROUlqSTJjSGdpSUhKNFBTSTRjSGdpSUhKNVBTSTRjSGdpSUdacGJHdzlJbkpuWW1Fb01Dd3dMREFzTUM0MktTSWdMejQ4ZEdWNGRDQjRQU0l4TW5CNElpQjVQU0l4TjNCNElpQm1iMjUwTFdaaGJXbHNlVDBpSjBOdmRYSnBaWElnVG1WM0p5d2diVzl1YjNOd1lXTmxJaUJtYjI1MExYTnBlbVU5SWpFeWNIZ2lJR1pwYkd3OUluZG9hWFJsSWo0OGRITndZVzRnWm1sc2JEMGljbWRpWVNneU5UVXNNalUxTERJMU5Td3dMallwSWo1TllYZ2dWR2xqYXpvZ1BDOTBjM0JoYmo0eE1EQXdQQzkwWlhoMFBqd3ZaejQ4WnlCemRIbHNaVDBpZEhKaGJuTm1iM0p0T25SeVlXNXpiR0YwWlNneU1qWndlQ3dnTkRNemNIZ3BJajQ4Y21WamRDQjNhV1IwYUQwaU16WndlQ0lnYUdWcFoyaDBQU0l6Tm5CNElpQnllRDBpT0hCNElpQnllVDBpT0hCNElpQm1hV3hzUFNKdWIyNWxJaUJ6ZEhKdmEyVTlJbkpuWW1Fb01qVTFMREkxTlN3eU5UVXNNQzR5S1NJZ0x6NDhjR0YwYUNCemRISnZhMlV0YkdsdVpXTmhjRDBpY205MWJtUWlJR1E5SWswNElEbERPQzR3TURBd05DQXlNaTQ1TkRrMElERTJMakl3T1RrZ01qZ2dNamNnTWpnaUlHWnBiR3c5SW01dmJtVWlJSE4wY205clpUMGlkMmhwZEdVaUlDOCtQR05wY21Oc1pTQnpkSGxzWlQwaWRISmhibk5tYjNKdE9uUnlZVzV6YkdGMFpUTmtLREV6Y0hnc0lESXpjSGdzSURCd2VDa2lJR040UFNJd2NIZ2lJR041UFNJd2NIZ2lJSEk5SWpSd2VDSWdabWxzYkQwaWQyaHBkR1VpTHo0OEwyYytQR2NnYzNSNWJHVTlJblJ5WVc1elptOXliVHAwY21GdWMyeGhkR1VvTWpJMmNIZ3NJRE01TW5CNEtTSStQSEpsWTNRZ2QybGtkR2c5SWpNMmNIZ2lJR2hsYVdkb2REMGlNelp3ZUNJZ2NuZzlJamh3ZUNJZ2NuazlJamh3ZUNJZ1ptbHNiRDBpYm05dVpTSWdjM1J5YjJ0bFBTSnlaMkpoS0RJMU5Td3lOVFVzTWpVMUxEQXVNaWtpSUM4K1BHYytQSEJoZEdnZ2MzUjViR1U5SW5SeVlXNXpabTl5YlRwMGNtRnVjMnhoZEdVb05uQjRMRFp3ZUNraUlHUTlJazB4TWlBd1RERXlMalkxTWpJZ09TNDFOalU0TjB3eE9DQXhMall3TnpkTU1UTXVOemd4T1NBeE1DNHlNVGd4VERJeUxqTTVNak1nTmt3eE5DNDBNelF4SURFeExqTTBOemhNTWpRZ01USk1NVFF1TkRNME1TQXhNaTQyTlRJeVRESXlMak01TWpNZ01UaE1NVE11TnpneE9TQXhNeTQzT0RFNVRERTRJREl5TGpNNU1qTk1NVEl1TmpVeU1pQXhOQzQwTXpReFRERXlJREkwVERFeExqTTBOemdnTVRRdU5ETTBNVXcySURJeUxqTTVNak5NTVRBdU1qRTRNU0F4TXk0M09ERTVUREV1TmpBM055QXhPRXc1TGpVMk5UZzNJREV5TGpZMU1qSk1NQ0F4TWt3NUxqVTJOVGczSURFeExqTTBOemhNTVM0Mk1EYzNJRFpNTVRBdU1qRTRNU0F4TUM0eU1UZ3hURFlnTVM0Mk1EYzNUREV4TGpNME56Z2dPUzQxTmpVNE4wd3hNaUF3V2lJZ1ptbHNiRDBpZDJocGRHVWlJQzgrUEdGdWFXMWhkR1ZVY21GdWMyWnZjbTBnWVhSMGNtbGlkWFJsVG1GdFpUMGlkSEpoYm5ObWIzSnRJaUIwZVhCbFBTSnliM1JoZEdVaUlHWnliMjA5SWpBZ01UZ2dNVGdpSUhSdlBTSXpOakFnTVRnZ01UZ2lJR1IxY2owaU1UQnpJaUJ5WlhCbFlYUkRiM1Z1ZEQwaWFXNWtaV1pwYm1sMFpTSXZQand2Wno0OEwyYytQQzl6ZG1jKyJ9"`; - -exports[`NFTDescriptor #svgImage matches the current snapshot 1`] = `" 0xabcdeabcdefabcdefabcdefabcdefabcdefabcdf • WETH 0xabcdeabcdefabcdefabcdefabcdefabcdefabcdf • WETH 0x1234567890123456789123456789012345678901 • UNI 0x1234567890123456789123456789012345678901 • UNI UNI/WETH0.05% ID: 123 Min Tick: -1000 Max Tick: 2000"`; diff --git a/lib/v3-periphery/test/__snapshots__/NFTDescriptor.svg b/lib/v3-periphery/test/__snapshots__/NFTDescriptor.svg deleted file mode 100644 index d09c263..0000000 --- a/lib/v3-periphery/test/__snapshots__/NFTDescriptor.svg +++ /dev/null @@ -1 +0,0 @@ - 0xabcdeabcdefabcdefabcdefabcdefabcdefabcdf • WETH 0xabcdeabcdefabcdefabcdefabcdefabcdefabcdf • WETH 0x1234567890123456789123456789012345678901 • UNI 0x1234567890123456789123456789012345678901 • UNI UNI/WETH0.05% ID: 123 Min Tick: -1000 Max Tick: 2000 \ No newline at end of file diff --git a/lib/v3-periphery/test/__snapshots__/NonfungiblePositionManager.spec.ts.snap b/lib/v3-periphery/test/__snapshots__/NonfungiblePositionManager.spec.ts.snap deleted file mode 100644 index 488d514..0000000 --- a/lib/v3-periphery/test/__snapshots__/NonfungiblePositionManager.spec.ts.snap +++ /dev/null @@ -1,41 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`NonfungiblePositionManager #burn gas 1`] = `66076`; - -exports[`NonfungiblePositionManager #collect gas transfers both 1`] = `118970`; - -exports[`NonfungiblePositionManager #collect gas transfers token0 only 1`] = `111897`; - -exports[`NonfungiblePositionManager #collect gas transfers token1 only 1`] = `112104`; - -exports[`NonfungiblePositionManager #createAndInitializePoolIfNecessary gas 1`] = `4612043`; - -exports[`NonfungiblePositionManager #decreaseLiquidity gas complete decrease 1`] = `148666`; - -exports[`NonfungiblePositionManager #decreaseLiquidity gas partial decrease 1`] = `161366`; - -exports[`NonfungiblePositionManager #increaseLiquidity gas 1`] = `176626`; - -exports[`NonfungiblePositionManager #mint gas first mint for pool 1`] = `619406`; - -exports[`NonfungiblePositionManager #mint gas first mint for pool using eth with non-zero refund 1`] = `629749`; - -exports[`NonfungiblePositionManager #mint gas first mint for pool using eth with zero refund 1`] = `622524`; - -exports[`NonfungiblePositionManager #mint gas mint for same pool, different ticks 1`] = `451862`; - -exports[`NonfungiblePositionManager #mint gas mint on same ticks 1`] = `344732`; - -exports[`NonfungiblePositionManager #permit owned by eoa gas 1`] = `64492`; - -exports[`NonfungiblePositionManager #permit owned by verifying contract gas 1`] = `68289`; - -exports[`NonfungiblePositionManager #positions gas 1`] = `19890`; - -exports[`NonfungiblePositionManager #transferFrom gas 1`] = `109691`; - -exports[`NonfungiblePositionManager #transferFrom gas comes from approved 1`] = `108291`; - -exports[`NonfungiblePositionManager bytecode size 1`] = `24450`; - -exports[`NonfungiblePositionManager multicall exit gas 1`] = `228718`; diff --git a/lib/v3-periphery/test/__snapshots__/OracleLibrary.spec.ts.snap b/lib/v3-periphery/test/__snapshots__/OracleLibrary.spec.ts.snap deleted file mode 100644 index e8fd682..0000000 --- a/lib/v3-periphery/test/__snapshots__/OracleLibrary.spec.ts.snap +++ /dev/null @@ -1,3 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`OracleLibrary #getQuoteAtTick gas test 1`] = `1205`; diff --git a/lib/v3-periphery/test/__snapshots__/PairFlash.spec.ts.snap b/lib/v3-periphery/test/__snapshots__/PairFlash.spec.ts.snap deleted file mode 100644 index 558e03e..0000000 --- a/lib/v3-periphery/test/__snapshots__/PairFlash.spec.ts.snap +++ /dev/null @@ -1,3 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`PairFlash test flash gas 1`] = `349643`; diff --git a/lib/v3-periphery/test/__snapshots__/Path.spec.ts.snap b/lib/v3-periphery/test/__snapshots__/Path.spec.ts.snap deleted file mode 100644 index e450df9..0000000 --- a/lib/v3-periphery/test/__snapshots__/Path.spec.ts.snap +++ /dev/null @@ -1,3 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Path gas cost 1`] = `451`; diff --git a/lib/v3-periphery/test/__snapshots__/PeripheryImmutableState.spec.ts.snap b/lib/v3-periphery/test/__snapshots__/PeripheryImmutableState.spec.ts.snap deleted file mode 100644 index b79d75f..0000000 --- a/lib/v3-periphery/test/__snapshots__/PeripheryImmutableState.spec.ts.snap +++ /dev/null @@ -1,3 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`PeripheryImmutableState bytecode size 1`] = `193`; diff --git a/lib/v3-periphery/test/__snapshots__/PoolAddress.spec.ts.snap b/lib/v3-periphery/test/__snapshots__/PoolAddress.spec.ts.snap deleted file mode 100644 index 7471415..0000000 --- a/lib/v3-periphery/test/__snapshots__/PoolAddress.spec.ts.snap +++ /dev/null @@ -1,5 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`PoolAddress #computeAddress gas cost 1`] = `642`; - -exports[`PoolAddress #computeAddress matches example from core repo 1`] = `"0x03D8bab195A5BC23d249693F53dfA0e358F2650D"`; diff --git a/lib/v3-periphery/test/__snapshots__/PositionValue.spec.ts.snap b/lib/v3-periphery/test/__snapshots__/PositionValue.spec.ts.snap deleted file mode 100644 index 3d8f9d4..0000000 --- a/lib/v3-periphery/test/__snapshots__/PositionValue.spec.ts.snap +++ /dev/null @@ -1,11 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`PositionValue #fees when price is above the position range gas 1`] = `47658`; - -exports[`PositionValue #fees when price is below the position range gas 1`] = `47626`; - -exports[`PositionValue #fees when price is within the position range gas 1`] = `53216`; - -exports[`PositionValue #principal gas 1`] = `23001`; - -exports[`PositionValue #total gas 1`] = `59777`; diff --git a/lib/v3-periphery/test/__snapshots__/QuoterV2.spec.ts.snap b/lib/v3-periphery/test/__snapshots__/QuoterV2.spec.ts.snap deleted file mode 100644 index ccb9341..0000000 --- a/lib/v3-periphery/test/__snapshots__/QuoterV2.spec.ts.snap +++ /dev/null @@ -1,51 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`QuoterV2 quotes #quoteExactInput 0 -> 2 -> 1 1`] = `277146`; - -exports[`QuoterV2 quotes #quoteExactInput 0 -> 2 cross 0 tick, starting tick initialized 1`] = `123797`; - -exports[`QuoterV2 quotes #quoteExactInput 0 -> 2 cross 0 tick, starting tick not initialized 1`] = `100962`; - -exports[`QuoterV2 quotes #quoteExactInput 0 -> 2 cross 1 tick 1`] = `144724`; - -exports[`QuoterV2 quotes #quoteExactInput 0 -> 2 cross 2 tick 1`] = `182321`; - -exports[`QuoterV2 quotes #quoteExactInput 0 -> 2 cross 2 tick where after is initialized 1`] = `144762`; - -exports[`QuoterV2 quotes #quoteExactInput 2 -> 0 cross 0 tick, starting tick initialized 1`] = `97654`; - -exports[`QuoterV2 quotes #quoteExactInput 2 -> 0 cross 0 tick, starting tick not initialized 1`] = `93779`; - -exports[`QuoterV2 quotes #quoteExactInput 2 -> 0 cross 2 1`] = `175133`; - -exports[`QuoterV2 quotes #quoteExactInput 2 -> 0 cross 2 where tick after is initialized 1`] = `175141`; - -exports[`QuoterV2 quotes #quoteExactInput 2 -> 1 1`] = `97329`; - -exports[`QuoterV2 quotes #quoteExactInputSingle 0 -> 2 1`] = `182303`; - -exports[`QuoterV2 quotes #quoteExactInputSingle 2 -> 0 1`] = `175105`; - -exports[`QuoterV2 quotes #quoteExactOutput 0 -> 2 -> 1 1`] = `276746`; - -exports[`QuoterV2 quotes #quoteExactOutput 0 -> 2 cross 0 tick starting tick initialized 1`] = `123352`; - -exports[`QuoterV2 quotes #quoteExactOutput 0 -> 2 cross 0 tick starting tick not initialized 1`] = `100537`; - -exports[`QuoterV2 quotes #quoteExactOutput 0 -> 2 cross 1 tick 1`] = `144010`; - -exports[`QuoterV2 quotes #quoteExactOutput 0 -> 2 cross 2 tick 1`] = `181363`; - -exports[`QuoterV2 quotes #quoteExactOutput 0 -> 2 cross 2 where tick after is initialized 1`] = `144048`; - -exports[`QuoterV2 quotes #quoteExactOutput 2 -> 0 cross 1 tick 1`] = `137858`; - -exports[`QuoterV2 quotes #quoteExactOutput 2 -> 0 cross 2 ticks 1`] = `175203`; - -exports[`QuoterV2 quotes #quoteExactOutput 2 -> 0 cross 2 where tick after is initialized 1`] = `175197`; - -exports[`QuoterV2 quotes #quoteExactOutput 2 -> 1 1`] = `97870`; - -exports[`QuoterV2 quotes #quoteExactOutputSingle 0 -> 1 1`] = `105200`; - -exports[`QuoterV2 quotes #quoteExactOutputSingle 1 -> 0 1`] = `98511`; diff --git a/lib/v3-periphery/test/__snapshots__/SwapRouter.gas.spec.ts.snap b/lib/v3-periphery/test/__snapshots__/SwapRouter.gas.spec.ts.snap deleted file mode 100644 index ba9a0a9..0000000 --- a/lib/v3-periphery/test/__snapshots__/SwapRouter.gas.spec.ts.snap +++ /dev/null @@ -1,37 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`SwapRouter gas tests #exactInput 0 -> 1 -> 2 1`] = `172498`; - -exports[`SwapRouter gas tests #exactInput 0 -> 1 1`] = `107759`; - -exports[`SwapRouter gas tests #exactInput 0 -> 1 minimal 1`] = `98059`; - -exports[`SwapRouter gas tests #exactInput 0 -> WETH9 1`] = `127578`; - -exports[`SwapRouter gas tests #exactInput 2 trades (via router) 1`] = `188814`; - -exports[`SwapRouter gas tests #exactInput 3 trades (directly to sender) 1`] = `258601`; - -exports[`SwapRouter gas tests #exactInput WETH9 -> 0 1`] = `106083`; - -exports[`SwapRouter gas tests #exactInputSingle 0 -> 1 1`] = `107180`; - -exports[`SwapRouter gas tests #exactInputSingle 0 -> WETH9 1`] = `126993`; - -exports[`SwapRouter gas tests #exactInputSingle WETH9 -> 0 1`] = `105504`; - -exports[`SwapRouter gas tests #exactOutput 0 -> 1 -> 2 1`] = `169275`; - -exports[`SwapRouter gas tests #exactOutput 0 -> 1 1`] = `111757`; - -exports[`SwapRouter gas tests #exactOutput 0 -> WETH9 1`] = `128821`; - -exports[`SwapRouter gas tests #exactOutput WETH9 -> 0 1`] = `119691`; - -exports[`SwapRouter gas tests #exactOutputSingle 0 -> 1 1`] = `111967`; - -exports[`SwapRouter gas tests #exactOutputSingle 0 -> WETH9 1`] = `129031`; - -exports[`SwapRouter gas tests #exactOutputSingle WETH9 -> 0 1`] = `114366`; - -exports[`SwapRouter gas tests 3 trades (directly to sender) 1`] = `179440`; diff --git a/lib/v3-periphery/test/__snapshots__/SwapRouter.spec.ts.snap b/lib/v3-periphery/test/__snapshots__/SwapRouter.spec.ts.snap deleted file mode 100644 index d123c7d..0000000 --- a/lib/v3-periphery/test/__snapshots__/SwapRouter.spec.ts.snap +++ /dev/null @@ -1,3 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`SwapRouter bytecode size 1`] = `12160`; diff --git a/lib/v3-periphery/test/__snapshots__/TickLens.spec.ts.snap b/lib/v3-periphery/test/__snapshots__/TickLens.spec.ts.snap deleted file mode 100644 index 3bdf4fc..0000000 --- a/lib/v3-periphery/test/__snapshots__/TickLens.spec.ts.snap +++ /dev/null @@ -1,5 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`TickLens #getPopulatedTicksInWord fully populated ticks 1`] = `2803889`; - -exports[`TickLens #getPopulatedTicksInWord gas for single populated tick 1`] = `55664`; diff --git a/lib/v3-periphery/test/__snapshots__/V3Migrator.spec.ts.snap b/lib/v3-periphery/test/__snapshots__/V3Migrator.spec.ts.snap deleted file mode 100644 index 0248aa8..0000000 --- a/lib/v3-periphery/test/__snapshots__/V3Migrator.spec.ts.snap +++ /dev/null @@ -1,3 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`V3Migrator #migrate gas 1`] = `730625`; diff --git a/lib/v3-periphery/test/contracts/WETH9.json b/lib/v3-periphery/test/contracts/WETH9.json deleted file mode 100644 index 68ec24f..0000000 --- a/lib/v3-periphery/test/contracts/WETH9.json +++ /dev/null @@ -1,156 +0,0 @@ -{ - "bytecode": "60606040526040805190810160405280600d81526020017f57726170706564204574686572000000000000000000000000000000000000008152506000908051906020019061004f9291906100c8565b506040805190810160405280600481526020017f57455448000000000000000000000000000000000000000000000000000000008152506001908051906020019061009b9291906100c8565b506012600260006101000a81548160ff021916908360ff16021790555034156100c357600080fd5b61016d565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061010957805160ff1916838001178555610137565b82800160010185558215610137579182015b8281111561013657825182559160200191906001019061011b565b5b5090506101449190610148565b5090565b61016a91905b8082111561016657600081600090555060010161014e565b5090565b90565b610c348061017c6000396000f3006060604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100b9578063095ea7b31461014757806318160ddd146101a157806323b872dd146101ca5780632e1a7d4d14610243578063313ce5671461026657806370a082311461029557806395d89b41146102e2578063a9059cbb14610370578063d0e30db0146103ca578063dd62ed3e146103d4575b6100b7610440565b005b34156100c457600080fd5b6100cc6104dd565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561010c5780820151818401526020810190506100f1565b50505050905090810190601f1680156101395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015257600080fd5b610187600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061057b565b604051808215151515815260200191505060405180910390f35b34156101ac57600080fd5b6101b461066d565b6040518082815260200191505060405180910390f35b34156101d557600080fd5b610229600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061068c565b604051808215151515815260200191505060405180910390f35b341561024e57600080fd5b61026460048080359060200190919050506109d9565b005b341561027157600080fd5b610279610b05565b604051808260ff1660ff16815260200191505060405180910390f35b34156102a057600080fd5b6102cc600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610b18565b6040518082815260200191505060405180910390f35b34156102ed57600080fd5b6102f5610b30565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561033557808201518184015260208101905061031a565b50505050905090810190601f1680156103625780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561037b57600080fd5b6103b0600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610bce565b604051808215151515815260200191505060405180910390f35b6103d2610440565b005b34156103df57600080fd5b61042a600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610be3565b6040518082815260200191505060405180910390f35b34600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055503373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a2565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105735780601f1061054857610100808354040283529160200191610573565b820191906000526020600020905b81548152906001019060200180831161055657829003601f168201915b505050505081565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60003073ffffffffffffffffffffffffffffffffffffffff1631905090565b600081600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101515156106dc57600080fd5b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141580156107b457507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b156108cf5781600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561084457600080fd5b81600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b81600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610a2757600080fd5b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501515610ab457600080fd5b3373ffffffffffffffffffffffffffffffffffffffff167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65826040518082815260200191505060405180910390a250565b600260009054906101000a900460ff1681565b60036020528060005260406000206000915090505481565b60018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610bc65780601f10610b9b57610100808354040283529160200191610bc6565b820191906000526020600020905b815481529060010190602001808311610ba957829003601f168201915b505050505081565b6000610bdb33848461068c565b905092915050565b60046020528160005260406000206020528060005260406000206000915091505054815600a165627a7a72305820deb4c2ccab3c2fdca32ab3f46728389c2fe2c165d5fafa07661e4e004f6c344a0029", - "abi": [ - { - "constant": true, - "inputs": [], - "name": "name", - "outputs": [{ "name": "", "type": "string" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "name": "guy", "type": "address" }, - { "name": "wad", "type": "uint256" } - ], - "name": "approve", - "outputs": [{ "name": "", "type": "bool" }], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "totalSupply", - "outputs": [{ "name": "", "type": "uint256" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "name": "src", "type": "address" }, - { "name": "dst", "type": "address" }, - { "name": "wad", "type": "uint256" } - ], - "name": "transferFrom", - "outputs": [{ "name": "", "type": "bool" }], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [{ "name": "wad", "type": "uint256" }], - "name": "withdraw", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "decimals", - "outputs": [{ "name": "", "type": "uint8" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [{ "name": "", "type": "address" }], - "name": "balanceOf", - "outputs": [{ "name": "", "type": "uint256" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "symbol", - "outputs": [{ "name": "", "type": "string" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { "name": "dst", "type": "address" }, - { "name": "wad", "type": "uint256" } - ], - "name": "transfer", - "outputs": [{ "name": "", "type": "bool" }], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "deposit", - "outputs": [], - "payable": true, - "stateMutability": "payable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { "name": "", "type": "address" }, - { "name": "", "type": "address" } - ], - "name": "allowance", - "outputs": [{ "name": "", "type": "uint256" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { "payable": true, "stateMutability": "payable", "type": "fallback" }, - { - "anonymous": false, - "inputs": [ - { "indexed": true, "name": "src", "type": "address" }, - { "indexed": true, "name": "guy", "type": "address" }, - { "indexed": false, "name": "wad", "type": "uint256" } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { "indexed": true, "name": "src", "type": "address" }, - { "indexed": true, "name": "dst", "type": "address" }, - { "indexed": false, "name": "wad", "type": "uint256" } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { "indexed": true, "name": "dst", "type": "address" }, - { "indexed": false, "name": "wad", "type": "uint256" } - ], - "name": "Deposit", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { "indexed": true, "name": "src", "type": "address" }, - { "indexed": false, "name": "wad", "type": "uint256" } - ], - "name": "Withdrawal", - "type": "event" - } - ] -} diff --git a/lib/v3-periphery/test/shared/base64.ts b/lib/v3-periphery/test/shared/base64.ts deleted file mode 100644 index 3a17c2f..0000000 --- a/lib/v3-periphery/test/shared/base64.ts +++ /dev/null @@ -1,7 +0,0 @@ -export function base64Encode(str: string): string { - return Buffer.from(str, 'utf8').toString('base64') -} - -export function base64Decode(str: string): string { - return Buffer.from(str, 'base64').toString('utf8') -} diff --git a/lib/v3-periphery/test/shared/completeFixture.ts b/lib/v3-periphery/test/shared/completeFixture.ts deleted file mode 100644 index 6f3a8e9..0000000 --- a/lib/v3-periphery/test/shared/completeFixture.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { Fixture } from 'ethereum-waffle' -import { ethers } from 'hardhat' -import { v3RouterFixture } from './externalFixtures' -import { constants } from 'ethers' -import { - IWETH9, - MockTimeNonfungiblePositionManager, - MockTimeSwapRouter, - NonfungibleTokenPositionDescriptor, - TestERC20, - IUniswapV3Factory, -} from '../../typechain' - -const completeFixture: Fixture<{ - weth9: IWETH9 - factory: IUniswapV3Factory - router: MockTimeSwapRouter - nft: MockTimeNonfungiblePositionManager - nftDescriptor: NonfungibleTokenPositionDescriptor - tokens: [TestERC20, TestERC20, TestERC20] -}> = async ([wallet], provider) => { - const { weth9, factory, router } = await v3RouterFixture([wallet], provider) - - const tokenFactory = await ethers.getContractFactory('TestERC20') - const tokens: [TestERC20, TestERC20, TestERC20] = [ - (await tokenFactory.deploy(constants.MaxUint256.div(2))) as TestERC20, // do not use maxu256 to avoid overflowing - (await tokenFactory.deploy(constants.MaxUint256.div(2))) as TestERC20, - (await tokenFactory.deploy(constants.MaxUint256.div(2))) as TestERC20, - ] - - const nftDescriptorLibraryFactory = await ethers.getContractFactory('NFTDescriptor') - const nftDescriptorLibrary = await nftDescriptorLibraryFactory.deploy() - const positionDescriptorFactory = await ethers.getContractFactory('NonfungibleTokenPositionDescriptor', { - libraries: { - NFTDescriptor: nftDescriptorLibrary.address, - }, - }) - const nftDescriptor = (await positionDescriptorFactory.deploy( - tokens[0].address, - // 'ETH' as a bytes32 string - '0x4554480000000000000000000000000000000000000000000000000000000000' - )) as NonfungibleTokenPositionDescriptor - - const positionManagerFactory = await ethers.getContractFactory('MockTimeNonfungiblePositionManager') - const nft = (await positionManagerFactory.deploy( - factory.address, - weth9.address, - nftDescriptor.address - )) as MockTimeNonfungiblePositionManager - - tokens.sort((a, b) => (a.address.toLowerCase() < b.address.toLowerCase() ? -1 : 1)) - - return { - weth9, - factory, - router, - tokens, - nft, - nftDescriptor, - } -} - -export default completeFixture diff --git a/lib/v3-periphery/test/shared/computePoolAddress.ts b/lib/v3-periphery/test/shared/computePoolAddress.ts deleted file mode 100644 index fde8c8a..0000000 --- a/lib/v3-periphery/test/shared/computePoolAddress.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { bytecode } from '@uniswap/v3-core/artifacts/contracts/UniswapV3Pool.sol/UniswapV3Pool.json' -import { utils } from 'ethers' - -export const POOL_BYTECODE_HASH = utils.keccak256(bytecode) - -export function computePoolAddress(factoryAddress: string, [tokenA, tokenB]: [string, string], fee: number): string { - const [token0, token1] = tokenA.toLowerCase() < tokenB.toLowerCase() ? [tokenA, tokenB] : [tokenB, tokenA] - const constructorArgumentsEncoded = utils.defaultAbiCoder.encode( - ['address', 'address', 'uint24'], - [token0, token1, fee] - ) - const create2Inputs = [ - '0xff', - factoryAddress, - // salt - utils.keccak256(constructorArgumentsEncoded), - // init code hash - POOL_BYTECODE_HASH, - ] - const sanitizedInputs = `0x${create2Inputs.map((i) => i.slice(2)).join('')}` - return utils.getAddress(`0x${utils.keccak256(sanitizedInputs).slice(-40)}`) -} diff --git a/lib/v3-periphery/test/shared/constants.ts b/lib/v3-periphery/test/shared/constants.ts deleted file mode 100644 index df044c9..0000000 --- a/lib/v3-periphery/test/shared/constants.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { BigNumber } from 'ethers' - -export const MaxUint128 = BigNumber.from(2).pow(128).sub(1) - -export enum FeeAmount { - LOW = 500, - MEDIUM = 3000, - HIGH = 10000, -} - -export const TICK_SPACINGS: { [amount in FeeAmount]: number } = { - [FeeAmount.LOW]: 10, - [FeeAmount.MEDIUM]: 60, - [FeeAmount.HIGH]: 200, -} diff --git a/lib/v3-periphery/test/shared/encodePriceSqrt.ts b/lib/v3-periphery/test/shared/encodePriceSqrt.ts deleted file mode 100644 index f95cd23..0000000 --- a/lib/v3-periphery/test/shared/encodePriceSqrt.ts +++ /dev/null @@ -1,16 +0,0 @@ -import bn from 'bignumber.js' -import { BigNumber, BigNumberish } from 'ethers' - -bn.config({ EXPONENTIAL_AT: 999999, DECIMAL_PLACES: 40 }) - -// returns the sqrt price as a 64x96 -export function encodePriceSqrt(reserve1: BigNumberish, reserve0: BigNumberish): BigNumber { - return BigNumber.from( - new bn(reserve1.toString()) - .div(reserve0.toString()) - .sqrt() - .multipliedBy(new bn(2).pow(96)) - .integerValue(3) - .toString() - ) -} diff --git a/lib/v3-periphery/test/shared/expandTo18Decimals.ts b/lib/v3-periphery/test/shared/expandTo18Decimals.ts deleted file mode 100644 index 30d2864..0000000 --- a/lib/v3-periphery/test/shared/expandTo18Decimals.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { BigNumber } from 'ethers' - -export function expandTo18Decimals(n: number): BigNumber { - return BigNumber.from(n).mul(BigNumber.from(10).pow(18)) -} diff --git a/lib/v3-periphery/test/shared/expect.ts b/lib/v3-periphery/test/shared/expect.ts deleted file mode 100644 index ac8f19b..0000000 --- a/lib/v3-periphery/test/shared/expect.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { expect, use } from 'chai' -import { solidity } from 'ethereum-waffle' -import { jestSnapshotPlugin } from 'mocha-chai-jest-snapshot' - -use(solidity) -use(jestSnapshotPlugin()) - -export { expect } diff --git a/lib/v3-periphery/test/shared/externalFixtures.ts b/lib/v3-periphery/test/shared/externalFixtures.ts deleted file mode 100644 index 4ac7603..0000000 --- a/lib/v3-periphery/test/shared/externalFixtures.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { - abi as FACTORY_ABI, - bytecode as FACTORY_BYTECODE, -} from '@uniswap/v3-core/artifacts/contracts/UniswapV3Factory.sol/UniswapV3Factory.json' -import { abi as FACTORY_V2_ABI, bytecode as FACTORY_V2_BYTECODE } from '@uniswap/v2-core/build/UniswapV2Factory.json' -import { Fixture } from 'ethereum-waffle' -import { ethers, waffle } from 'hardhat' -import { IUniswapV3Factory, IWETH9, MockTimeSwapRouter } from '../../typechain' - -import WETH9 from '../contracts/WETH9.json' -import { Contract } from '@ethersproject/contracts' -import { constants } from 'ethers' - -const wethFixture: Fixture<{ weth9: IWETH9 }> = async ([wallet]) => { - const weth9 = (await waffle.deployContract(wallet, { - bytecode: WETH9.bytecode, - abi: WETH9.abi, - })) as IWETH9 - - return { weth9 } -} - -export const v2FactoryFixture: Fixture<{ factory: Contract }> = async ([wallet]) => { - const factory = await waffle.deployContract( - wallet, - { - bytecode: FACTORY_V2_BYTECODE, - abi: FACTORY_V2_ABI, - }, - [constants.AddressZero] - ) - - return { factory } -} - -const v3CoreFactoryFixture: Fixture = async ([wallet]) => { - return (await waffle.deployContract(wallet, { - bytecode: FACTORY_BYTECODE, - abi: FACTORY_ABI, - })) as IUniswapV3Factory -} - -export const v3RouterFixture: Fixture<{ - weth9: IWETH9 - factory: IUniswapV3Factory - router: MockTimeSwapRouter -}> = async ([wallet], provider) => { - const { weth9 } = await wethFixture([wallet], provider) - const factory = await v3CoreFactoryFixture([wallet], provider) - - const router = (await (await ethers.getContractFactory('MockTimeSwapRouter')).deploy( - factory.address, - weth9.address - )) as MockTimeSwapRouter - - return { factory, weth9, router } -} diff --git a/lib/v3-periphery/test/shared/extractJSONFromURI.ts b/lib/v3-periphery/test/shared/extractJSONFromURI.ts deleted file mode 100644 index 47105be..0000000 --- a/lib/v3-periphery/test/shared/extractJSONFromURI.ts +++ /dev/null @@ -1,5 +0,0 @@ -export function extractJSONFromURI(uri: string): { name: string; description: string; image: string } { - const encodedJSON = uri.substr('data:application/json;base64,'.length) - const decodedJSON = Buffer.from(encodedJSON, 'base64').toString('utf8') - return JSON.parse(decodedJSON) -} diff --git a/lib/v3-periphery/test/shared/formatSqrtRatioX96.spec.ts b/lib/v3-periphery/test/shared/formatSqrtRatioX96.spec.ts deleted file mode 100644 index 61e9661..0000000 --- a/lib/v3-periphery/test/shared/formatSqrtRatioX96.spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { encodePriceSqrt } from './encodePriceSqrt' -import { expect } from './expect' -import { formatSqrtRatioX96 } from './formatSqrtRatioX96' - -describe('#formatSqrtRatioX96', () => { - it('is correct for 9_999_999/10_000_000', () => { - expect(formatSqrtRatioX96(encodePriceSqrt(9_999_999, 10_000_000))).to.eq('1.0000') - }) - it('is correct for 9_999_999/1', () => { - expect(formatSqrtRatioX96(encodePriceSqrt(9_999_999, 1))).to.eq('10000000') - }) - it('is correct for 1/3', () => { - expect(formatSqrtRatioX96(encodePriceSqrt(1, 3))).to.eq('0.33333') - }) - it('is correct for 100/3', () => { - expect(formatSqrtRatioX96(encodePriceSqrt(100, 3))).to.eq('33.333') - }) - it('is correct for 1_000_000/3', () => { - expect(formatSqrtRatioX96(encodePriceSqrt(1_000_000, 3))).to.eq('333330') - }) - it('1e-18 still prints 5 sig figs', () => { - expect(formatSqrtRatioX96(encodePriceSqrt(1, 1e18), 18, 18)).to.eq('0.0000000000000000010000') - }) - it('accounts for decimal differences', () => { - expect(formatSqrtRatioX96(encodePriceSqrt(1e6, 1e18), 18, 6)).to.eq('1.0000') - }) - it('accounts for decimal differences in reverse', () => { - expect(formatSqrtRatioX96(encodePriceSqrt(1e18, 1e6), 6, 18)).to.eq('1.0000') - }) -}) diff --git a/lib/v3-periphery/test/shared/formatSqrtRatioX96.ts b/lib/v3-periphery/test/shared/formatSqrtRatioX96.ts deleted file mode 100644 index 7f93d55..0000000 --- a/lib/v3-periphery/test/shared/formatSqrtRatioX96.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { BigNumber } from 'ethers' -import Decimal from 'decimal.js' - -const TWO = BigNumber.from(2) -const TEN = BigNumber.from(10) -const FIVE_SIG_FIGS_POW = new Decimal(10).pow(5) - -export function formatSqrtRatioX96( - sqrtRatioX96: BigNumber | number, - decimalsToken0: number = 18, - decimalsToken1: number = 18 -): string { - Decimal.set({ toExpPos: 9_999_999, toExpNeg: -9_999_999 }) - - let ratioNum = ((parseInt(sqrtRatioX96.toString()) / 2 ** 96) ** 2).toPrecision(5) - let ratio = new Decimal(ratioNum.toString()) - - // adjust for decimals - if (decimalsToken1 < decimalsToken0) { - ratio = ratio.mul(TEN.pow(decimalsToken0 - decimalsToken1).toString()) - } else if (decimalsToken0 < decimalsToken1) { - ratio = ratio.div(TEN.pow(decimalsToken1 - decimalsToken0).toString()) - } - - if (ratio.lessThan(FIVE_SIG_FIGS_POW)) { - return ratio.toPrecision(5) - } - - return ratio.toString() -} diff --git a/lib/v3-periphery/test/shared/getPermitNFTSignature.ts b/lib/v3-periphery/test/shared/getPermitNFTSignature.ts deleted file mode 100644 index 697af96..0000000 --- a/lib/v3-periphery/test/shared/getPermitNFTSignature.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { BigNumber, BigNumberish, constants, Signature, Wallet } from 'ethers' -import { splitSignature } from 'ethers/lib/utils' -import { NonfungiblePositionManager } from '../../typechain' - -export default async function getPermitNFTSignature( - wallet: Wallet, - positionManager: NonfungiblePositionManager, - spender: string, - tokenId: BigNumberish, - deadline: BigNumberish = constants.MaxUint256, - permitConfig?: { nonce?: BigNumberish; name?: string; chainId?: number; version?: string } -): Promise { - const [nonce, name, version, chainId] = await Promise.all([ - permitConfig?.nonce ?? positionManager.positions(tokenId).then((p) => p.nonce), - permitConfig?.name ?? positionManager.name(), - permitConfig?.version ?? '1', - permitConfig?.chainId ?? wallet.getChainId(), - ]) - - return splitSignature( - await wallet._signTypedData( - { - name, - version, - chainId, - verifyingContract: positionManager.address, - }, - { - Permit: [ - { - name: 'spender', - type: 'address', - }, - { - name: 'tokenId', - type: 'uint256', - }, - { - name: 'nonce', - type: 'uint256', - }, - { - name: 'deadline', - type: 'uint256', - }, - ], - }, - { - owner: wallet.address, - spender, - tokenId, - nonce, - deadline, - } - ) - ) -} diff --git a/lib/v3-periphery/test/shared/path.ts b/lib/v3-periphery/test/shared/path.ts deleted file mode 100644 index 99418b1..0000000 --- a/lib/v3-periphery/test/shared/path.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { utils } from 'ethers' -import { FeeAmount } from './constants' - -const ADDR_SIZE = 20 -const FEE_SIZE = 3 -const OFFSET = ADDR_SIZE + FEE_SIZE -const DATA_SIZE = OFFSET + ADDR_SIZE - -export function encodePath(path: string[], fees: FeeAmount[]): string { - if (path.length != fees.length + 1) { - throw new Error('path/fee lengths do not match') - } - - let encoded = '0x' - for (let i = 0; i < fees.length; i++) { - // 20 byte encoding of the address - encoded += path[i].slice(2) - // 3 byte encoding of the fee - encoded += fees[i].toString(16).padStart(2 * FEE_SIZE, '0') - } - // encode the final token - encoded += path[path.length - 1].slice(2) - - return encoded.toLowerCase() -} - -function decodeOne(tokenFeeToken: Buffer): [[string, string], number] { - // reads the first 20 bytes for the token address - const tokenABuf = tokenFeeToken.slice(0, ADDR_SIZE) - const tokenA = utils.getAddress('0x' + tokenABuf.toString('hex')) - - // reads the next 2 bytes for the fee - const feeBuf = tokenFeeToken.slice(ADDR_SIZE, OFFSET) - const fee = feeBuf.readUIntBE(0, FEE_SIZE) - - // reads the next 20 bytes for the token address - const tokenBBuf = tokenFeeToken.slice(OFFSET, DATA_SIZE) - const tokenB = utils.getAddress('0x' + tokenBBuf.toString('hex')) - - return [[tokenA, tokenB], fee] -} - -export function decodePath(path: string): [string[], number[]] { - let data = Buffer.from(path.slice(2), 'hex') - - let tokens: string[] = [] - let fees: number[] = [] - let i = 0 - let finalToken: string = '' - while (data.length >= DATA_SIZE) { - const [[tokenA, tokenB], fee] = decodeOne(data) - finalToken = tokenB - tokens = [...tokens, tokenA] - fees = [...fees, fee] - data = data.slice((i + 1) * OFFSET) - i += 1 - } - tokens = [...tokens, finalToken] - - return [tokens, fees] -} diff --git a/lib/v3-periphery/test/shared/permit.ts b/lib/v3-periphery/test/shared/permit.ts deleted file mode 100644 index f3ec85d..0000000 --- a/lib/v3-periphery/test/shared/permit.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { BigNumberish, constants, Signature, Wallet } from 'ethers' -import { splitSignature } from 'ethers/lib/utils' -import { TestERC20, TestERC20PermitAllowed } from '../../typechain' - -export async function getPermitSignature( - wallet: Wallet, - token: TestERC20 | TestERC20PermitAllowed, - spender: string, - value: BigNumberish = constants.MaxUint256, - deadline = constants.MaxUint256, - permitConfig?: { nonce?: BigNumberish; name?: string; chainId?: number; version?: string } -): Promise { - const [nonce, name, version, chainId] = await Promise.all([ - permitConfig?.nonce ?? token.nonces(wallet.address), - permitConfig?.name ?? token.name(), - permitConfig?.version ?? '1', - permitConfig?.chainId ?? wallet.getChainId(), - ]) - - return splitSignature( - await wallet._signTypedData( - { - name, - version, - chainId, - verifyingContract: token.address, - }, - { - Permit: [ - { - name: 'owner', - type: 'address', - }, - { - name: 'spender', - type: 'address', - }, - { - name: 'value', - type: 'uint256', - }, - { - name: 'nonce', - type: 'uint256', - }, - { - name: 'deadline', - type: 'uint256', - }, - ], - }, - { - owner: wallet.address, - spender, - value, - nonce, - deadline, - } - ) - ) -} diff --git a/lib/v3-periphery/test/shared/poolAtAddress.ts b/lib/v3-periphery/test/shared/poolAtAddress.ts deleted file mode 100644 index b877813..0000000 --- a/lib/v3-periphery/test/shared/poolAtAddress.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { abi as POOL_ABI } from '@uniswap/v3-core/artifacts/contracts/UniswapV3Pool.sol/UniswapV3Pool.json' -import { Contract, Wallet } from 'ethers' -import { IUniswapV3Pool } from '../../typechain' - -export default function poolAtAddress(address: string, wallet: Wallet): IUniswapV3Pool { - return new Contract(address, POOL_ABI, wallet) as IUniswapV3Pool -} diff --git a/lib/v3-periphery/test/shared/quoter.ts b/lib/v3-periphery/test/shared/quoter.ts deleted file mode 100644 index 48d1b52..0000000 --- a/lib/v3-periphery/test/shared/quoter.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { Wallet } from 'ethers' -import { MockTimeNonfungiblePositionManager } from '../../typechain' -import { FeeAmount, TICK_SPACINGS } from './constants' -import { encodePriceSqrt } from './encodePriceSqrt' -import { getMaxTick, getMinTick } from './ticks' - -export async function createPool( - nft: MockTimeNonfungiblePositionManager, - wallet: Wallet, - tokenAddressA: string, - tokenAddressB: string -) { - if (tokenAddressA.toLowerCase() > tokenAddressB.toLowerCase()) - [tokenAddressA, tokenAddressB] = [tokenAddressB, tokenAddressA] - - await nft.createAndInitializePoolIfNecessary(tokenAddressA, tokenAddressB, FeeAmount.MEDIUM, encodePriceSqrt(1, 1)) - - const liquidityParams = { - token0: tokenAddressA, - token1: tokenAddressB, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - recipient: wallet.address, - amount0Desired: 1000000, - amount1Desired: 1000000, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - } - - return nft.mint(liquidityParams) -} - -export async function createPoolWithMultiplePositions( - nft: MockTimeNonfungiblePositionManager, - wallet: Wallet, - tokenAddressA: string, - tokenAddressB: string -) { - if (tokenAddressA.toLowerCase() > tokenAddressB.toLowerCase()) - [tokenAddressA, tokenAddressB] = [tokenAddressB, tokenAddressA] - - await nft.createAndInitializePoolIfNecessary(tokenAddressA, tokenAddressB, FeeAmount.MEDIUM, encodePriceSqrt(1, 1)) - - const liquidityParams = { - token0: tokenAddressA, - token1: tokenAddressB, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - recipient: wallet.address, - amount0Desired: 1000000, - amount1Desired: 1000000, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - } - - await nft.mint(liquidityParams) - - const liquidityParams2 = { - token0: tokenAddressA, - token1: tokenAddressB, - fee: FeeAmount.MEDIUM, - tickLower: -60, - tickUpper: 60, - recipient: wallet.address, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - } - - await nft.mint(liquidityParams2) - - const liquidityParams3 = { - token0: tokenAddressA, - token1: tokenAddressB, - fee: FeeAmount.MEDIUM, - tickLower: -120, - tickUpper: 120, - recipient: wallet.address, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - } - - return nft.mint(liquidityParams3) -} - -export async function createPoolWithZeroTickInitialized( - nft: MockTimeNonfungiblePositionManager, - wallet: Wallet, - tokenAddressA: string, - tokenAddressB: string -) { - if (tokenAddressA.toLowerCase() > tokenAddressB.toLowerCase()) - [tokenAddressA, tokenAddressB] = [tokenAddressB, tokenAddressA] - - await nft.createAndInitializePoolIfNecessary(tokenAddressA, tokenAddressB, FeeAmount.MEDIUM, encodePriceSqrt(1, 1)) - - const liquidityParams = { - token0: tokenAddressA, - token1: tokenAddressB, - fee: FeeAmount.MEDIUM, - tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]), - recipient: wallet.address, - amount0Desired: 1000000, - amount1Desired: 1000000, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - } - - await nft.mint(liquidityParams) - - const liquidityParams2 = { - token0: tokenAddressA, - token1: tokenAddressB, - fee: FeeAmount.MEDIUM, - tickLower: 0, - tickUpper: 60, - recipient: wallet.address, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - } - - await nft.mint(liquidityParams2) - - const liquidityParams3 = { - token0: tokenAddressA, - token1: tokenAddressB, - fee: FeeAmount.MEDIUM, - tickLower: -120, - tickUpper: 0, - recipient: wallet.address, - amount0Desired: 100, - amount1Desired: 100, - amount0Min: 0, - amount1Min: 0, - deadline: 1, - } - - return nft.mint(liquidityParams3) -} diff --git a/lib/v3-periphery/test/shared/snapshotGasCost.ts b/lib/v3-periphery/test/shared/snapshotGasCost.ts deleted file mode 100644 index 5a606d2..0000000 --- a/lib/v3-periphery/test/shared/snapshotGasCost.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { TransactionReceipt, TransactionResponse } from '@ethersproject/abstract-provider' -import { expect } from './expect' -import { Contract, BigNumber, ContractTransaction } from 'ethers' - -export default async function snapshotGasCost( - x: - | TransactionResponse - | Promise - | ContractTransaction - | Promise - | TransactionReceipt - | Promise - | BigNumber - | Contract - | Promise -): Promise { - const resolved = await x - if ('deployTransaction' in resolved) { - const receipt = await resolved.deployTransaction.wait() - expect(receipt.gasUsed.toNumber()).toMatchSnapshot() - } else if ('wait' in resolved) { - const waited = await resolved.wait() - expect(waited.gasUsed.toNumber()).toMatchSnapshot() - } else if (BigNumber.isBigNumber(resolved)) { - expect(resolved.toNumber()).toMatchSnapshot() - } -} diff --git a/lib/v3-periphery/test/shared/ticks.ts b/lib/v3-periphery/test/shared/ticks.ts deleted file mode 100644 index 40aa294..0000000 --- a/lib/v3-periphery/test/shared/ticks.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { BigNumber } from 'ethers' - -export const getMinTick = (tickSpacing: number) => Math.ceil(-887272 / tickSpacing) * tickSpacing -export const getMaxTick = (tickSpacing: number) => Math.floor(887272 / tickSpacing) * tickSpacing -export const getMaxLiquidityPerTick = (tickSpacing: number) => - BigNumber.from(2) - .pow(128) - .sub(1) - .div((getMaxTick(tickSpacing) - getMinTick(tickSpacing)) / tickSpacing + 1) diff --git a/lib/v3-periphery/test/shared/tokenSort.ts b/lib/v3-periphery/test/shared/tokenSort.ts deleted file mode 100644 index bdab508..0000000 --- a/lib/v3-periphery/test/shared/tokenSort.ts +++ /dev/null @@ -1,10 +0,0 @@ -export function compareToken(a: { address: string }, b: { address: string }): -1 | 1 { - return a.address.toLowerCase() < b.address.toLowerCase() ? -1 : 1 -} - -export function sortedTokens( - a: { address: string }, - b: { address: string } -): [typeof a, typeof b] | [typeof b, typeof a] { - return compareToken(a, b) < 0 ? [a, b] : [b, a] -} diff --git a/lib/v3-periphery/testnet-deploys.md b/lib/v3-periphery/testnet-deploys.md deleted file mode 100644 index dfaa185..0000000 --- a/lib/v3-periphery/testnet-deploys.md +++ /dev/null @@ -1,3 +0,0 @@ -## Uniswap V3 is live on Mainnet - -See the addresses [here](./deploys.md). diff --git a/lib/v3-periphery/tsconfig.json b/lib/v3-periphery/tsconfig.json deleted file mode 100644 index 69ab585..0000000 --- a/lib/v3-periphery/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - "target": "es2018", - "module": "commonjs", - "strict": true, - "esModuleInterop": true, - "resolveJsonModule": true, - "outDir": "dist", - "typeRoots": ["./typechain", "./node_modules/@types"], - "types": ["@nomiclabs/hardhat-ethers", "@nomiclabs/hardhat-waffle"] - }, - "include": ["./test"], - "files": ["./hardhat.config.ts"] -} diff --git a/lib/v3-periphery/yarn.lock b/lib/v3-periphery/yarn.lock deleted file mode 100644 index 568fc21..0000000 --- a/lib/v3-periphery/yarn.lock +++ /dev/null @@ -1,8111 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/code-frame@^7.0.0": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" - dependencies: - "@babel/highlight" "^7.10.4" - -"@babel/helper-validator-identifier@^7.10.4", "@babel/helper-validator-identifier@^7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" - -"@babel/highlight@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" - dependencies: - "@babel/helper-validator-identifier" "^7.10.4" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/types@^7.0.0", "@babel/types@^7.3.0": - version "7.12.12" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.12.tgz#4608a6ec313abbd87afa55004d373ad04a96c299" - dependencies: - "@babel/helper-validator-identifier" "^7.12.11" - lodash "^4.17.19" - to-fast-properties "^2.0.0" - -"@cnakazawa/watch@^1.0.3": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" - dependencies: - exec-sh "^0.3.2" - minimist "^1.2.0" - -"@ensdomains/ens@^0.4.4": - version "0.4.5" - resolved "https://registry.yarnpkg.com/@ensdomains/ens/-/ens-0.4.5.tgz#e0aebc005afdc066447c6e22feb4eda89a5edbfc" - dependencies: - bluebird "^3.5.2" - eth-ens-namehash "^2.0.8" - solc "^0.4.20" - testrpc "0.0.1" - web3-utils "^1.0.0-beta.31" - -"@ensdomains/resolver@^0.2.4": - version "0.2.4" - resolved "https://registry.yarnpkg.com/@ensdomains/resolver/-/resolver-0.2.4.tgz#c10fe28bf5efbf49bff4666d909aed0265efbc89" - -"@ethereum-waffle/chai@^3.2.1": - version "3.2.1" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/chai/-/chai-3.2.1.tgz#5cb542b2a323adf0bc2dda00f48b0eb85944d8ab" - dependencies: - "@ethereum-waffle/provider" "^3.2.1" - ethers "^5.0.0" - -"@ethereum-waffle/compiler@^3.2.1": - version "3.2.1" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/compiler/-/compiler-3.2.1.tgz#612a9056285a94ce28eb57b895770ad10e438bf9" - dependencies: - "@resolver-engine/imports" "^0.3.3" - "@resolver-engine/imports-fs" "^0.3.3" - "@types/mkdirp" "^0.5.2" - "@types/node-fetch" "^2.5.5" - ethers "^5.0.1" - mkdirp "^0.5.1" - node-fetch "^2.6.0" - solc "^0.6.3" - -"@ethereum-waffle/ens@^3.2.1": - version "3.2.1" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/ens/-/ens-3.2.1.tgz#9f369112d62f7aa88d010be4d133b6d0f5e8c492" - dependencies: - "@ensdomains/ens" "^0.4.4" - "@ensdomains/resolver" "^0.2.4" - ethers "^5.0.1" - -"@ethereum-waffle/mock-contract@^3.2.1": - version "3.2.1" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/mock-contract/-/mock-contract-3.2.1.tgz#bf5f63f61c9749eb3270108893a88ff161e68f58" - dependencies: - "@ethersproject/abi" "^5.0.1" - ethers "^5.0.1" - -"@ethereum-waffle/provider@^3.2.1": - version "3.2.1" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/provider/-/provider-3.2.1.tgz#d84c0603936f09afa69ecb671d56f527e9818e71" - dependencies: - "@ethereum-waffle/ens" "^3.2.1" - ethers "^5.0.1" - ganache-core "^2.10.2" - patch-package "^6.2.2" - postinstall-postinstall "^2.1.0" - -"@ethereumjs/block@^3.4.0", "@ethereumjs/block@^3.5.0", "@ethereumjs/block@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@ethereumjs/block/-/block-3.6.0.tgz#5cf89ea748607597a3f8b038abc986e4ac0b05db" - 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" - -"@ethereumjs/blockchain@^5.4.0", "@ethereumjs/blockchain@^5.5.0": - version "5.5.1" - resolved "https://registry.yarnpkg.com/@ethereumjs/blockchain/-/blockchain-5.5.1.tgz#60f1f50592c06cc47e1704800b88b7d32f609742" - 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" - -"@ethereumjs/common@^2.4.0", "@ethereumjs/common@^2.6.0": - version "2.6.0" - resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.6.0.tgz#feb96fb154da41ee2cc2c5df667621a440f36348" - integrity sha512-Cq2qS0FTu6O2VU1sgg+WyU9Ps0M6j/BEMHN+hRaECXCV/r0aI78u4N6p52QW/BDVhwWZpCdrvG8X7NJdzlpNUA== - dependencies: - crc-32 "^1.2.0" - ethereumjs-util "^7.1.3" - -"@ethereumjs/ethash@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@ethereumjs/ethash/-/ethash-1.1.0.tgz#7c5918ffcaa9cb9c1dc7d12f77ef038c11fb83fb" - 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" - -"@ethereumjs/tx@^3.3.0", "@ethereumjs/tx@^3.4.0": - version "3.4.0" - resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.4.0.tgz#7eb1947eefa55eb9cf05b3ca116fb7a3dbd0bce7" - integrity sha512-WWUwg1PdjHKZZxPPo274ZuPsJCWV3SqATrEKQP1n2DrVYVP1aZIYpo/mFaA0BDoE0tIQmBeimRCEA0Lgil+yYw== - dependencies: - "@ethereumjs/common" "^2.6.0" - ethereumjs-util "^7.1.3" - -"@ethereumjs/vm@^5.5.2": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethereumjs/vm/-/vm-5.6.0.tgz#e0ca62af07de820143674c30b776b86c1983a464" - 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" - -"@ethersproject/abi@5.0.0-beta.153": - version "5.0.0-beta.153" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.0.0-beta.153.tgz#43a37172b33794e4562999f6e2d555b7599a8eee" - dependencies: - "@ethersproject/address" ">=5.0.0-beta.128" - "@ethersproject/bignumber" ">=5.0.0-beta.130" - "@ethersproject/bytes" ">=5.0.0-beta.129" - "@ethersproject/constants" ">=5.0.0-beta.128" - "@ethersproject/hash" ">=5.0.0-beta.128" - "@ethersproject/keccak256" ">=5.0.0-beta.127" - "@ethersproject/logger" ">=5.0.0-beta.129" - "@ethersproject/properties" ">=5.0.0-beta.131" - "@ethersproject/strings" ">=5.0.0-beta.130" - -"@ethersproject/abi@5.0.9", "@ethersproject/abi@^5.0.1", "@ethersproject/abi@^5.0.5": - version "5.0.9" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.0.9.tgz#738c1c557e56d8f395a5a27caef9b0449bc85a10" - 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" - -"@ethersproject/abi@^5.1.2": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.5.0.tgz#fb52820e22e50b854ff15ce1647cc508d6660613" - integrity sha512-loW7I4AohP5KycATvc0MgujU6JyCHPqHdeoo9z3Nr9xEiNioxa65ccdm1+fsoJhkuhdRtfcL8cfyGamz2AxZ5w== - 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" - -"@ethersproject/abstract-provider@5.0.7", "@ethersproject/abstract-provider@^5.0.4": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.0.7.tgz#04ee3bfe43323384e7fecf6c774975b8dec4bdc9" - dependencies: - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/networks" "^5.0.3" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/transactions" "^5.0.5" - "@ethersproject/web" "^5.0.6" - -"@ethersproject/abstract-provider@^5.5.0": - version "5.5.1" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.5.1.tgz#2f1f6e8a3ab7d378d8ad0b5718460f85649710c5" - integrity sha512-m+MA/ful6eKbxpr99xUYeRvLkfnlqzrF8SZ46d/xFB1A7ZVknYc/sXJG0RcufF52Qn2jeFj1hhcoQ7IXjNKUqg== - 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" - -"@ethersproject/abstract-signer@5.0.9", "@ethersproject/abstract-signer@^5.0.4", "@ethersproject/abstract-signer@^5.0.6": - version "5.0.9" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.0.9.tgz#238ddc06031aeb9dfceee2add965292d7dd1acbf" - dependencies: - "@ethersproject/abstract-provider" "^5.0.4" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - -"@ethersproject/abstract-signer@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.5.0.tgz#590ff6693370c60ae376bf1c7ada59eb2a8dd08d" - integrity sha512-lj//7r250MXVLKI7sVarXAbZXbv9P50lgmJQGr2/is82EwEb8r7HrxsmMqAjTsztMYy7ohrIhGMIml+Gx4D3mA== - 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" - -"@ethersproject/address@5.0.8", "@ethersproject/address@>=5.0.0-beta.128", "@ethersproject/address@^5.0.4", "@ethersproject/address@^5.0.5": - version "5.0.8" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.8.tgz#0c551659144a5a7643c6bea337149d410825298f" - dependencies: - "@ethersproject/bignumber" "^5.0.10" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/rlp" "^5.0.3" - -"@ethersproject/address@^5.0.2": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.1.0.tgz#3854fd7ebcb6af7597de66f847c3345dae735b58" - integrity sha512-rfWQR12eHn2cpstCFS4RF7oGjfbkZb0oqep+BfrT+gWEGWG2IowJvIsacPOvzyS1jhNF4MQ4BS59B04Mbovteg== - dependencies: - "@ethersproject/bignumber" "^5.1.0" - "@ethersproject/bytes" "^5.1.0" - "@ethersproject/keccak256" "^5.1.0" - "@ethersproject/logger" "^5.1.0" - "@ethersproject/rlp" "^5.1.0" - -"@ethersproject/address@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.5.0.tgz#bcc6f576a553f21f3dd7ba17248f81b473c9c78f" - integrity sha512-l4Nj0eWlTUh6ro5IbPTgbpT4wRbdH5l8CQf7icF7sb/SI3Nhd9Y9HzhonTSTi6CefI0necIw7LJqQPopPLZyWw== - 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" - -"@ethersproject/base64@5.0.6", "@ethersproject/base64@^5.0.3": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.0.6.tgz#26311ebf29ea3d0b9c300ccf3e1fdc44b7481516" - dependencies: - "@ethersproject/bytes" "^5.0.4" - -"@ethersproject/base64@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.5.0.tgz#881e8544e47ed976930836986e5eb8fab259c090" - integrity sha512-tdayUKhU1ljrlHzEWbStXazDpsx4eg1dBXUSI6+mHlYklOXoXF6lZvw8tnD6oVaWfnMxAgRSKROg3cVKtCcppA== - dependencies: - "@ethersproject/bytes" "^5.5.0" - -"@ethersproject/basex@5.0.6", "@ethersproject/basex@^5.0.3": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.0.6.tgz#ab95c32e48288a3d868726463506641cb1e9fb6b" - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/properties" "^5.0.3" - -"@ethersproject/bignumber@5.0.12", "@ethersproject/bignumber@>=5.0.0-beta.130", "@ethersproject/bignumber@^5.0.10", "@ethersproject/bignumber@^5.0.7", "@ethersproject/bignumber@^5.0.8": - version "5.0.12" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.0.12.tgz#fe4a78667d7cb01790f75131147e82d6ea7e7cba" - dependencies: - "@ethersproject/bytes" "^5.0.8" - "@ethersproject/logger" "^5.0.5" - bn.js "^4.4.0" - -"@ethersproject/bignumber@^5.1.0": - version "5.1.1" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.1.1.tgz#84812695253ccbc639117f7ac49ee1529b68e637" - integrity sha512-AVz5iqz7+70RIqoQTznsdJ6DOVBYciNlvO+AlQmPTB6ofCvoihI9bQdr6wljsX+d5W7Yc4nyvQvP4JMzg0Agig== - dependencies: - "@ethersproject/bytes" "^5.1.0" - "@ethersproject/logger" "^5.1.0" - bn.js "^4.4.0" - -"@ethersproject/bignumber@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.5.0.tgz#875b143f04a216f4f8b96245bde942d42d279527" - integrity sha512-6Xytlwvy6Rn3U3gKEc1vP7nR92frHkv6wtVr95LFR3jREXiCPzdWxKQ1cx4JGQBXxcguAwjA8murlYN2TSiEbg== - dependencies: - "@ethersproject/bytes" "^5.5.0" - "@ethersproject/logger" "^5.5.0" - bn.js "^4.11.9" - -"@ethersproject/bytes@5.0.8", "@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.0.4", "@ethersproject/bytes@^5.0.8": - version "5.0.8" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.0.8.tgz#cf1246a6a386086e590063a4602b1ffb6cc43db1" - dependencies: - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/bytes@^5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.1.0.tgz#55dfa9c4c21df1b1b538be3accb50fb76d5facfd" - integrity sha512-sGTxb+LVjFxJcJeUswAIK6ncgOrh3D8c192iEJd7mLr95V6du119rRfYT/b87WPkZ5I3gRBUYIYXtdgCWACe8g== - dependencies: - "@ethersproject/logger" "^5.1.0" - -"@ethersproject/bytes@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.5.0.tgz#cb11c526de657e7b45d2e0f0246fb3b9d29a601c" - integrity sha512-ABvc7BHWhZU9PNM/tANm/Qx4ostPGadAuQzWTr3doklZOhDlmcBqclrQe/ZXUIj3K8wC28oYeuRa+A37tX9kog== - dependencies: - "@ethersproject/logger" "^5.5.0" - -"@ethersproject/constants@5.0.7", "@ethersproject/constants@>=5.0.0-beta.128", "@ethersproject/constants@^5.0.4": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.0.7.tgz#44ff979e5781b17c8c6901266896c3ee745f4e7e" - dependencies: - "@ethersproject/bignumber" "^5.0.7" - -"@ethersproject/constants@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.5.0.tgz#d2a2cd7d94bd1d58377d1d66c4f53c9be4d0a45e" - integrity sha512-2MsRRVChkvMWR+GyMGY4N1sAX9Mt3J9KykCsgUFd/1mwS0UH1qw+Bv9k1UJb3X3YJYFco9H20pjSlOIfCG5HYQ== - dependencies: - "@ethersproject/bignumber" "^5.5.0" - -"@ethersproject/contracts@5.0.8": - version "5.0.8" - resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.0.8.tgz#71d3ba16853a1555be2e161a6741df186f81c73b" - dependencies: - "@ethersproject/abi" "^5.0.5" - "@ethersproject/abstract-provider" "^5.0.4" - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/address" "^5.0.4" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - -"@ethersproject/hash@5.0.9", "@ethersproject/hash@>=5.0.0-beta.128", "@ethersproject/hash@^5.0.4": - version "5.0.9" - resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.0.9.tgz#81252a848185b584aa600db4a1a68cad9229a4d4" - dependencies: - "@ethersproject/abstract-signer" "^5.0.6" - "@ethersproject/address" "^5.0.5" - "@ethersproject/bignumber" "^5.0.8" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.4" - "@ethersproject/strings" "^5.0.4" - -"@ethersproject/hash@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.5.0.tgz#7cee76d08f88d1873574c849e0207dcb32380cc9" - integrity sha512-dnGVpK1WtBjmnp3mUT0PlU2MpapnwWI0PibldQEq1408tQBAbZpPidkWoVVuNMOl/lISO3+4hXZWCL3YV7qzfg== - 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" - -"@ethersproject/hdnode@5.0.7", "@ethersproject/hdnode@^5.0.4": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.0.7.tgz#c7bce94a337ea65e37c46bab09a83e1c1a555d99" - dependencies: - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/basex" "^5.0.3" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/pbkdf2" "^5.0.3" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/sha2" "^5.0.3" - "@ethersproject/signing-key" "^5.0.4" - "@ethersproject/strings" "^5.0.4" - "@ethersproject/transactions" "^5.0.5" - "@ethersproject/wordlists" "^5.0.4" - -"@ethersproject/json-wallets@5.0.9", "@ethersproject/json-wallets@^5.0.6": - version "5.0.9" - resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.0.9.tgz#2e1708c2854c4ab764e35920bd1f44c948b95434" - dependencies: - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/address" "^5.0.4" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/hdnode" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/pbkdf2" "^5.0.3" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/random" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - "@ethersproject/transactions" "^5.0.5" - aes-js "3.0.0" - scrypt-js "3.0.1" - -"@ethersproject/keccak256@5.0.6", "@ethersproject/keccak256@>=5.0.0-beta.127", "@ethersproject/keccak256@^5.0.3": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.6.tgz#5b5ba715ef1be86efde5c271f896fa0daf0e1efe" - dependencies: - "@ethersproject/bytes" "^5.0.4" - js-sha3 "0.5.7" - -"@ethersproject/keccak256@^5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.1.0.tgz#fdcd88fb13bfef4271b225cdd8dec4d315c8e60e" - integrity sha512-vrTB1W6AEYoadww5c9UyVJ2YcSiyIUTNDRccZIgwTmFFoSHwBtcvG1hqy9RzJ1T0bMdATbM9Hfx2mJ6H0i7Hig== - dependencies: - "@ethersproject/bytes" "^5.1.0" - js-sha3 "0.5.7" - -"@ethersproject/keccak256@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.5.0.tgz#e4b1f9d7701da87c564ffe336f86dcee82983492" - integrity sha512-5VoFCTjo2rYbBe1l2f4mccaRFN/4VQEYFwwn04aJV2h7qf4ZvI2wFxUE1XOX+snbwCLRzIeikOqtAoPwMza9kg== - dependencies: - "@ethersproject/bytes" "^5.5.0" - js-sha3 "0.8.0" - -"@ethersproject/logger@5.0.8", "@ethersproject/logger@>=5.0.0-beta.129", "@ethersproject/logger@^5.0.5": - version "5.0.8" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.8.tgz#135c1903d35c878265f3cbf2b287042c4c20d5d4" - -"@ethersproject/logger@^5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.1.0.tgz#4cdeeefac029373349d5818f39c31b82cc6d9bbf" - integrity sha512-wtUaD1lBX10HBXjjKV9VHCBnTdUaKQnQ2XSET1ezglqLdPdllNOIlLfhyCRqXm5xwcjExVI5ETokOYfjPtaAlw== - -"@ethersproject/logger@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.5.0.tgz#0c2caebeff98e10aefa5aef27d7441c7fd18cf5d" - integrity sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg== - -"@ethersproject/networks@5.0.6", "@ethersproject/networks@^5.0.3": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.0.6.tgz#4d6586bbebfde1c027504ebf6dfb783b29c3803a" - dependencies: - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/networks@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.5.0.tgz#babec47cab892c51f8dd652ce7f2e3e14283981a" - integrity sha512-KWfP3xOnJeF89Uf/FCJdV1a2aDJe5XTN2N52p4fcQ34QhDqQFkgQKZ39VGtiqUgHcLI8DfT0l9azC3KFTunqtA== - dependencies: - "@ethersproject/logger" "^5.5.0" - -"@ethersproject/pbkdf2@5.0.6", "@ethersproject/pbkdf2@^5.0.3": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.0.6.tgz#105dbfb08cd5fcf33869b42bfdc35a3ebd978cbd" - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/sha2" "^5.0.3" - -"@ethersproject/properties@5.0.6", "@ethersproject/properties@>=5.0.0-beta.131", "@ethersproject/properties@^5.0.3", "@ethersproject/properties@^5.0.4": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.6.tgz#44d82aaa294816fd63333e7def42426cf0e87b3b" - dependencies: - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/properties@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.5.0.tgz#61f00f2bb83376d2071baab02245f92070c59995" - integrity sha512-l3zRQg3JkD8EL3CPjNK5g7kMx4qSwiR60/uk5IVjd3oq1MZR5qUg40CNOoEJoX5wc3DyY5bt9EbMk86C7x0DNA== - dependencies: - "@ethersproject/logger" "^5.5.0" - -"@ethersproject/providers@5.0.17": - version "5.0.17" - resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.0.17.tgz#f380e7831149e24e7a1c6c9b5fb1d6dfc729d024" - dependencies: - "@ethersproject/abstract-provider" "^5.0.4" - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/address" "^5.0.4" - "@ethersproject/basex" "^5.0.3" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/hash" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/networks" "^5.0.3" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/random" "^5.0.3" - "@ethersproject/rlp" "^5.0.3" - "@ethersproject/sha2" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - "@ethersproject/transactions" "^5.0.5" - "@ethersproject/web" "^5.0.6" - bech32 "1.1.4" - ws "7.2.3" - -"@ethersproject/random@5.0.6", "@ethersproject/random@^5.0.3": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.0.6.tgz#9be80a1065f2b8e6f321dccb3ebeb4886cac9ea4" - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/rlp@5.0.6", "@ethersproject/rlp@^5.0.3": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.6.tgz#29f9097348a3c330811997433b7df89ab51cd644" - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/rlp@^5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.1.0.tgz#700f4f071c27fa298d3c1d637485fefe919dd084" - integrity sha512-vDTyHIwNPrecy55gKGZ47eJZhBm8LLBxihzi5ou+zrSvYTpkSTWRcKUlXFDFQVwfWB+P5PGyERAdiDEI76clxw== - dependencies: - "@ethersproject/bytes" "^5.1.0" - "@ethersproject/logger" "^5.1.0" - -"@ethersproject/rlp@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.5.0.tgz#530f4f608f9ca9d4f89c24ab95db58ab56ab99a0" - integrity sha512-hLv8XaQ8PTI9g2RHoQGf/WSxBfTB/NudRacbzdxmst5VHAqd1sMibWG7SENzT5Dj3yZ3kJYx+WiRYEcQTAkcYA== - dependencies: - "@ethersproject/bytes" "^5.5.0" - "@ethersproject/logger" "^5.5.0" - -"@ethersproject/sha2@5.0.6", "@ethersproject/sha2@^5.0.3": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.0.6.tgz#175116dc10b866a0a381f6316d094bcc510bee3c" - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - hash.js "1.1.3" - -"@ethersproject/signing-key@5.0.7", "@ethersproject/signing-key@^5.0.4": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.0.7.tgz#d03bfc5f565efb962bafebf8e6965e70d1c46d31" - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - elliptic "6.5.3" - -"@ethersproject/signing-key@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.5.0.tgz#2aa37169ce7e01e3e80f2c14325f624c29cedbe0" - integrity sha512-5VmseH7qjtNmDdZBswavhotYbWB0bOwKIlOTSlX14rKn5c11QmJwGt4GHeo7NrL/Ycl7uo9AHvEqs5xZgFBTng== - 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" - -"@ethersproject/solidity@5.0.7": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.0.7.tgz#72a3455f47a454db2dcf363992d42e9045dc7fce" - dependencies: - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/sha2" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - -"@ethersproject/strings@5.0.7", "@ethersproject/strings@>=5.0.0-beta.130", "@ethersproject/strings@^5.0.4": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.7.tgz#8dc68f794c9e2901f3b75e53b2afbcb6b6c15037" - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/strings@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.5.0.tgz#e6784d00ec6c57710755699003bc747e98c5d549" - integrity sha512-9fy3TtF5LrX/wTrBaT8FGE6TDJyVjOvXynXJz5MT5azq+E6D92zuKNx7i29sWW2FjVOaWjAsiZ1ZWznuduTIIQ== - dependencies: - "@ethersproject/bytes" "^5.5.0" - "@ethersproject/constants" "^5.5.0" - "@ethersproject/logger" "^5.5.0" - -"@ethersproject/transactions@5.0.8", "@ethersproject/transactions@^5.0.0-beta.135", "@ethersproject/transactions@^5.0.5": - version "5.0.8" - resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.0.8.tgz#3b4d7041e13b957a9c4f131e0aea9dae7b6f5a23" - dependencies: - "@ethersproject/address" "^5.0.4" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/rlp" "^5.0.3" - "@ethersproject/signing-key" "^5.0.4" - -"@ethersproject/transactions@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.5.0.tgz#7e9bf72e97bcdf69db34fe0d59e2f4203c7a2908" - integrity sha512-9RZYSKX26KfzEd/1eqvv8pLauCKzDTub0Ko4LfIgaERvRuwyaNV78mJs7cpIgZaDl6RJui4o49lHwwCM0526zA== - 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" - -"@ethersproject/units@5.0.8": - version "5.0.8" - resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.0.8.tgz#563325b20fe1eceff7b61857711d5e2b3f38fd09" - dependencies: - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/wallet@5.0.9": - version "5.0.9" - resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.0.9.tgz#976c7d950489c40308d676869d24e59ab7b82ad1" - dependencies: - "@ethersproject/abstract-provider" "^5.0.4" - "@ethersproject/abstract-signer" "^5.0.4" - "@ethersproject/address" "^5.0.4" - "@ethersproject/bignumber" "^5.0.7" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/hash" "^5.0.4" - "@ethersproject/hdnode" "^5.0.4" - "@ethersproject/json-wallets" "^5.0.6" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/random" "^5.0.3" - "@ethersproject/signing-key" "^5.0.4" - "@ethersproject/transactions" "^5.0.5" - "@ethersproject/wordlists" "^5.0.4" - -"@ethersproject/web@5.0.11", "@ethersproject/web@^5.0.6": - version "5.0.11" - resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.0.11.tgz#d47da612b958b4439e415782a53c8f8461522d68" - dependencies: - "@ethersproject/base64" "^5.0.3" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - -"@ethersproject/web@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.5.0.tgz#0e5bb21a2b58fb4960a705bfc6522a6acf461e28" - integrity sha512-BEgY0eL5oH4mAo37TNYVrFeHsIXLRxggCRG/ksRIxI2X5uj5IsjGmcNiRN/VirQOlBxcUhCgHhaDLG4m6XAVoA== - 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" - -"@ethersproject/wordlists@5.0.7", "@ethersproject/wordlists@^5.0.4": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.0.7.tgz#4e5ad38cfbef746b196a3290c0d41696eb7ab468" - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/hash" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - "@ethersproject/strings" "^5.0.4" - -"@jest/console@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-26.6.2.tgz#4e04bc464014358b03ab4937805ee36a0aeb98f2" - dependencies: - "@jest/types" "^26.6.2" - "@types/node" "*" - chalk "^4.0.0" - jest-message-util "^26.6.2" - jest-util "^26.6.2" - slash "^3.0.0" - -"@jest/test-result@^26.5.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-26.6.2.tgz#55da58b62df134576cc95476efa5f7949e3f5f18" - dependencies: - "@jest/console" "^26.6.2" - "@jest/types" "^26.6.2" - "@types/istanbul-lib-coverage" "^2.0.0" - collect-v8-coverage "^1.0.0" - -"@jest/types@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^15.0.0" - chalk "^4.0.0" - -"@nomiclabs/hardhat-ethers@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.2.tgz#c472abcba0c5185aaa4ad4070146e95213c68511" - integrity sha512-6quxWe8wwS4X5v3Au8q1jOvXYEPkS1Fh+cME5u6AwNdnI4uERvPlVjlgRWzpnb+Rrt1l/cEqiNRH9GlsBMSDQg== - -"@nomiclabs/hardhat-etherscan@^2.1.8": - version "2.1.8" - resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-2.1.8.tgz#e206275e96962cd15e5ba9148b44388bc922d8c2" - 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" - -"@nomiclabs/hardhat-waffle@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-waffle/-/hardhat-waffle-2.0.1.tgz#5d43654fba780720c5033dea240fe14f70ef4bd2" - integrity sha512-2YR2V5zTiztSH9n8BYWgtv3Q+EL0N5Ltm1PAr5z20uAY4SkkfylJ98CIqt18XFvxTD5x4K2wKBzddjV9ViDAZQ== - dependencies: - "@types/sinon-chai" "^3.2.3" - "@types/web3" "1.0.19" - -"@openzeppelin/contracts@3.4.2-solc-0.7": - version "3.4.2-solc-0.7" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.4.2-solc-0.7.tgz#38f4dbab672631034076ccdf2f3201fab1726635" - integrity sha512-W6QmqgkADuFcTLzHL8vVoNBtkwjvQRpYIAom7KiUNoLKghyx3FgH0GBjt8NRvigV1ZmMOBllvE1By1C+bi8WpA== - -"@resolver-engine/core@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@resolver-engine/core/-/core-0.3.3.tgz#590f77d85d45bc7ecc4e06c654f41345db6ca967" - dependencies: - debug "^3.1.0" - is-url "^1.2.4" - request "^2.85.0" - -"@resolver-engine/fs@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@resolver-engine/fs/-/fs-0.3.3.tgz#fbf83fa0c4f60154a82c817d2fe3f3b0c049a973" - dependencies: - "@resolver-engine/core" "^0.3.3" - debug "^3.1.0" - -"@resolver-engine/imports-fs@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@resolver-engine/imports-fs/-/imports-fs-0.3.3.tgz#4085db4b8d3c03feb7a425fbfcf5325c0d1e6c1b" - dependencies: - "@resolver-engine/fs" "^0.3.3" - "@resolver-engine/imports" "^0.3.3" - debug "^3.1.0" - -"@resolver-engine/imports@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@resolver-engine/imports/-/imports-0.3.3.tgz#badfb513bb3ff3c1ee9fd56073e3144245588bcc" - 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" - -"@sentry/core@5.29.2": - version "5.29.2" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.29.2.tgz#9e05fe197234161d57aabaf52fab336a7c520d81" - dependencies: - "@sentry/hub" "5.29.2" - "@sentry/minimal" "5.29.2" - "@sentry/types" "5.29.2" - "@sentry/utils" "5.29.2" - tslib "^1.9.3" - -"@sentry/hub@5.29.2": - version "5.29.2" - resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.29.2.tgz#208f10fe6674695575ad74182a1151f71d6df00a" - dependencies: - "@sentry/types" "5.29.2" - "@sentry/utils" "5.29.2" - tslib "^1.9.3" - -"@sentry/minimal@5.29.2": - version "5.29.2" - resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.29.2.tgz#420bebac8d03d30980fdb05c72d7b253d8aa541b" - dependencies: - "@sentry/hub" "5.29.2" - "@sentry/types" "5.29.2" - tslib "^1.9.3" - -"@sentry/node@^5.18.1": - version "5.29.2" - resolved "https://registry.yarnpkg.com/@sentry/node/-/node-5.29.2.tgz#f0f0b4b2be63c9ddd702729fab998cead271dff1" - dependencies: - "@sentry/core" "5.29.2" - "@sentry/hub" "5.29.2" - "@sentry/tracing" "5.29.2" - "@sentry/types" "5.29.2" - "@sentry/utils" "5.29.2" - cookie "^0.4.1" - https-proxy-agent "^5.0.0" - lru_map "^0.3.3" - tslib "^1.9.3" - -"@sentry/tracing@5.29.2": - version "5.29.2" - resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.29.2.tgz#6012788547d2ab7893799d82c4941bda145dcd47" - dependencies: - "@sentry/hub" "5.29.2" - "@sentry/minimal" "5.29.2" - "@sentry/types" "5.29.2" - "@sentry/utils" "5.29.2" - tslib "^1.9.3" - -"@sentry/types@5.29.2": - version "5.29.2" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.29.2.tgz#ac87383df1222c2d9b9f8f9ed7a6b86ea41a098a" - -"@sentry/utils@5.29.2": - version "5.29.2" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.29.2.tgz#99a5cdda2ea19d34a41932f138d470adcb3ee673" - dependencies: - "@sentry/types" "5.29.2" - tslib "^1.9.3" - -"@sindresorhus/is@^0.14.0": - version "0.14.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" - -"@solidity-parser/parser@^0.12.1": - version "0.12.1" - resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.12.1.tgz#10ce249890d32ba500e9ce449e60a2b26b11be7a" - integrity sha512-ikxVpwskNxEp2fvYS1BdRImnevHmM97zdPFBa1cVtjtNpoqCm/EmljATTZk0s9G/zsN5ZbPf9OAIAW4gbBJiRA== - -"@solidity-parser/parser@^0.14.0": - version "0.14.0" - resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.14.0.tgz#d51f074efb0acce0e953ec48133561ed710cebc0" - integrity sha512-cX0JJRcmPtNUJpzD2K7FdA7qQsTOk1UZnFx2k7qAg9ZRvuaH5NBe5IEdBMXGlmf2+FmjhqbygJ26H8l2SV7aKQ== - dependencies: - antlr4ts "^0.5.0-alpha.4" - -"@solidity-parser/parser@^0.8.2": - version "0.8.2" - resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.8.2.tgz#a6a5e93ac8dca6884a99a532f133beba59b87b69" - -"@szmarczak/http-timer@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" - dependencies: - defer-to-connect "^1.0.1" - -"@typechain/ethers-v5@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-4.0.0.tgz#2a8be5e108d23f3b8e6354d1618fdc2abcb00b07" - -"@types/abstract-leveldown@*": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@types/abstract-leveldown/-/abstract-leveldown-5.0.1.tgz#3c7750d0186b954c7f2d2f6acc8c3c7ba0c3412e" - integrity sha512-wYxU3kp5zItbxKmeRYCEplS2MW7DzyBnxPGj+GJVHZEUZiK/nn5Ei1sUFgURDh+X051+zsGe28iud3oHjrYWQQ== - -"@types/babel__traverse@^7.0.4": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.11.0.tgz#b9a1efa635201ba9bc850323a8793ee2d36c04a0" - dependencies: - "@babel/types" "^7.3.0" - -"@types/bn.js@*", "@types/bn.js@^4.11.3", "@types/bn.js@^4.11.5": - version "4.11.6" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" - dependencies: - "@types/node" "*" - -"@types/bn.js@^5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.0.tgz#32c5d271503a12653c62cf4d2b45e6eab8cebc68" - integrity sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA== - dependencies: - "@types/node" "*" - -"@types/chai@*", "@types/chai@^4.2.6": - version "4.2.14" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.14.tgz#44d2dd0b5de6185089375d976b4ec5caf6861193" - -"@types/graceful-fs@^4.1.2": - version "4.1.4" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.4.tgz#4ff9f641a7c6d1a3508ff88bc3141b152772e753" - dependencies: - "@types/node" "*" - -"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762" - -"@types/istanbul-lib-report@*": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" - dependencies: - "@types/istanbul-lib-coverage" "*" - -"@types/istanbul-reports@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz#508b13aa344fa4976234e75dddcc34925737d821" - dependencies: - "@types/istanbul-lib-report" "*" - -"@types/levelup@^4.3.0": - version "4.3.1" - resolved "https://registry.yarnpkg.com/@types/levelup/-/levelup-4.3.1.tgz#7a53b9fd510716e11b2065332790fdf5f9b950b9" - integrity sha512-n//PeTpbHLjMLTIgW5B/g06W/6iuTBHuvUka2nFL9APMSVMNe2r4enADfu3CIE9IyV9E+uquf9OEQQqrDeg24A== - dependencies: - "@types/abstract-leveldown" "*" - "@types/node" "*" - -"@types/lru-cache@^5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.0.tgz#57f228f2b80c046b4a1bd5cac031f81f207f4f03" - -"@types/mkdirp@^0.5.2": - version "0.5.2" - resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-0.5.2.tgz#503aacfe5cc2703d5484326b1b27efa67a339c1f" - dependencies: - "@types/node" "*" - -"@types/mocha@^5.2.7": - version "5.2.7" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.7.tgz#315d570ccb56c53452ff8638738df60726d5b6ea" - -"@types/node-fetch@^2.5.5": - version "2.5.7" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.7.tgz#20a2afffa882ab04d44ca786449a276f9f6bbf3c" - dependencies: - "@types/node" "*" - form-data "^3.0.0" - -"@types/node@*": - version "14.14.14" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.14.tgz#f7fd5f3cc8521301119f63910f0fb965c7d761ae" - -"@types/node@^12.12.6": - version "12.19.9" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.9.tgz#990ad687ad8b26ef6dcc34a4f69c33d40c95b679" - -"@types/normalize-package-data@^2.4.0": - version "2.4.0" - resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" - -"@types/pbkdf2@^3.0.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.0.tgz#039a0e9b67da0cdc4ee5dab865caa6b267bb66b1" - dependencies: - "@types/node" "*" - -"@types/prettier@^2.0.0", "@types/prettier@^2.1.1": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.1.5.tgz#b6ab3bba29e16b821d84e09ecfaded462b816b00" - -"@types/resolve@^0.0.8": - version "0.0.8" - resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194" - dependencies: - "@types/node" "*" - -"@types/secp256k1@^4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.1.tgz#fb3aa61a1848ad97d7425ff9dcba784549fca5a4" - dependencies: - "@types/node" "*" - -"@types/sinon-chai@^3.2.3": - version "3.2.5" - resolved "https://registry.yarnpkg.com/@types/sinon-chai/-/sinon-chai-3.2.5.tgz#df21ae57b10757da0b26f512145c065f2ad45c48" - dependencies: - "@types/chai" "*" - "@types/sinon" "*" - -"@types/sinon@*": - version "9.0.10" - resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-9.0.10.tgz#7fb9bcb6794262482859cab66d59132fca18fcf7" - dependencies: - "@types/sinonjs__fake-timers" "*" - -"@types/sinonjs__fake-timers@*": - version "6.0.2" - resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.2.tgz#3a84cf5ec3249439015e14049bd3161419bf9eae" - -"@types/stack-utils@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff" - -"@types/underscore@*": - version "1.10.24" - resolved "https://registry.yarnpkg.com/@types/underscore/-/underscore-1.10.24.tgz#dede004deed3b3f99c4db0bdb9ee21cae25befdd" - -"@types/web3@1.0.19": - version "1.0.19" - resolved "https://registry.yarnpkg.com/@types/web3/-/web3-1.0.19.tgz#46b85d91d398ded9ab7c85a5dd57cb33ac558924" - dependencies: - "@types/bn.js" "*" - "@types/underscore" "*" - -"@types/yargs-parser@*": - version "20.2.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.0.tgz#dd3e6699ba3237f0348cd085e4698780204842f9" - -"@types/yargs@^15.0.0": - version "15.0.12" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.12.tgz#6234ce3e3e3fa32c5db301a170f96a599c960d74" - dependencies: - "@types/yargs-parser" "*" - -"@uniswap/lib@^4.0.1-alpha": - version "4.0.1-alpha" - resolved "https://registry.yarnpkg.com/@uniswap/lib/-/lib-4.0.1-alpha.tgz#2881008e55f075344675b3bca93f020b028fbd02" - -"@uniswap/v2-core@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@uniswap/v2-core/-/v2-core-1.0.1.tgz#af8f508bf183204779938969e2e54043e147d425" - integrity sha512-MtybtkUPSyysqLY2U210NBDeCHX+ltHt3oADGdjqoThZaFRDKwM6k1Nb3F0A3hk5hwuQvytFWhrWHOEq6nVJ8Q== - -"@uniswap/v3-core@^1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@uniswap/v3-core/-/v3-core-1.0.1.tgz#b6d2bdc6ba3c3fbd610bdc502395d86cd35264a0" - integrity sha512-7pVk4hEm00j9tc71Y9+ssYpO6ytkeI0y7WE9P6UcmNzhxPePwyAxImuhVsTqWK9YFvzgtvzJHi64pBl4jUzKMQ== - -"@yarnpkg/lockfile@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" - -abort-controller@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" - dependencies: - event-target-shim "^5.0.0" - -abstract-leveldown@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-3.0.0.tgz#5cb89f958a44f526779d740d1440e743e0c30a57" - dependencies: - xtend "~4.0.0" - -abstract-leveldown@^2.4.1, abstract-leveldown@~2.7.1: - version "2.7.2" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz#87a44d7ebebc341d59665204834c8b7e0932cc93" - dependencies: - xtend "~4.0.0" - -abstract-leveldown@^5.0.0, abstract-leveldown@~5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz#f7128e1f86ccabf7d2893077ce5d06d798e386c6" - dependencies: - xtend "~4.0.0" - -abstract-leveldown@^6.2.1: - version "6.3.0" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz#d25221d1e6612f820c35963ba4bd739928f6026a" - 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" - -abstract-leveldown@~2.6.0: - version "2.6.3" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz#1c5e8c6a5ef965ae8c35dfb3a8770c476b82c4b8" - dependencies: - xtend "~4.0.0" - -abstract-leveldown@~6.2.1: - version "6.2.3" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz#036543d87e3710f2528e47040bc3261b77a9a8eb" - 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" - -accepts@~1.3.7: - version "1.3.7" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" - dependencies: - mime-types "~2.1.24" - negotiator "0.6.2" - -acorn-jsx@^5.0.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" - -acorn@^6.0.7: - version "6.4.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" - -adm-zip@^0.4.16: - version "0.4.16" - resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.16.tgz#cf4c508fdffab02c269cbc7f471a875f05570365" - -aes-js@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" - -aes-js@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.2.tgz#db9aabde85d5caabbfc0d4f2a4446960f627146a" - -agent-base@6: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - dependencies: - debug "4" - -ajv@^6.10.2, ajv@^6.12.3, ajv@^6.6.1, ajv@^6.9.1: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - 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" - -ansi-colors@3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" - -ansi-colors@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - -ansi-escapes@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" - -ansi-escapes@^4.3.0: - version "4.3.1" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61" - dependencies: - type-fest "^0.11.0" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - -ansi-regex@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" - -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - -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" - 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" - dependencies: - color-convert "^2.0.1" - -antlr4@4.7.1: - version "4.7.1" - resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.7.1.tgz#69984014f096e9e775f53dd9744bf994d8959773" - -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@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - dependencies: - micromatch "^3.1.4" - normalize-path "^2.1.1" - -anymatch@^3.0.3, anymatch@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" - 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" - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - dependencies: - sprintf-js "~1.0.2" - -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - -arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - -array-back@^1.0.3, array-back@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-1.0.4.tgz#644ba7f095f7ffcf7c43b5f0dc39d3c1f03c063b" - dependencies: - typical "^2.6.0" - -array-back@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-2.0.0.tgz#6877471d51ecc9c9bfa6136fb6c7d5fe69748022" - dependencies: - typical "^2.6.1" - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - -asn1.js@^5.2.0: - version "5.4.1" - resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" - dependencies: - bn.js "^4.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - safer-buffer "^2.1.0" - -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - 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" - -assertion-error@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - -ast-parents@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/ast-parents/-/ast-parents-0.0.1.tgz#508fd0f05d0c48775d9eccda2e174423261e8dd3" - -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - -async-eventemitter@^0.2.2, async-eventemitter@^0.2.4: - version "0.2.4" - resolved "https://registry.yarnpkg.com/async-eventemitter/-/async-eventemitter-0.2.4.tgz#f5e7c8ca7d3e46aab9ec40a292baf686a0bafaca" - dependencies: - async "^2.4.0" - -async-limiter@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" - -async@2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.2.tgz#18330ea7e6e313887f5d2f2a904bac6fe4dd5381" - dependencies: - lodash "^4.17.11" - -async@^1.4.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" - -async@^2.0.1, async@^2.1.2, async@^2.4.0, async@^2.5.0, async@^2.6.1: - version "2.6.3" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" - dependencies: - lodash "^4.17.14" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - -atob@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - -aws4@^1.8.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" - -babel-code-frame@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" - dependencies: - chalk "^1.1.3" - esutils "^2.0.2" - js-tokens "^3.0.2" - -babel-core@^6.0.14, babel-core@^6.26.0: - version "6.26.3" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" - dependencies: - babel-code-frame "^6.26.0" - babel-generator "^6.26.0" - babel-helpers "^6.24.1" - babel-messages "^6.23.0" - babel-register "^6.26.0" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - convert-source-map "^1.5.1" - debug "^2.6.9" - json5 "^0.5.1" - lodash "^4.17.4" - minimatch "^3.0.4" - path-is-absolute "^1.0.1" - private "^0.1.8" - slash "^1.0.0" - source-map "^0.5.7" - -babel-generator@^6.26.0: - version "6.26.1" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" - dependencies: - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - detect-indent "^4.0.0" - jsesc "^1.3.0" - lodash "^4.17.4" - source-map "^0.5.7" - trim-right "^1.0.1" - -babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" - dependencies: - babel-helper-explode-assignable-expression "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-call-delegate@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" - dependencies: - babel-helper-hoist-variables "^6.24.1" - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-define-map@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-helper-explode-assignable-expression@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" - dependencies: - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-function-name@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" - dependencies: - babel-helper-get-function-arity "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-get-function-arity@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-hoist-variables@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-optimise-call-expression@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-regex@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" - dependencies: - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-helper-remap-async-to-generator@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-replace-supers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" - dependencies: - babel-helper-optimise-call-expression "^6.24.1" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helpers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-messages@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-check-es2015-constants@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-syntax-async-functions@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" - -babel-plugin-syntax-exponentiation-operator@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" - -babel-plugin-syntax-trailing-function-commas@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" - -babel-plugin-transform-async-to-generator@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" - dependencies: - babel-helper-remap-async-to-generator "^6.24.1" - babel-plugin-syntax-async-functions "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-arrow-functions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-block-scoping@^6.23.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" - dependencies: - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-plugin-transform-es2015-classes@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" - dependencies: - babel-helper-define-map "^6.24.1" - babel-helper-function-name "^6.24.1" - babel-helper-optimise-call-expression "^6.24.1" - babel-helper-replace-supers "^6.24.1" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-computed-properties@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-destructuring@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-duplicate-keys@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-for-of@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-function-name@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-literals@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" - dependencies: - babel-plugin-transform-es2015-modules-commonjs "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: - version "6.26.2" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" - dependencies: - babel-plugin-transform-strict-mode "^6.24.1" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-types "^6.26.0" - -babel-plugin-transform-es2015-modules-systemjs@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" - dependencies: - babel-helper-hoist-variables "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-modules-umd@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" - dependencies: - babel-plugin-transform-es2015-modules-amd "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-object-super@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" - dependencies: - babel-helper-replace-supers "^6.24.1" - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-parameters@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" - dependencies: - babel-helper-call-delegate "^6.24.1" - babel-helper-get-function-arity "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-shorthand-properties@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-spread@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-sticky-regex@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" - dependencies: - babel-helper-regex "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-template-literals@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-typeof-symbol@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-unicode-regex@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" - dependencies: - babel-helper-regex "^6.24.1" - babel-runtime "^6.22.0" - regexpu-core "^2.0.0" - -babel-plugin-transform-exponentiation-operator@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" - dependencies: - babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" - babel-plugin-syntax-exponentiation-operator "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-regenerator@^6.22.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" - dependencies: - regenerator-transform "^0.10.0" - -babel-plugin-transform-strict-mode@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-preset-env@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" - dependencies: - babel-plugin-check-es2015-constants "^6.22.0" - babel-plugin-syntax-trailing-function-commas "^6.22.0" - babel-plugin-transform-async-to-generator "^6.22.0" - babel-plugin-transform-es2015-arrow-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoping "^6.23.0" - babel-plugin-transform-es2015-classes "^6.23.0" - babel-plugin-transform-es2015-computed-properties "^6.22.0" - babel-plugin-transform-es2015-destructuring "^6.23.0" - babel-plugin-transform-es2015-duplicate-keys "^6.22.0" - babel-plugin-transform-es2015-for-of "^6.23.0" - babel-plugin-transform-es2015-function-name "^6.22.0" - babel-plugin-transform-es2015-literals "^6.22.0" - babel-plugin-transform-es2015-modules-amd "^6.22.0" - babel-plugin-transform-es2015-modules-commonjs "^6.23.0" - babel-plugin-transform-es2015-modules-systemjs "^6.23.0" - babel-plugin-transform-es2015-modules-umd "^6.23.0" - babel-plugin-transform-es2015-object-super "^6.22.0" - babel-plugin-transform-es2015-parameters "^6.23.0" - babel-plugin-transform-es2015-shorthand-properties "^6.22.0" - babel-plugin-transform-es2015-spread "^6.22.0" - babel-plugin-transform-es2015-sticky-regex "^6.22.0" - babel-plugin-transform-es2015-template-literals "^6.22.0" - babel-plugin-transform-es2015-typeof-symbol "^6.23.0" - babel-plugin-transform-es2015-unicode-regex "^6.22.0" - babel-plugin-transform-exponentiation-operator "^6.22.0" - babel-plugin-transform-regenerator "^6.22.0" - browserslist "^3.2.6" - invariant "^2.2.2" - semver "^5.3.0" - -babel-register@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" - dependencies: - babel-core "^6.26.0" - babel-runtime "^6.26.0" - core-js "^2.5.0" - home-or-tmp "^2.0.0" - lodash "^4.17.4" - mkdirp "^0.5.1" - source-map-support "^0.4.15" - -babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.11.0" - -babel-template@^6.24.1, babel-template@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" - dependencies: - babel-runtime "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - lodash "^4.17.4" - -babel-traverse@^6.24.1, babel-traverse@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" - dependencies: - babel-code-frame "^6.26.0" - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - debug "^2.6.8" - globals "^9.18.0" - invariant "^2.2.2" - lodash "^4.17.4" - -babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" - dependencies: - babel-runtime "^6.26.0" - esutils "^2.0.2" - lodash "^4.17.4" - to-fast-properties "^1.0.3" - -babelify@^7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/babelify/-/babelify-7.3.0.tgz#aa56aede7067fd7bd549666ee16dc285087e88e5" - dependencies: - babel-core "^6.0.14" - object-assign "^4.0.0" - -babylon@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" - -backoff@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/backoff/-/backoff-2.5.0.tgz#f616eda9d3e4b66b8ca7fca79f695722c5f8e26f" - dependencies: - precond "0.2" - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - -base-x@^3.0.2, base-x@^3.0.8: - version "3.0.8" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.8.tgz#1e1106c2537f0162e8b52474a557ebb09000018d" - 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" - -base64-sol@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/base64-sol/-/base64-sol-1.0.1.tgz#91317aa341f0bc763811783c5729f1c2574600f6" - integrity sha512-ld3cCNMeXt4uJXmLZBHFGMvVpK9KsLVEhPpFRXnvSVAqABKbuNZg/+dsq3NuM+wxFLb/UrVkz7m1ciWmkMfTbg== - -base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - 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" - -bignumber.js@^9.0.0, bignumber.js@^9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.1.tgz#8d7ba124c882bfd8e43260c67475518d0689e4e5" - -binary-extensions@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" - -bip39@2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.5.0.tgz#51cbd5179460504a63ea3c000db3f787ca051235" - dependencies: - create-hash "^1.1.0" - pbkdf2 "^3.0.9" - randombytes "^2.0.1" - safe-buffer "^5.0.1" - unorm "^1.3.3" - -blakejs@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.1.0.tgz#69df92ef953aa88ca51a32df6ab1c54a155fc7a5" - -bluebird@^3.5.0, bluebird@^3.5.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - -bn.js@4.11.6: - version "4.11.6" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" - -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.10.0, bn.js@^4.11.0, bn.js@^4.11.1, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.11.9, bn.js@^4.4.0, bn.js@^4.8.0: - version "4.11.9" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" - -bn.js@^5.0.0, bn.js@^5.1.1, bn.js@^5.1.2: - version "5.1.3" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.3.tgz#beca005408f642ebebea80b042b4d18d2ac0ee6b" - -body-parser@1.19.0, body-parser@^1.16.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" - 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" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^2.3.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - -braces@^3.0.1, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - dependencies: - fill-range "^7.0.1" - -brorand@^1.0.1, brorand@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - -browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" - dependencies: - buffer-xor "^1.0.3" - cipher-base "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.3" - inherits "^2.0.1" - safe-buffer "^5.0.1" - -browserify-cipher@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" - dependencies: - browserify-aes "^1.0.4" - browserify-des "^1.0.0" - evp_bytestokey "^1.0.0" - -browserify-des@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" - dependencies: - cipher-base "^1.0.1" - des.js "^1.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" - dependencies: - bn.js "^5.0.0" - randombytes "^2.0.1" - -browserify-sign@^4.0.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3" - dependencies: - bn.js "^5.1.1" - browserify-rsa "^4.0.1" - create-hash "^1.2.0" - create-hmac "^1.1.7" - elliptic "^6.5.3" - inherits "^2.0.4" - parse-asn1 "^5.1.5" - readable-stream "^3.6.0" - safe-buffer "^5.2.0" - -browserslist@^3.2.6: - version "3.2.8" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" - dependencies: - caniuse-lite "^1.0.30000844" - electron-to-chromium "^1.3.47" - -bs58@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" - 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" - dependencies: - bs58 "^4.0.0" - create-hash "^1.1.0" - safe-buffer "^5.1.2" - -bser@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" - dependencies: - node-int64 "^0.4.0" - -buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - -buffer-to-arraybuffer@^0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz#6064a40fa76eb43c723aba9ef8f6e1216d10511a" - -buffer-xor@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - -buffer-xor@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-2.0.2.tgz#34f7c64f04c777a1f8aac5e661273bb9dd320289" - dependencies: - safe-buffer "^5.1.1" - -buffer@^5.0.5, buffer@^5.2.1, buffer@^5.5.0, buffer@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - -bufferutil@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.2.tgz#79f68631910f6b993d870fc77dc0a2894eb96cd5" - dependencies: - node-gyp-build "^4.2.0" - -bytes@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" - -bytewise-core@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/bytewise-core/-/bytewise-core-1.2.3.tgz#3fb410c7e91558eb1ab22a82834577aa6bd61d42" - dependencies: - typewise-core "^1.2" - -bytewise@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/bytewise/-/bytewise-1.1.0.tgz#1d13cbff717ae7158094aa881b35d081b387253e" - dependencies: - bytewise-core "^1.2.2" - typewise "^1.0.3" - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - -cacheable-request@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" - 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" - -cachedown@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/cachedown/-/cachedown-1.0.0.tgz#d43f036e4510696b31246d7db31ebf0f7ac32d15" - dependencies: - abstract-leveldown "^2.4.1" - lru-cache "^3.2.0" - -call-bind@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.0.tgz#24127054bb3f9bdcb4b1fb82418186072f77b8ce" - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.0" - -caller-callsite@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" - dependencies: - callsites "^2.0.0" - -caller-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" - dependencies: - caller-callsite "^2.0.0" - -callsites@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - -camelcase@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" - -camelcase@^5.0.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - -caniuse-lite@^1.0.30000844: - version "1.0.30001170" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001170.tgz#0088bfecc6a14694969e391cc29d7eb6362ca6a7" - -capture-exit@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" - dependencies: - rsvp "^4.8.4" - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - -cbor@^5.0.2: - version "5.2.0" - resolved "https://registry.yarnpkg.com/cbor/-/cbor-5.2.0.tgz#4cca67783ccd6de7b50ab4ed62636712f287a67c" - integrity sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A== - dependencies: - bignumber.js "^9.0.1" - nofilter "^1.0.4" - -chai@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5" - 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.0" - type-detect "^4.0.5" - -chalk@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.0.0, chalk@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - -check-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - -checkpoint-store@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/checkpoint-store/-/checkpoint-store-1.1.0.tgz#04e4cb516b91433893581e6d4601a78e9552ea06" - dependencies: - functional-red-black-tree "^1.0.1" - -chokidar@3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.0.tgz#12c0714668c55800f659e262d4962a97faf554a6" - 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.4.0: - version "3.4.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.3.tgz#c1df38231448e45ca4ac588e6c79573ba6a57d5b" - 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.5.0" - optionalDependencies: - fsevents "~2.1.2" - -chokidar@^3.4.3: - version "3.5.1" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" - integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== - 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.5.0" - optionalDependencies: - fsevents "~2.3.1" - -chownr@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" - -ci-info@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" - -cids@^0.7.1: - version "0.7.5" - resolved "https://registry.yarnpkg.com/cids/-/cids-0.7.5.tgz#60a08138a99bfb69b6be4ceb63bfef7a396b28b2" - dependencies: - buffer "^5.5.0" - class-is "^1.1.0" - multibase "~0.6.0" - multicodec "^1.0.0" - multihashes "~0.4.15" - -cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -class-is@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/class-is/-/class-is-1.1.0.tgz#9d3c0fba0440d211d843cec3dedfa48055005825" - -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - -cli-cursor@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" - dependencies: - restore-cursor "^2.0.0" - -cli-width@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48" - -cliui@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - wrap-ansi "^2.0.0" - -cliui@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" - 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" - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -clone-response@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" - dependencies: - mimic-response "^1.0.0" - -clone@2.1.2, clone@^2.0.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - -collect-v8-coverage@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - 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" - 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" - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - -combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - 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" - -command-line-args@^4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-4.0.7.tgz#f8d1916ecb90e9e121eda6428e41300bfb64cc46" - dependencies: - array-back "^2.0.0" - find-replace "^1.0.3" - typical "^2.6.1" - -commander@2.18.0: - version "2.18.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.18.0.tgz#2bf063ddee7c7891176981a2cc798e5754bc6970" - -commander@3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" - -component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - -concat-stream@^1.5.1: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -content-disposition@0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" - dependencies: - safe-buffer "5.1.2" - -content-hash@^2.5.2: - version "2.5.2" - resolved "https://registry.yarnpkg.com/content-hash/-/content-hash-2.5.2.tgz#bbc2655e7c21f14fd3bfc7b7d4bfe6e454c9e211" - dependencies: - cids "^0.7.1" - multicodec "^0.5.5" - multihashes "^0.4.15" - -content-type@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - -convert-source-map@^1.5.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" - dependencies: - safe-buffer "~5.1.1" - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - -cookie@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" - -cookie@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" - -cookiejar@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c" - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - -core-js-pure@^3.0.1: - version "3.8.1" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.8.1.tgz#23f84048f366fdfcf52d3fd1c68fec349177d119" - -core-js@^2.4.0, core-js@^2.5.0: - version "2.6.12" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" - -core-util-is@1.0.2, core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - -cors@^2.8.1: - version "2.8.5" - resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" - dependencies: - object-assign "^4" - vary "^1" - -cosmiconfig@^5.0.7: - version "5.2.1" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" - dependencies: - import-fresh "^2.0.0" - is-directory "^0.3.1" - js-yaml "^3.13.1" - parse-json "^4.0.0" - -crc-32@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208" - integrity sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA== - dependencies: - exit-on-epipe "~1.0.1" - printj "~1.1.0" - -create-ecdh@^4.0.0: - version "4.0.4" - resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" - dependencies: - bn.js "^4.1.0" - elliptic "^6.5.3" - -create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - -create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" - 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" - -cross-fetch@^2.1.0, cross-fetch@^2.1.1: - version "2.2.3" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.2.3.tgz#e8a0b3c54598136e037f8650f8e823ccdfac198e" - dependencies: - node-fetch "2.1.2" - whatwg-fetch "2.0.4" - -cross-spawn@^6.0.0, cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -crypto-browserify@3.12.0: - version "3.12.0" - resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" - dependencies: - browserify-cipher "^1.0.0" - browserify-sign "^4.0.0" - create-ecdh "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.0" - diffie-hellman "^5.0.0" - inherits "^2.0.1" - pbkdf2 "^3.0.3" - public-encrypt "^4.0.0" - randombytes "^2.0.0" - randomfill "^1.0.3" - -d@1, d@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" - dependencies: - es5-ext "^0.10.50" - type "^1.0.1" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - dependencies: - assert-plus "^1.0.0" - -debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - dependencies: - ms "2.0.0" - -debug@3.2.6: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - dependencies: - ms "^2.1.1" - -debug@4, debug@^4.0.1, debug@^4.1.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" - dependencies: - ms "2.1.2" - -debug@^3.1.0: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - dependencies: - ms "^2.1.1" - -decamelize@^1.1.1, decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - -decimal.js@^10.2.1: - version "10.2.1" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.1.tgz#238ae7b0f0c793d3e3cea410108b35a2c01426a3" - -decode-uri-component@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - -decompress-response@^3.2.0, decompress-response@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" - dependencies: - mimic-response "^1.0.0" - -deep-eql@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" - dependencies: - type-detect "^4.0.0" - -deep-equal@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" - dependencies: - is-arguments "^1.0.4" - is-date-object "^1.0.1" - is-regex "^1.0.4" - object-is "^1.0.1" - object-keys "^1.1.1" - regexp.prototype.flags "^1.2.0" - -deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - -defer-to-connect@^1.0.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" - -deferred-leveldown@~1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz#3acd2e0b75d1669924bc0a4b642851131173e1eb" - dependencies: - abstract-leveldown "~2.6.0" - -deferred-leveldown@~4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-4.0.2.tgz#0b0570087827bf480a23494b398f04c128c19a20" - dependencies: - abstract-leveldown "~5.0.0" - inherits "^2.0.3" - -deferred-leveldown@~5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz#27a997ad95408b61161aa69bd489b86c71b78058" - integrity sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw== - dependencies: - abstract-leveldown "~6.2.1" - inherits "^2.0.3" - -define-properties@^1.1.2, define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - dependencies: - object-keys "^1.0.12" - -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - -defined@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - -des.js@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" - dependencies: - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - -destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - -detect-indent@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" - dependencies: - repeating "^2.0.0" - -diff-sequences@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" - -diff@3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - -diffie-hellman@^5.0.0: - version "5.0.3" - resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" - dependencies: - bn.js "^4.1.0" - miller-rabin "^4.0.0" - randombytes "^2.0.0" - -dir-to-object@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/dir-to-object/-/dir-to-object-2.0.0.tgz#29723e9bd1c3e58e4f307bd04ff634c0370c8f8a" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - dependencies: - esutils "^2.0.2" - -dom-walk@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" - -dotignore@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/dotignore/-/dotignore-0.1.2.tgz#f942f2200d28c3a76fbdd6f0ee9f3257c8a2e905" - dependencies: - minimatch "^3.0.4" - -duplexer3@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - -electron-to-chromium@^1.3.47: - version "1.3.633" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.633.tgz#16dd5aec9de03894e8d14a1db4cda8a369b9b7fe" - -elliptic@6.5.3, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3: - version "6.5.3" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6" - 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" - -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" - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - -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== - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - -encoding-down@5.0.4, encoding-down@~5.0.0: - version "5.0.4" - resolved "https://registry.yarnpkg.com/encoding-down/-/encoding-down-5.0.4.tgz#1e477da8e9e9d0f7c8293d320044f8b2cd8e9614" - dependencies: - abstract-leveldown "^5.0.0" - inherits "^2.0.3" - level-codec "^9.0.0" - level-errors "^2.0.0" - xtend "^4.0.1" - -encoding-down@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/encoding-down/-/encoding-down-6.3.0.tgz#b1c4eb0e1728c146ecaef8e32963c549e76d082b" - integrity sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw== - dependencies: - abstract-leveldown "^6.2.1" - inherits "^2.0.3" - level-codec "^9.0.0" - level-errors "^2.0.0" - -encoding@^0.1.11: - version "0.1.13" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" - dependencies: - iconv-lite "^0.6.2" - -end-of-stream@^1.1.0: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - dependencies: - once "^1.4.0" - -enquirer@^2.3.0: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - dependencies: - ansi-colors "^4.1.1" - -env-paths@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.0.tgz#cdca557dc009152917d6166e2febe1f039685e43" - -errno@~0.1.1: - version "0.1.8" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" - dependencies: - prr "~1.0.1" - -error-ex@^1.2.0, error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.17.0-next.1, es-abstract@^1.17.2: - version "1.17.7" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.7.tgz#a4de61b2f66989fc7421676c1cb9787573ace54c" - 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" - -es-abstract@^1.18.0-next.1: - version "1.18.0-next.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.1.tgz#6e3a0a4bda717e5023ab3b8e90bec36108d22c68" - 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" - -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" - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -es5-ext@^0.10.35, es5-ext@^0.10.50: - version "0.10.53" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" - dependencies: - es6-iterator "~2.0.3" - es6-symbol "~3.1.3" - next-tick "~1.0.0" - -es6-iterator@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" - dependencies: - d "1" - es5-ext "^0.10.35" - es6-symbol "^3.1.1" - -es6-symbol@^3.1.1, es6-symbol@~3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" - dependencies: - d "^1.0.1" - ext "^1.1.2" - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - -escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - -escape-string-regexp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" - -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" - -eslint-scope@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -eslint-utils@^1.3.1: - version "1.4.3" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" - -eslint@^5.6.0: - version "5.16.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea" - 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" - -espree@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a" - dependencies: - acorn "^6.0.7" - acorn-jsx "^5.0.0" - eslint-visitor-keys "^1.0.0" - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - -esquery@^1.0.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.3.1.tgz#b78b5828aa8e214e29fb74c4d5b752e1c033da57" - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - -estraverse@^5.1.0, estraverse@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - -eth-block-tracker@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/eth-block-tracker/-/eth-block-tracker-3.0.1.tgz#95cd5e763c7293e0b1b2790a2a39ac2ac188a5e1" - dependencies: - eth-query "^2.1.0" - ethereumjs-tx "^1.3.3" - ethereumjs-util "^5.1.3" - ethjs-util "^0.1.3" - json-rpc-engine "^3.6.0" - pify "^2.3.0" - tape "^4.6.3" - -eth-ens-namehash@2.0.8, eth-ens-namehash@^2.0.8: - version "2.0.8" - resolved "https://registry.yarnpkg.com/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz#229ac46eca86d52e0c991e7cb2aef83ff0f68bcf" - dependencies: - idna-uts46-hx "^2.3.1" - js-sha3 "^0.5.7" - -eth-json-rpc-infura@^3.1.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/eth-json-rpc-infura/-/eth-json-rpc-infura-3.2.1.tgz#26702a821067862b72d979c016fd611502c6057f" - dependencies: - cross-fetch "^2.1.1" - eth-json-rpc-middleware "^1.5.0" - json-rpc-engine "^3.4.0" - json-rpc-error "^2.0.0" - -eth-json-rpc-middleware@^1.5.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.6.0.tgz#5c9d4c28f745ccb01630f0300ba945f4bef9593f" - dependencies: - async "^2.5.0" - eth-query "^2.1.2" - eth-tx-summary "^3.1.2" - ethereumjs-block "^1.6.0" - ethereumjs-tx "^1.3.3" - ethereumjs-util "^5.1.2" - ethereumjs-vm "^2.1.0" - fetch-ponyfill "^4.0.0" - json-rpc-engine "^3.6.0" - json-rpc-error "^2.0.0" - json-stable-stringify "^1.0.1" - promise-to-callback "^1.0.0" - tape "^4.6.3" - -eth-lib@0.2.8: - version "0.2.8" - resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.2.8.tgz#b194058bef4b220ad12ea497431d6cb6aa0623c8" - dependencies: - bn.js "^4.11.6" - elliptic "^6.4.0" - xhr-request-promise "^0.1.2" - -eth-lib@^0.1.26: - version "0.1.29" - resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.1.29.tgz#0c11f5060d42da9f931eab6199084734f4dbd1d9" - dependencies: - bn.js "^4.11.6" - elliptic "^6.4.0" - nano-json-stream-parser "^0.1.2" - servify "^0.1.12" - ws "^3.0.0" - xhr-request-promise "^0.1.2" - -eth-query@^2.0.2, eth-query@^2.1.0, eth-query@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/eth-query/-/eth-query-2.1.2.tgz#d6741d9000106b51510c72db92d6365456a6da5e" - dependencies: - json-rpc-random-id "^1.0.0" - xtend "^4.0.1" - -eth-sig-util@^1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-1.4.2.tgz#8d958202c7edbaae839707fba6f09ff327606210" - dependencies: - ethereumjs-abi "git+https://github.com/ethereumjs/ethereumjs-abi.git" - ethereumjs-util "^5.1.1" - -eth-sig-util@^2.0.0, eth-sig-util@^2.5.2: - version "2.5.3" - resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-2.5.3.tgz#6938308b38226e0b3085435474900b03036abcbe" - dependencies: - buffer "^5.2.1" - elliptic "^6.4.0" - ethereumjs-abi "0.6.5" - ethereumjs-util "^5.1.1" - tweetnacl "^1.0.0" - tweetnacl-util "^0.15.0" - -eth-tx-summary@^3.1.2: - version "3.2.4" - resolved "https://registry.yarnpkg.com/eth-tx-summary/-/eth-tx-summary-3.2.4.tgz#e10eb95eb57cdfe549bf29f97f1e4f1db679035c" - dependencies: - async "^2.1.2" - clone "^2.0.0" - concat-stream "^1.5.1" - end-of-stream "^1.1.0" - eth-query "^2.0.2" - ethereumjs-block "^1.4.1" - ethereumjs-tx "^1.1.1" - ethereumjs-util "^5.0.1" - ethereumjs-vm "^2.6.0" - through2 "^2.0.3" - -ethashjs@~0.0.7: - version "0.0.8" - resolved "https://registry.yarnpkg.com/ethashjs/-/ethashjs-0.0.8.tgz#227442f1bdee409a548fb04136e24c874f3aa6f9" - dependencies: - async "^2.1.2" - buffer-xor "^2.0.1" - ethereumjs-util "^7.0.2" - miller-rabin "^4.0.0" - -ethereum-bloom-filters@^1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.7.tgz#b7b80735e385dbb7f944ce6b4533e24511306060" - dependencies: - js-sha3 "^0.8.0" - -ethereum-common@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.2.0.tgz#13bf966131cce1eeade62a1b434249bb4cb120ca" - -ethereum-common@^0.0.18: - version "0.0.18" - resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.0.18.tgz#2fdc3576f232903358976eb39da783213ff9523f" - -ethereum-cryptography@^0.1.2, ethereum-cryptography@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz#8d6143cfc3d74bf79bbd8edecdf29e4ae20dd191" - 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-waffle@^3.0.2: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ethereum-waffle/-/ethereum-waffle-3.2.1.tgz#9d6d6b93484c5e1b77dfdeb646c050ed877e836e" - dependencies: - "@ethereum-waffle/chai" "^3.2.1" - "@ethereum-waffle/compiler" "^3.2.1" - "@ethereum-waffle/mock-contract" "^3.2.1" - "@ethereum-waffle/provider" "^3.2.1" - ethers "^5.0.1" - -ethereumjs-abi@0.6.5: - version "0.6.5" - resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.5.tgz#5a637ef16ab43473fa72a29ad90871405b3f5241" - dependencies: - bn.js "^4.10.0" - ethereumjs-util "^4.3.0" - -ethereumjs-abi@0.6.8, ethereumjs-abi@^0.6.8: - version "0.6.8" - resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz#71bc152db099f70e62f108b7cdfca1b362c6fcae" - dependencies: - bn.js "^4.11.8" - ethereumjs-util "^6.0.0" - -"ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git": - version "0.6.8" - resolved "git+https://github.com/ethereumjs/ethereumjs-abi.git#1ce6a1d64235fabe2aaf827fd606def55693508f" - dependencies: - bn.js "^4.11.8" - ethereumjs-util "^6.0.0" - -ethereumjs-account@3.0.0, ethereumjs-account@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ethereumjs-account/-/ethereumjs-account-3.0.0.tgz#728f060c8e0c6e87f1e987f751d3da25422570a9" - dependencies: - ethereumjs-util "^6.0.0" - rlp "^2.2.1" - safe-buffer "^5.1.1" - -ethereumjs-account@^2.0.3: - version "2.0.5" - resolved "https://registry.yarnpkg.com/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz#eeafc62de544cb07b0ee44b10f572c9c49e00a84" - dependencies: - ethereumjs-util "^5.0.0" - rlp "^2.0.0" - safe-buffer "^5.1.1" - -ethereumjs-block@2.2.2, ethereumjs-block@^2.2.2, ethereumjs-block@~2.2.0, ethereumjs-block@~2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz#c7654be7e22df489fda206139ecd63e2e9c04965" - dependencies: - async "^2.0.1" - ethereumjs-common "^1.5.0" - ethereumjs-tx "^2.1.1" - ethereumjs-util "^5.0.0" - merkle-patricia-tree "^2.1.2" - -ethereumjs-block@^1.2.2, ethereumjs-block@^1.4.1, ethereumjs-block@^1.6.0: - version "1.7.1" - resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz#78b88e6cc56de29a6b4884ee75379b6860333c3f" - dependencies: - async "^2.0.1" - ethereum-common "0.2.0" - ethereumjs-tx "^1.2.2" - ethereumjs-util "^5.0.0" - merkle-patricia-tree "^2.1.2" - -ethereumjs-blockchain@^4.0.3: - version "4.0.4" - resolved "https://registry.yarnpkg.com/ethereumjs-blockchain/-/ethereumjs-blockchain-4.0.4.tgz#30f2228dc35f6dcf94423692a6902604ae34960f" - dependencies: - async "^2.6.1" - ethashjs "~0.0.7" - ethereumjs-block "~2.2.2" - ethereumjs-common "^1.5.0" - ethereumjs-util "^6.1.0" - flow-stoplight "^1.0.0" - level-mem "^3.0.1" - lru-cache "^5.1.1" - rlp "^2.2.2" - semaphore "^1.1.0" - -ethereumjs-common@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/ethereumjs-common/-/ethereumjs-common-1.5.0.tgz#d3e82fc7c47c0cef95047f431a99485abc9bb1cd" - -ethereumjs-common@^1.1.0, ethereumjs-common@^1.3.2, ethereumjs-common@^1.5.0: - version "1.5.2" - resolved "https://registry.yarnpkg.com/ethereumjs-common/-/ethereumjs-common-1.5.2.tgz#2065dbe9214e850f2e955a80e650cb6999066979" - -ethereumjs-tx@2.1.2, ethereumjs-tx@^2.1.1, ethereumjs-tx@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz#5dfe7688bf177b45c9a23f86cf9104d47ea35fed" - dependencies: - ethereumjs-common "^1.5.0" - ethereumjs-util "^6.0.0" - -ethereumjs-tx@^1.1.1, ethereumjs-tx@^1.2.0, ethereumjs-tx@^1.2.2, ethereumjs-tx@^1.3.3: - version "1.3.7" - resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz#88323a2d875b10549b8347e09f4862b546f3d89a" - dependencies: - ethereum-common "^0.0.18" - ethereumjs-util "^5.0.0" - -ethereumjs-util@6.2.1, ethereumjs-util@^6.0.0, ethereumjs-util@^6.1.0, ethereumjs-util@^6.2.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz#fcb4e4dd5ceacb9d2305426ab1a5cd93e3163b69" - dependencies: - "@types/bn.js" "^4.11.3" - bn.js "^4.11.0" - create-hash "^1.1.2" - elliptic "^6.5.2" - ethereum-cryptography "^0.1.3" - ethjs-util "0.1.6" - rlp "^2.2.3" - -ethereumjs-util@^4.3.0: - version "4.5.1" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-4.5.1.tgz#f4bf9b3b515a484e3cc8781d61d9d980f7c83bd0" - dependencies: - bn.js "^4.8.0" - create-hash "^1.1.2" - elliptic "^6.5.2" - ethereum-cryptography "^0.1.3" - rlp "^2.0.0" - -ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.2, ethereumjs-util@^5.1.3, ethereumjs-util@^5.1.5, ethereumjs-util@^5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz#a833f0e5fca7e5b361384dc76301a721f537bf65" - dependencies: - bn.js "^4.11.0" - create-hash "^1.1.2" - elliptic "^6.5.2" - ethereum-cryptography "^0.1.3" - ethjs-util "^0.1.3" - rlp "^2.0.0" - safe-buffer "^5.1.1" - -ethereumjs-util@^7.0.2: - version "7.0.7" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.0.7.tgz#484fb9c03b766b2ee64821281070616562fb5a59" - 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" - -ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.1, ethereumjs-util@^7.1.2, ethereumjs-util@^7.1.3: - version "7.1.3" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz#b55d7b64dde3e3e45749e4c41288238edec32d23" - 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" - -ethereumjs-vm@4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-4.2.0.tgz#e885e861424e373dbc556278f7259ff3fca5edab" - dependencies: - async "^2.1.2" - async-eventemitter "^0.2.2" - core-js-pure "^3.0.1" - ethereumjs-account "^3.0.0" - ethereumjs-block "^2.2.2" - ethereumjs-blockchain "^4.0.3" - ethereumjs-common "^1.5.0" - ethereumjs-tx "^2.1.2" - ethereumjs-util "^6.2.0" - fake-merkle-patricia-tree "^1.0.1" - functional-red-black-tree "^1.0.1" - merkle-patricia-tree "^2.3.2" - rustbn.js "~0.2.0" - safe-buffer "^5.1.1" - util.promisify "^1.0.0" - -ethereumjs-vm@^2.1.0, ethereumjs-vm@^2.3.4, ethereumjs-vm@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz#76243ed8de031b408793ac33907fb3407fe400c6" - dependencies: - async "^2.1.2" - async-eventemitter "^0.2.2" - ethereumjs-account "^2.0.3" - ethereumjs-block "~2.2.0" - ethereumjs-common "^1.1.0" - ethereumjs-util "^6.0.0" - fake-merkle-patricia-tree "^1.0.1" - functional-red-black-tree "^1.0.1" - merkle-patricia-tree "^2.3.2" - rustbn.js "~0.2.0" - safe-buffer "^5.1.1" - -ethereumjs-wallet@0.6.5: - version "0.6.5" - resolved "https://registry.yarnpkg.com/ethereumjs-wallet/-/ethereumjs-wallet-0.6.5.tgz#685e9091645cee230ad125c007658833991ed474" - dependencies: - aes-js "^3.1.1" - bs58check "^2.1.2" - ethereum-cryptography "^0.1.3" - ethereumjs-util "^6.0.0" - randombytes "^2.0.6" - safe-buffer "^5.1.2" - scryptsy "^1.2.1" - utf8 "^3.0.0" - uuid "^3.3.2" - -ethers@^5.0.0, ethers@^5.0.1, ethers@^5.0.8: - version "5.0.24" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.0.24.tgz#fbb8e4d35070d134f2eb846c07500b8c0eaef6d3" - dependencies: - "@ethersproject/abi" "5.0.9" - "@ethersproject/abstract-provider" "5.0.7" - "@ethersproject/abstract-signer" "5.0.9" - "@ethersproject/address" "5.0.8" - "@ethersproject/base64" "5.0.6" - "@ethersproject/basex" "5.0.6" - "@ethersproject/bignumber" "5.0.12" - "@ethersproject/bytes" "5.0.8" - "@ethersproject/constants" "5.0.7" - "@ethersproject/contracts" "5.0.8" - "@ethersproject/hash" "5.0.9" - "@ethersproject/hdnode" "5.0.7" - "@ethersproject/json-wallets" "5.0.9" - "@ethersproject/keccak256" "5.0.6" - "@ethersproject/logger" "5.0.8" - "@ethersproject/networks" "5.0.6" - "@ethersproject/pbkdf2" "5.0.6" - "@ethersproject/properties" "5.0.6" - "@ethersproject/providers" "5.0.17" - "@ethersproject/random" "5.0.6" - "@ethersproject/rlp" "5.0.6" - "@ethersproject/sha2" "5.0.6" - "@ethersproject/signing-key" "5.0.7" - "@ethersproject/solidity" "5.0.7" - "@ethersproject/strings" "5.0.7" - "@ethersproject/transactions" "5.0.8" - "@ethersproject/units" "5.0.8" - "@ethersproject/wallet" "5.0.9" - "@ethersproject/web" "5.0.11" - "@ethersproject/wordlists" "5.0.7" - -ethjs-unit@0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" - dependencies: - bn.js "4.11.6" - number-to-bn "1.7.0" - -ethjs-util@0.1.6, ethjs-util@^0.1.3: - version "0.1.6" - resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536" - dependencies: - is-hex-prefixed "1.0.0" - strip-hex-prefix "1.0.0" - -event-target-shim@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" - -eventemitter3@4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" - -events@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379" - -evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" - dependencies: - md5.js "^1.3.4" - safe-buffer "^5.1.1" - -exec-sh@^0.3.2: - version "0.3.4" - resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.4.tgz#3a018ceb526cc6f6df2bb504b2bfe8e3a4934ec5" - -execa@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - 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" - -exit-on-epipe@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692" - integrity sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw== - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - 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" - -expect@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/expect/-/expect-26.6.2.tgz#c6b996bf26bf3fe18b67b2d0f51fc981ba934417" - dependencies: - "@jest/types" "^26.6.2" - ansi-styles "^4.0.0" - jest-get-type "^26.3.0" - jest-matcher-utils "^26.6.2" - jest-message-util "^26.6.2" - jest-regex-util "^26.0.0" - -express@^4.14.0: - version "4.17.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" - 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" - -ext@^1.1.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244" - dependencies: - type "^2.0.0" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - -external-editor@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - -fake-merkle-patricia-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz#4b8c3acfb520afadf9860b1f14cd8ce3402cddd3" - dependencies: - checkpoint-store "^1.1.0" - -fast-deep-equal@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - -fast-diff@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" - -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" - -fast-levenshtein@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - -fast-xml-parser@^3.19.0: - version "3.19.0" - resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-3.19.0.tgz#cb637ec3f3999f51406dd8ff0e6fc4d83e520d01" - integrity sha512-4pXwmBplsCPv8FOY1WRakF970TjNGnGnfbOnLqjlYvMiF1SR3yOHyxMR/YCXpPTOspNF5gwudqktIP4VsWkvBg== - -fb-watchman@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" - dependencies: - bser "2.1.1" - -fetch-ponyfill@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz#ae3ce5f732c645eab87e4ae8793414709b239893" - dependencies: - node-fetch "~1.7.1" - -figures@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" - dependencies: - escape-string-regexp "^1.0.5" - -file-entry-cache@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" - dependencies: - flat-cache "^2.0.1" - -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - dependencies: - to-regex-range "^5.0.1" - -finalhandler@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" - 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" - -find-package-json@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/find-package-json/-/find-package-json-1.2.0.tgz#4057d1b943f82d8445fe52dc9cf456f6b8b58083" - -find-replace@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-1.0.3.tgz#b88e7364d2d9c959559f388c66670d6130441fa0" - dependencies: - array-back "^1.0.4" - test-value "^2.1.0" - -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" - dependencies: - locate-path "^3.0.0" - -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - -find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - 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" - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -find-yarn-workspace-root@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-1.2.1.tgz#40eb8e6e7c2502ddfaa2577c176f221422f860db" - dependencies: - fs-extra "^4.0.3" - micromatch "^3.1.4" - -flat-cache@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" - dependencies: - flatted "^2.0.0" - rimraf "2.6.3" - write "1.0.3" - -flat@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/flat/-/flat-4.1.1.tgz#a392059cc382881ff98642f5da4dde0a959f309b" - dependencies: - is-buffer "~2.0.3" - -flatted@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" - -flow-stoplight@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/flow-stoplight/-/flow-stoplight-1.0.0.tgz#4a292c5bcff8b39fa6cc0cb1a853d86f27eeff7b" - -follow-redirects@^1.12.1: - version "1.13.1" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.1.tgz#5f69b813376cee4fd0474a3aba835df04ab763b7" - -for-each@~0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" - dependencies: - is-callable "^1.1.3" - -for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - -form-data@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682" - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -forwarded@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" - -fp-ts@1.19.3: - version "1.19.3" - resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.3.tgz#261a60d1088fbff01f91256f91d21d0caaaaa96f" - -fp-ts@^1.0.0: - version "1.19.5" - resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.5.tgz#3da865e585dfa1fdfd51785417357ac50afc520a" - -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - dependencies: - map-cache "^0.2.2" - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - -fs-extra@^0.30.0: - version "0.30.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" - dependencies: - graceful-fs "^4.1.2" - jsonfile "^2.1.0" - klaw "^1.0.0" - path-is-absolute "^1.0.0" - rimraf "^2.2.8" - -fs-extra@^4.0.2, fs-extra@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-extra@^7.0.0, fs-extra@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-minipass@^1.2.5: - version "1.2.7" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" - dependencies: - minipass "^2.6.0" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - -fsevents@^2.1.2: - version "2.2.1" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.2.1.tgz#1fb02ded2036a8ac288d507a65962bd87b97628d" - -fsevents@~2.1.1, fsevents@~2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" - -fsevents@~2.3.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -function-bind@^1.1.1, function-bind@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - -functional-red-black-tree@^1.0.1, functional-red-black-tree@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - -ganache-core@^2.10.2: - version "2.13.1" - resolved "https://registry.yarnpkg.com/ganache-core/-/ganache-core-2.13.1.tgz#bf60399a2dd084e1090db91cbbc7ed3885dc01e4" - 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 "^2.0.0" - ethereumjs-abi "0.6.8" - ethereumjs-account "3.0.0" - ethereumjs-block "2.2.2" - ethereumjs-common "1.5.0" - ethereumjs-tx "2.1.2" - ethereumjs-util "6.2.1" - ethereumjs-vm "4.2.0" - heap "0.2.6" - keccak "3.0.1" - level-sublevel "6.6.4" - levelup "3.1.1" - lodash "4.17.20" - lru-cache "5.1.1" - merkle-patricia-tree "3.0.0" - patch-package "6.2.2" - seedrandom "3.0.1" - source-map-support "0.5.12" - tmp "0.1.0" - web3-provider-engine "14.2.1" - websocket "1.0.32" - optionalDependencies: - ethereumjs-wallet "0.6.5" - web3 "1.2.11" - -get-caller-file@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" - -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" - -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" - -get-intrinsic@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.2.tgz#6820da226e50b24894e08859469dc68361545d49" - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - -get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - -get-stream@^4.0.0, get-stream@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - dependencies: - pump "^3.0.0" - -get-stream@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" - dependencies: - pump "^3.0.0" - -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - dependencies: - assert-plus "^1.0.0" - -glob-parent@~5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" - 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" - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.1.2, glob@^7.1.3, glob@~7.1.6: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - 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" - -global@~4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" - dependencies: - min-document "^2.19.0" - process "^0.11.10" - -globals@^11.7.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - -globals@^9.18.0: - version "9.18.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" - -got@9.6.0: - version "9.6.0" - resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" - dependencies: - "@sindresorhus/is" "^0.14.0" - "@szmarczak/http-timer" "^1.1.2" - cacheable-request "^6.0.0" - decompress-response "^3.3.0" - duplexer3 "^0.1.4" - get-stream "^4.1.0" - lowercase-keys "^1.0.1" - mimic-response "^1.0.1" - p-cancelable "^1.0.0" - to-readable-stream "^1.0.0" - url-parse-lax "^3.0.0" - -got@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" - 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" - -graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.4: - version "4.2.4" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" - -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" - -hardhat-typechain@^0.3.5: - version "0.3.5" - resolved "https://registry.yarnpkg.com/hardhat-typechain/-/hardhat-typechain-0.3.5.tgz#8e50616a9da348b33bd001168c8fda9c66b7b4af" - integrity sha512-w9lm8sxqTJACY+V7vijiH+NkPExnmtiQEjsV9JKD1KgMdVk2q8y+RhvU/c4B7+7b1+HylRUCxpOIvFuB3rE4+w== - -hardhat-watcher@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/hardhat-watcher/-/hardhat-watcher-2.1.1.tgz#8b05fec429ed45da11808bbf6054a90f3e34c51a" - integrity sha512-zilmvxAYD34IofBrwOliQn4z92UiDmt2c949DW4Gokf0vS0qk4YTfVCi/LmUBICThGygNANE3WfnRTpjCJGtDA== - dependencies: - chokidar "^3.4.3" - -hardhat@^2.6.8: - version "2.6.8" - resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.6.8.tgz#9ef6f8c16f9044acb95609d15a760b89177b8181" - integrity sha512-iRVd5DgcIVV3rNXMlogOfwlXAhHp7Wy/OjjFiUhTey8Unvo6oq5+Is5ANiKVN+Iw07Pcb/HpkGt7jCB6a4ITgg== - dependencies: - "@ethereumjs/block" "^3.4.0" - "@ethereumjs/blockchain" "^5.4.0" - "@ethereumjs/common" "^2.4.0" - "@ethereumjs/tx" "^3.3.0" - "@ethereumjs/vm" "^5.5.2" - "@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.0" - 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.0" - mnemonist "^0.38.0" - mocha "^7.1.2" - 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 "^3.3.2" - ws "^7.4.6" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - dependencies: - ansi-regex "^2.0.0" - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - -has-symbol-support-x@^1.4.1: - version "1.4.2" - resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" - -has-symbols@^1.0.0, has-symbols@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" - -has-to-string-tag-x@^1.2.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" - dependencies: - has-symbol-support-x "^1.4.1" - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -has@^1.0.3, has@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - 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" - 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" - 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" - 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" - -heap@0.2.6: - version "0.2.6" - resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.6.tgz#087e1f10b046932fc8594dd9e6d378afc9d1e5ac" - -hmac-drbg@^1.0.0, hmac-drbg@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - -home-or-tmp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.1" - -hosted-git-info@^2.1.4, hosted-git-info@^2.6.0: - version "2.8.8" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" - -http-cache-semantics@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" - -http-errors@1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -http-errors@1.7.3, http-errors@~1.7.2: - version "1.7.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -http-https@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/http-https/-/http-https-1.0.0.tgz#2f908dd5f1db4068c058cd6e6d4ce392c913389b" - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -https-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" - dependencies: - agent-base "6" - debug "4" - -iconv-lite@0.4.24, iconv-lite@^0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - dependencies: - safer-buffer ">= 2.1.2 < 3" - -iconv-lite@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.2.tgz#ce13d1875b0c3a674bd6a04b7f76b01b1b6ded01" - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - -idna-uts46-hx@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz#a1dc5c4df37eee522bf66d969cc980e00e8711f9" - dependencies: - punycode "2.1.0" - -ieee754@^1.1.13: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - -ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - -immediate@^3.2.3: - version "3.3.0" - resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.3.0.tgz#1aef225517836bcdf7f2a2de2600c79ff0269266" - -immediate@~3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c" - -immutable@^4.0.0-rc.12: - version "4.0.0-rc.12" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.0.0-rc.12.tgz#ca59a7e4c19ae8d9bf74a97bdf0f6e2f2a5d0217" - -import-fresh@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" - dependencies: - caller-path "^2.0.0" - resolve-from "^3.0.0" - -import-fresh@^3.0.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - -inquirer@^6.2.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" - 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" - -invariant@^2.2.2: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - dependencies: - loose-envify "^1.0.0" - -invert-kv@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" - -io-ts@1.10.4: - version "1.10.4" - resolved "https://registry.yarnpkg.com/io-ts/-/io-ts-1.10.4.tgz#cd5401b138de88e4f920adbcb7026e2d1967e6e2" - dependencies: - fp-ts "^1.0.0" - -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - dependencies: - kind-of "^6.0.0" - -is-arguments@^1.0.4: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9" - dependencies: - call-bind "^1.0.0" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - -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" - dependencies: - binary-extensions "^2.0.0" - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - -is-buffer@~2.0.3: - version "2.0.5" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" - -is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.2.tgz#c7c6715cd22d4ddb48d3e19970223aceabb080d9" - -is-ci@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" - dependencies: - ci-info "^2.0.0" - -is-core-module@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" - dependencies: - has "^1.0.3" - -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - dependencies: - kind-of "^6.0.0" - -is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -is-directory@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - -is-finite@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" - -is-fn@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fn/-/is-fn-1.0.0.tgz#9543d5de7bcf5b08a22ec8a20bae6e286d510d8c" - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - -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" - -is-function@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08" - -is-glob@^4.0.1, is-glob@~4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - 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" - -is-negative-zero@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - dependencies: - kind-of "^3.0.2" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - -is-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" - -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" - -is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - dependencies: - isobject "^3.0.1" - -is-regex@^1.0.4, is-regex@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.1.tgz#c6f98aacc546f6cec5468a07b7b153ab564a57b9" - dependencies: - has-symbols "^1.0.1" - -is-regex@~1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" - dependencies: - has "^1.0.3" - -is-retry-allowed@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" - -is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - -is-svg@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-4.3.1.tgz#8c63ec8c67c8c7f0a8de0a71c8c7d58eccf4406b" - integrity sha512-h2CGs+yPUyvkgTJQS9cJzo9lYK06WgRiXUqBBHtglSzVKAuH4/oWsqk7LGfbSa1hGk9QcZ0SyQtVggvBA8LZXA== - dependencies: - fast-xml-parser "^3.19.0" - -is-symbol@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" - dependencies: - has-symbols "^1.0.1" - -is-typedarray@^1.0.0, is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - -is-url@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" - -is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - -is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - -isarray@1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - -isurl@^1.0.0-alpha5: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" - dependencies: - has-to-string-tag-x "^1.2.0" - is-object "^1.0.1" - -jest-diff@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.6.2.tgz#1aa7468b52c3a68d7d5c5fdcdfcd5e49bd164394" - dependencies: - chalk "^4.0.0" - diff-sequences "^26.6.2" - jest-get-type "^26.3.0" - pretty-format "^26.6.2" - -jest-get-type@^26.3.0: - version "26.3.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" - -jest-haste-map@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.2.tgz#dd7e60fe7dc0e9f911a23d79c5ff7fb5c2cafeaa" - dependencies: - "@jest/types" "^26.6.2" - "@types/graceful-fs" "^4.1.2" - "@types/node" "*" - anymatch "^3.0.3" - fb-watchman "^2.0.0" - graceful-fs "^4.2.4" - jest-regex-util "^26.0.0" - jest-serializer "^26.6.2" - jest-util "^26.6.2" - jest-worker "^26.6.2" - micromatch "^4.0.2" - sane "^4.0.3" - walker "^1.0.7" - optionalDependencies: - fsevents "^2.1.2" - -jest-matcher-utils@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz#8e6fd6e863c8b2d31ac6472eeb237bc595e53e7a" - dependencies: - chalk "^4.0.0" - jest-diff "^26.6.2" - jest-get-type "^26.3.0" - pretty-format "^26.6.2" - -jest-message-util@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-26.6.2.tgz#58173744ad6fc0506b5d21150b9be56ef001ca07" - dependencies: - "@babel/code-frame" "^7.0.0" - "@jest/types" "^26.6.2" - "@types/stack-utils" "^2.0.0" - chalk "^4.0.0" - graceful-fs "^4.2.4" - micromatch "^4.0.2" - pretty-format "^26.6.2" - slash "^3.0.0" - stack-utils "^2.0.2" - -jest-pnp-resolver@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" - -jest-regex-util@^26.0.0: - version "26.0.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" - -jest-resolve@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-26.6.2.tgz#a3ab1517217f469b504f1b56603c5bb541fbb507" - dependencies: - "@jest/types" "^26.6.2" - chalk "^4.0.0" - graceful-fs "^4.2.4" - jest-pnp-resolver "^1.2.2" - jest-util "^26.6.2" - read-pkg-up "^7.0.1" - resolve "^1.18.1" - slash "^3.0.0" - -jest-serializer@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-26.6.2.tgz#d139aafd46957d3a448f3a6cdabe2919ba0742d1" - dependencies: - "@types/node" "*" - graceful-fs "^4.2.4" - -jest-snapshot@^26.5.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-26.6.2.tgz#f3b0af1acb223316850bd14e1beea9837fb39c84" - dependencies: - "@babel/types" "^7.0.0" - "@jest/types" "^26.6.2" - "@types/babel__traverse" "^7.0.4" - "@types/prettier" "^2.0.0" - chalk "^4.0.0" - expect "^26.6.2" - graceful-fs "^4.2.4" - jest-diff "^26.6.2" - jest-get-type "^26.3.0" - jest-haste-map "^26.6.2" - jest-matcher-utils "^26.6.2" - jest-message-util "^26.6.2" - jest-resolve "^26.6.2" - natural-compare "^1.4.0" - pretty-format "^26.6.2" - semver "^7.3.2" - -jest-util@^26.5.2, jest-util@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1" - dependencies: - "@jest/types" "^26.6.2" - "@types/node" "*" - chalk "^4.0.0" - graceful-fs "^4.2.4" - is-ci "^2.0.0" - micromatch "^4.0.2" - -jest-worker@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^7.0.0" - -js-sha3@0.5.7, js-sha3@^0.5.7: - version "0.5.7" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" - -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" - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - -js-tokens@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" - -js-yaml@3.13.1: - version "3.13.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -js-yaml@^3.12.0, js-yaml@^3.13.0, js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - -jsesc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" - -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - -json-buffer@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" - -json-parse-better-errors@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - -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" - -json-rpc-engine@^3.4.0, json-rpc-engine@^3.6.0: - version "3.8.0" - resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-3.8.0.tgz#9d4ff447241792e1d0a232f6ef927302bb0c62a9" - dependencies: - async "^2.0.1" - babel-preset-env "^1.7.0" - babelify "^7.3.0" - json-rpc-error "^2.0.0" - promise-to-callback "^1.0.0" - safe-event-emitter "^1.0.1" - -json-rpc-error@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/json-rpc-error/-/json-rpc-error-2.0.0.tgz#a7af9c202838b5e905c7250e547f1aff77258a02" - dependencies: - inherits "^2.0.1" - -json-rpc-random-id@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz#ba49d96aded1444dbb8da3d203748acbbcdec8c8" - -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" - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - -json-stable-stringify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - dependencies: - jsonify "~0.0.0" - -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" - -json5@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" - -jsonfile@^2.1.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" - 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" - optionalDependencies: - graceful-fs "^4.1.6" - -jsonify@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -keccak@3.0.1, keccak@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.1.tgz#ae30a0e94dbe43414f741375cff6d64c8bea0bff" - dependencies: - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - -keyv@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" - dependencies: - json-buffer "3.0.0" - -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - -kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" - -klaw-sync@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/klaw-sync/-/klaw-sync-6.0.0.tgz#1fd2cfd56ebb6250181114f0a581167099c2b28c" - dependencies: - graceful-fs "^4.1.11" - -klaw@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" - optionalDependencies: - graceful-fs "^4.1.9" - -lcid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - dependencies: - invert-kv "^1.0.0" - -level-codec@^9.0.0: - version "9.0.2" - resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-9.0.2.tgz#fd60df8c64786a80d44e63423096ffead63d8cbc" - dependencies: - buffer "^5.6.0" - -level-codec@~7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-7.0.1.tgz#341f22f907ce0f16763f24bddd681e395a0fb8a7" - -level-concat-iterator@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz#1d1009cf108340252cb38c51f9727311193e6263" - integrity sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw== - -level-errors@^1.0.3: - version "1.1.2" - resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.1.2.tgz#4399c2f3d3ab87d0625f7e3676e2d807deff404d" - dependencies: - errno "~0.1.1" - -level-errors@^2.0.0, level-errors@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-2.0.1.tgz#2132a677bf4e679ce029f517c2f17432800c05c8" - dependencies: - errno "~0.1.1" - -level-errors@~1.0.3: - version "1.0.5" - resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.0.5.tgz#83dbfb12f0b8a2516bdc9a31c4876038e227b859" - dependencies: - errno "~0.1.1" - -level-iterator-stream@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-2.0.3.tgz#ccfff7c046dcf47955ae9a86f46dfa06a31688b4" - dependencies: - inherits "^2.0.1" - readable-stream "^2.0.5" - xtend "^4.0.0" - -level-iterator-stream@~1.3.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz#e43b78b1a8143e6fa97a4f485eb8ea530352f2ed" - dependencies: - inherits "^2.0.1" - level-errors "^1.0.3" - readable-stream "^1.0.33" - xtend "^4.0.0" - -level-iterator-stream@~3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-3.0.1.tgz#2c98a4f8820d87cdacab3132506815419077c730" - dependencies: - inherits "^2.0.1" - readable-stream "^2.3.6" - xtend "^4.0.0" - -level-iterator-stream@~4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz#7ceba69b713b0d7e22fcc0d1f128ccdc8a24f79c" - integrity sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q== - dependencies: - inherits "^2.0.4" - readable-stream "^3.4.0" - xtend "^4.0.2" - -level-mem@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/level-mem/-/level-mem-3.0.1.tgz#7ce8cf256eac40f716eb6489654726247f5a89e5" - dependencies: - level-packager "~4.0.0" - memdown "~3.0.0" - -level-mem@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/level-mem/-/level-mem-5.0.1.tgz#c345126b74f5b8aa376dc77d36813a177ef8251d" - integrity sha512-qd+qUJHXsGSFoHTziptAKXoLX87QjR7v2KMbqncDXPxQuCdsQlzmyX+gwrEHhlzn08vkf8TyipYyMmiC6Gobzg== - dependencies: - level-packager "^5.0.3" - memdown "^5.0.0" - -level-packager@^5.0.3: - version "5.1.1" - resolved "https://registry.yarnpkg.com/level-packager/-/level-packager-5.1.1.tgz#323ec842d6babe7336f70299c14df2e329c18939" - integrity sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ== - dependencies: - encoding-down "^6.3.0" - levelup "^4.3.2" - -level-packager@~4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/level-packager/-/level-packager-4.0.1.tgz#7e7d3016af005be0869bc5fa8de93d2a7f56ffe6" - dependencies: - encoding-down "~5.0.0" - levelup "^3.0.0" - -level-post@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/level-post/-/level-post-1.0.7.tgz#19ccca9441a7cc527879a0635000f06d5e8f27d0" - dependencies: - ltgt "^2.1.2" - -level-sublevel@6.6.4: - version "6.6.4" - resolved "https://registry.yarnpkg.com/level-sublevel/-/level-sublevel-6.6.4.tgz#f7844ae893919cd9d69ae19d7159499afd5352ba" - dependencies: - bytewise "~1.1.0" - level-codec "^9.0.0" - level-errors "^2.0.0" - level-iterator-stream "^2.0.3" - ltgt "~2.1.1" - pull-defer "^0.2.2" - pull-level "^2.0.3" - pull-stream "^3.6.8" - typewiselite "~1.0.0" - xtend "~4.0.0" - -level-supports@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-1.0.1.tgz#2f530a596834c7301622521988e2c36bb77d122d" - integrity sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg== - dependencies: - xtend "^4.0.2" - -level-ws@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-0.0.0.tgz#372e512177924a00424b0b43aef2bb42496d228b" - dependencies: - readable-stream "~1.0.15" - xtend "~2.1.1" - -level-ws@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-1.0.0.tgz#19a22d2d4ac57b18cc7c6ecc4bd23d899d8f603b" - dependencies: - inherits "^2.0.3" - readable-stream "^2.2.8" - xtend "^4.0.1" - -level-ws@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-2.0.0.tgz#207a07bcd0164a0ec5d62c304b4615c54436d339" - integrity sha512-1iv7VXx0G9ec1isqQZ7y5LmoZo/ewAsyDHNA8EFDW5hqH2Kqovm33nSFkSdnLLAK+I5FlT+lo5Cw9itGe+CpQA== - dependencies: - inherits "^2.0.3" - readable-stream "^3.1.0" - xtend "^4.0.1" - -levelup@3.1.1, levelup@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/levelup/-/levelup-3.1.1.tgz#c2c0b3be2b4dc316647c53b42e2f559e232d2189" - dependencies: - deferred-leveldown "~4.0.0" - level-errors "~2.0.0" - level-iterator-stream "~3.0.0" - xtend "~4.0.0" - -levelup@^1.2.1: - version "1.3.9" - resolved "https://registry.yarnpkg.com/levelup/-/levelup-1.3.9.tgz#2dbcae845b2bb2b6bea84df334c475533bbd82ab" - 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" - -levelup@^4.3.2: - version "4.4.0" - resolved "https://registry.yarnpkg.com/levelup/-/levelup-4.4.0.tgz#f89da3a228c38deb49c48f88a70fb71f01cafed6" - 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" - -levn@^0.3.0, levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -lines-and-columns@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" - -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - 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" - 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" - dependencies: - p-locate "^4.1.0" - -lodash.assign@^4.0.3, lodash.assign@^4.0.6: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" - -lodash@4.17.20, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.4: - version "4.17.20" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" - -log-symbols@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" - dependencies: - chalk "^2.0.1" - -log-symbols@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" - dependencies: - chalk "^2.4.2" - -looper@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/looper/-/looper-2.0.0.tgz#66cd0c774af3d4fedac53794f742db56da8f09ec" - -looper@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/looper/-/looper-3.0.0.tgz#2efa54c3b1cbaba9b94aee2e5914b0be57fbb749" - -loose-envify@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" - -lowercase-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" - -lru-cache@5.1.1, lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - dependencies: - yallist "^3.0.2" - -lru-cache@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-3.2.0.tgz#71789b3b7f5399bec8565dda38aa30d2a097efee" - dependencies: - pseudomap "^1.0.1" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - 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" - -ltgt@^2.1.2, ltgt@~2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5" - -ltgt@~2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.1.3.tgz#10851a06d9964b971178441c23c9e52698eece34" - -make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - -makeerror@1.0.x: - version "1.0.11" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" - dependencies: - tmpl "1.0.x" - -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - dependencies: - object-visit "^1.0.0" - -mcl-wasm@^0.7.1: - version "0.7.6" - resolved "https://registry.yarnpkg.com/mcl-wasm/-/mcl-wasm-0.7.6.tgz#c1789ebda5565d49b77d2ee195ff3e4d282f1554" - integrity sha512-cbRl3sUOkBeRY2hsM4t1EIln2TIdQBkSiTOqNTv/4Hu5KOECnMWCgjIf+a9Ebunyn22VKqkMF3zj6ejRzz7YBw== - -md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - -memdown@^1.0.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/memdown/-/memdown-1.4.1.tgz#b4e4e192174664ffbae41361aa500f3119efe215" - dependencies: - abstract-leveldown "~2.7.1" - functional-red-black-tree "^1.0.1" - immediate "^3.2.3" - inherits "~2.0.1" - ltgt "~2.2.0" - safe-buffer "~5.1.1" - -memdown@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/memdown/-/memdown-5.1.0.tgz#608e91a9f10f37f5b5fe767667a8674129a833cb" - 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" - -memdown@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/memdown/-/memdown-3.0.0.tgz#93aca055d743b20efc37492e9e399784f2958309" - 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" - -memorystream@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" - -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - -merkle-patricia-tree@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-3.0.0.tgz#448d85415565df72febc33ca362b8b614f5a58f8" - dependencies: - async "^2.6.1" - ethereumjs-util "^5.2.0" - level-mem "^3.0.1" - level-ws "^1.0.0" - readable-stream "^3.0.6" - rlp "^2.0.0" - semaphore ">=1.0.1" - -merkle-patricia-tree@^2.1.2, merkle-patricia-tree@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz#982ca1b5a0fde00eed2f6aeed1f9152860b8208a" - 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" - -merkle-patricia-tree@^4.2.0, merkle-patricia-tree@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-4.2.2.tgz#6dec17855370172458244c2f42c989dd60b773a3" - 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" - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - -micromatch@^3.1.4: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - -micromatch@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" - dependencies: - braces "^3.0.1" - picomatch "^2.0.5" - -miller-rabin@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" - dependencies: - bn.js "^4.0.0" - brorand "^1.0.1" - -mime-db@1.44.0: - version "1.44.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" - -mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.19, mime-types@~2.1.24: - version "2.1.27" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" - dependencies: - mime-db "1.44.0" - -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - -mimic-fn@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" - -mimic-response@^1.0.0, mimic-response@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" - -min-document@^2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" - dependencies: - dom-walk "^0.1.0" - -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - -minimalistic-crypto-utils@^1.0.0, 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" - -minimatch@3.0.4, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - dependencies: - brace-expansion "^1.1.7" - -minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5, minimist@~1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - -minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - -minizlib@^1.2.1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" - dependencies: - minipass "^2.9.0" - -mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - -mkdirp-promise@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz#e9b8f68e552c68a9c1713b84883f7a1dd039b8a1" - dependencies: - mkdirp "*" - -mkdirp@*: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - -mkdirp@0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.4.tgz#fd01504a6797ec5c9be81ff43d204961ed64a512" - dependencies: - minimist "^1.2.5" - -mkdirp@0.5.5, mkdirp@^0.5.0, mkdirp@^0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - dependencies: - minimist "^1.2.5" - -mnemonist@^0.38.0: - version "0.38.3" - resolved "https://registry.yarnpkg.com/mnemonist/-/mnemonist-0.38.3.tgz#35ec79c1c1f4357cfda2fe264659c2775ccd7d9d" - integrity sha512-2K9QYubXx/NAjv4VLq1d1Ly8pWNC5L3BrixtdkyTegXWJIqY+zLNDhhX/A+ZwWt70tB1S8H4BE8FLYEFyNoOBw== - dependencies: - obliterator "^1.6.1" - -mocha-chai-jest-snapshot@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/mocha-chai-jest-snapshot/-/mocha-chai-jest-snapshot-1.1.1.tgz#7e49f20d0c12e6792d7f7da2e4ee0c38950571cc" - dependencies: - "@jest/test-result" "^26.5.2" - chalk "^4.1.0" - find-package-json "^1.2.0" - jest-snapshot "^26.5.2" - jest-util "^26.5.2" - slash "^3.0.0" - yargs "^16.0.3" - -mocha@^6.2.2: - version "6.2.3" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-6.2.3.tgz#e648432181d8b99393410212664450a4c1e31912" - dependencies: - ansi-colors "3.2.3" - browser-stdout "1.3.1" - 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 "2.2.0" - minimatch "3.0.4" - mkdirp "0.5.4" - ms "2.1.1" - node-environment-flags "1.0.5" - 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@^7.1.2: - version "7.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.2.0.tgz#01cc227b00d875ab1eed03a75106689cfed5a604" - 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" - -mock-fs@^4.1.0: - version "4.13.0" - resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.13.0.tgz#31c02263673ec3789f90eb7b6963676aa407a598" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - -ms@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - -ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - -multibase@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.7.0.tgz#1adfc1c50abe05eefeb5091ac0c2728d6b84581b" - dependencies: - base-x "^3.0.8" - buffer "^5.5.0" - -multibase@~0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.6.1.tgz#b76df6298536cc17b9f6a6db53ec88f85f8cc12b" - dependencies: - base-x "^3.0.8" - buffer "^5.5.0" - -multicodec@^0.5.5: - version "0.5.7" - resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-0.5.7.tgz#1fb3f9dd866a10a55d226e194abba2dcc1ee9ffd" - dependencies: - varint "^5.0.0" - -multicodec@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-1.0.4.tgz#46ac064657c40380c28367c90304d8ed175a714f" - dependencies: - buffer "^5.6.0" - varint "^5.0.0" - -multihashes@^0.4.15, multihashes@~0.4.15: - version "0.4.21" - resolved "https://registry.yarnpkg.com/multihashes/-/multihashes-0.4.21.tgz#dc02d525579f334a7909ade8a122dabb58ccfcb5" - dependencies: - buffer "^5.5.0" - multibase "^0.7.0" - varint "^5.0.0" - -mute-stream@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" - -nano-json-stream-parser@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f" - -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - 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" - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - -negotiator@0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" - -next-tick@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" - -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - -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" - -node-environment-flags@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.5.tgz#fa930275f5bf5dae188d6192b24b4c8bbac3d76a" - dependencies: - object.getownpropertydescriptors "^2.0.3" - semver "^5.7.0" - -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" - dependencies: - object.getownpropertydescriptors "^2.0.3" - semver "^5.7.0" - -node-fetch@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" - -node-fetch@^2.6.0: - version "2.6.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" - -node-fetch@~1.7.1: - version "1.7.3" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" - dependencies: - encoding "^0.1.11" - is-stream "^1.0.1" - -node-gyp-build@^4.2.0: - version "4.2.3" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.2.3.tgz#ce6277f853835f718829efb47db20f3e4d9c4739" - -node-int64@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" - -nofilter@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-1.0.4.tgz#78d6f4b6a613e7ced8b015cec534625f7667006e" - integrity sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA== - -normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - dependencies: - remove-trailing-separator "^1.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" - -normalize-url@^4.1.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - dependencies: - path-key "^2.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - -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" - 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" - -object-assign@^4, object-assign@^4.0.0, object-assign@^4.1.0, object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-inspect@^1.8.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a" - -object-inspect@~1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" - -object-is@^1.0.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.4.tgz#63d6c83c00a43f4cbc9434eb9757c8a5b8565068" - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - -object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - -object-keys@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" - -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - dependencies: - isobject "^3.0.0" - -object.assign@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" - 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.1: - version "4.1.2" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - has-symbols "^1.0.1" - object-keys "^1.1.1" - -object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.1.tgz#0dfda8d108074d9c563e80490c883b6661091544" - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - es-abstract "^1.18.0-next.1" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - dependencies: - isobject "^3.0.1" - -obliterator@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-1.6.1.tgz#dea03e8ab821f6c4d96a299e17aef6a3af994ef3" - integrity sha512-9WXswnqINnnhOG/5SLimUlzuU1hFJUc8zkwyD59Sd+dPOMf05PmnYG/d6Q7HZ+KmgkZJa1PxRso6QdM3sTNHig== - -oboe@2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.4.tgz#20c88cdb0c15371bb04119257d4fdd34b0aa49f6" - dependencies: - http-https "^1.0.0" - -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - dependencies: - ee-first "1.1.1" - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - dependencies: - wrappy "1" - -onetime@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" - dependencies: - mimic-fn "^1.0.0" - -optionator@^0.8.2: - 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" - -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - -os-locale@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" - dependencies: - lcid "^1.0.0" - -os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - -p-cancelable@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" - -p-cancelable@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - 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" - dependencies: - p-try "^2.0.0" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - 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" - 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" - dependencies: - p-limit "^2.2.0" - -p-timeout@^1.1.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386" - dependencies: - p-finally "^1.0.0" - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - dependencies: - callsites "^3.0.0" - -parse-asn1@^5.0.0, parse-asn1@^5.1.5: - version "5.1.6" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" - dependencies: - asn1.js "^5.2.0" - browserify-aes "^1.0.0" - evp_bytestokey "^1.0.0" - pbkdf2 "^3.0.3" - safe-buffer "^5.1.1" - -parse-headers@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.3.tgz#5e8e7512383d140ba02f0c7aa9f49b4399c92515" - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - dependencies: - error-ex "^1.2.0" - -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -parse-json@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.1.0.tgz#f96088cdf24a8faa9aea9a009f2d9d942c999646" - 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" - -parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - -patch-package@6.2.2, patch-package@^6.2.2: - version "6.2.2" - resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.2.2.tgz#71d170d650c65c26556f0d0fbbb48d92b6cc5f39" - 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" - -path-browserify@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - dependencies: - pinkie-promise "^2.0.0" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - -path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - -path-is-inside@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - -path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - -path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -pathval@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" - -pbkdf2@^3.0.17, pbkdf2@^3.0.3, pbkdf2@^3.0.9: - version "3.1.1" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" - 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" - -picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: - version "2.2.2" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" - -pify@^2.0.0, pify@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - -postinstall-postinstall@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz#4f7f77441ef539d1512c40bd04c71b06a4704ca3" - -precond@0.2: - version "0.2.3" - resolved "https://registry.yarnpkg.com/precond/-/precond-0.2.3.tgz#aa9591bcaa24923f1e0f4849d240f47efc1075ac" - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - -prepend-http@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - -prepend-http@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" - -prettier-linter-helpers@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" - dependencies: - fast-diff "^1.1.2" - -prettier-plugin-solidity@^1.0.0-beta.10: - version "1.0.0-beta.10" - resolved "https://registry.yarnpkg.com/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-beta.10.tgz#f2a249002733826b08d981b599335ddb7e93af8d" - integrity sha512-55UsEbeJfqYKB3RFR7Nvpi+ApEoUfgdKHVg2ZybrbOkRW4RTblyONLL3mEr8Vrxpo7wBbObVLbWodGg4YXIQ7g== - dependencies: - "@solidity-parser/parser" "^0.12.1" - dir-to-object "^2.0.0" - emoji-regex "^9.2.2" - escape-string-regexp "^4.0.0" - prettier "^2.2.1" - semver "^7.3.5" - solidity-comments-extractor "^0.0.7" - string-width "^4.2.2" - -prettier@^1.14.3: - version "1.19.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" - -prettier@^2.0.5, prettier@^2.1.2, prettier@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" - -pretty-format@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93" - dependencies: - "@jest/types" "^26.6.2" - ansi-regex "^5.0.0" - ansi-styles "^4.0.0" - react-is "^17.0.1" - -printj@~1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222" - integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ== - -private@^0.1.6, private@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" - -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" - -process@^0.11.10: - version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" - -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - -promise-to-callback@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/promise-to-callback/-/promise-to-callback-1.0.0.tgz#5d2a749010bfb67d963598fcd3960746a68feef7" - dependencies: - is-fn "^1.0.0" - set-immediate-shim "^1.0.1" - -proxy-addr@~2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" - dependencies: - forwarded "~0.1.2" - ipaddr.js "1.9.1" - -prr@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" - -pseudomap@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - -psl@^1.1.28: - version "1.8.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" - -public-encrypt@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" - dependencies: - bn.js "^4.1.0" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - parse-asn1 "^5.0.0" - randombytes "^2.0.1" - safe-buffer "^5.1.2" - -pull-cat@^1.1.9: - version "1.1.11" - resolved "https://registry.yarnpkg.com/pull-cat/-/pull-cat-1.1.11.tgz#b642dd1255da376a706b6db4fa962f5fdb74c31b" - -pull-defer@^0.2.2: - version "0.2.3" - resolved "https://registry.yarnpkg.com/pull-defer/-/pull-defer-0.2.3.tgz#4ee09c6d9e227bede9938db80391c3dac489d113" - -pull-level@^2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pull-level/-/pull-level-2.0.4.tgz#4822e61757c10bdcc7cf4a03af04c92734c9afac" - dependencies: - level-post "^1.0.7" - pull-cat "^1.1.9" - pull-live "^1.0.1" - pull-pushable "^2.0.0" - pull-stream "^3.4.0" - pull-window "^2.1.4" - stream-to-pull-stream "^1.7.1" - -pull-live@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/pull-live/-/pull-live-1.0.1.tgz#a4ecee01e330155e9124bbbcf4761f21b38f51f5" - dependencies: - pull-cat "^1.1.9" - pull-stream "^3.4.0" - -pull-pushable@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/pull-pushable/-/pull-pushable-2.2.0.tgz#5f2f3aed47ad86919f01b12a2e99d6f1bd776581" - -pull-stream@^3.2.3, pull-stream@^3.4.0, pull-stream@^3.6.8: - version "3.6.14" - resolved "https://registry.yarnpkg.com/pull-stream/-/pull-stream-3.6.14.tgz#529dbd5b86131f4a5ed636fdf7f6af00781357ee" - -pull-window@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/pull-window/-/pull-window-2.1.4.tgz#fc3b86feebd1920c7ae297691e23f705f88552f0" - dependencies: - looper "^2.0.0" - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - -punycode@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" - -punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - -qs@6.7.0: - version "6.7.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" - -qs@^6.7.0: - version "6.9.4" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.4.tgz#9090b290d1f91728d3c22e54843ca44aea5ab687" - -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - -query-string@^5.0.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" - dependencies: - decode-uri-component "^0.2.0" - object-assign "^4.1.0" - strict-uri-encode "^1.0.0" - -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.0.6, randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - dependencies: - safe-buffer "^5.1.0" - -randomfill@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" - dependencies: - randombytes "^2.0.5" - safe-buffer "^5.1.0" - -range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - -raw-body@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" - dependencies: - bytes "3.1.0" - http-errors "1.7.2" - iconv-lite "0.4.24" - unpipe "1.0.0" - -raw-body@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" - dependencies: - bytes "3.1.0" - http-errors "1.7.3" - iconv-lite "0.4.24" - unpipe "1.0.0" - -react-is@^17.0.1: - version "17.0.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.1.tgz#5b3531bd76a645a4c9fb6e693ed36419e3301339" - -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - dependencies: - find-up "^1.0.0" - read-pkg "^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" - dependencies: - find-up "^4.1.0" - read-pkg "^5.2.0" - type-fest "^0.8.1" - -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - -read-pkg@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" - 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@^1.0.33: - version "1.1.14" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.2.2, readable-stream@^2.2.8, readable-stream@^2.2.9, readable-stream@^2.3.6, readable-stream@~2.3.6: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.0.6, readable-stream@^3.1.0, readable-stream@^3.4.0, readable-stream@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readable-stream@~1.0.15: - version "1.0.34" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readdirp@~3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.2.0.tgz#c30c33352b12c96dfb4b895421a49fd5a9593839" - dependencies: - picomatch "^2.0.4" - -readdirp@~3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" - dependencies: - picomatch "^2.2.1" - -regenerate@^1.2.1: - version "1.4.2" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" - -regenerator-runtime@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" - -regenerator-transform@^0.10.0: - version "0.10.1" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" - dependencies: - babel-runtime "^6.18.0" - babel-types "^6.19.0" - private "^0.1.6" - -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - -regexp.prototype.flags@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75" - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - -regexpp@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" - -regexpu-core@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" - dependencies: - regenerate "^1.2.1" - regjsgen "^0.2.0" - regjsparser "^0.1.4" - -regjsgen@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" - -regjsparser@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" - dependencies: - jsesc "~0.5.0" - -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - -repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - -repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - dependencies: - is-finite "^1.0.0" - -request@^2.79.0, request@^2.85.0: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - 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" - -require-from-string@^1.1.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418" - -require-from-string@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - -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" - -resolve-from@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - -resolve@1.17.0, resolve@~1.17.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" - dependencies: - path-parse "^1.0.6" - -resolve@^1.10.0, resolve@^1.18.1, resolve@^1.8.1: - version "1.19.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c" - dependencies: - is-core-module "^2.1.0" - path-parse "^1.0.6" - -responselike@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" - dependencies: - lowercase-keys "^1.0.0" - -restore-cursor@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" - dependencies: - onetime "^2.0.0" - signal-exit "^3.0.2" - -resumer@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/resumer/-/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759" - dependencies: - through "~2.3.4" - -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - -rimraf@2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - dependencies: - glob "^7.1.3" - -rimraf@^2.2.8, rimraf@^2.6.3: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - 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" - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - -rlp@^2.0.0, rlp@^2.2.1, rlp@^2.2.2, rlp@^2.2.3, rlp@^2.2.4: - version "2.2.6" - resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.6.tgz#c80ba6266ac7a483ef1e69e8e2f056656de2fb2c" - dependencies: - bn.js "^4.11.1" - -rsvp@^4.8.4: - version "4.8.5" - resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" - -run-async@^2.2.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" - -rustbn.js@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca" - -rxjs@^6.4.0: - version "6.6.3" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.3.tgz#8ca84635c4daa900c0d3967a6ee7ac60271ee552" - dependencies: - tslib "^1.9.0" - -safe-buffer@5.1.2, 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" - -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" - -safe-event-emitter@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/safe-event-emitter/-/safe-event-emitter-1.0.1.tgz#5b692ef22329ed8f69fdce607e50ca734f6f20af" - dependencies: - events "^3.0.0" - -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - dependencies: - ret "~0.1.10" - -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - -sane@^4.0.3: - version "4.1.0" - resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" - dependencies: - "@cnakazawa/watch" "^1.0.3" - anymatch "^2.0.0" - capture-exit "^2.0.0" - exec-sh "^0.3.2" - execa "^1.0.0" - fb-watchman "^2.0.0" - micromatch "^3.1.4" - minimist "^1.1.1" - walker "~1.0.5" - -scrypt-js@3.0.1, scrypt-js@^3.0.0, scrypt-js@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" - -scryptsy@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/scryptsy/-/scryptsy-1.2.1.tgz#a3225fa4b2524f802700761e2855bdf3b2d92163" - dependencies: - pbkdf2 "^3.0.3" - -secp256k1@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.2.tgz#15dd57d0f0b9fdb54ac1fa1694f40e5e9a54f4a1" - dependencies: - elliptic "^6.5.2" - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - -seedrandom@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.1.tgz#eb3dde015bcf55df05a233514e5df44ef9dce083" - -semaphore-async-await@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/semaphore-async-await/-/semaphore-async-await-1.5.1.tgz#857bef5e3644601ca4b9570b87e9df5ca12974fa" - integrity sha1-hXvvXjZEYBykuVcLh+nfXKEpdPo= - -semaphore@>=1.0.1, semaphore@^1.0.3, semaphore@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/semaphore/-/semaphore-1.1.0.tgz#aaad8b86b20fe8e9b32b16dc2ee682a8cd26a8aa" - -"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - -semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - -semver@^7.3.2: - version "7.3.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97" - dependencies: - lru-cache "^6.0.0" - -semver@^7.3.5: - version "7.3.5" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== - dependencies: - lru-cache "^6.0.0" - -semver@~5.4.1: - version "5.4.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" - -send@0.17.1: - version "0.17.1" - resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" - 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" - -serve-static@1.14.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.17.1" - -servify@^0.1.12: - version "0.1.12" - resolved "https://registry.yarnpkg.com/servify/-/servify-0.1.12.tgz#142ab7bee1f1d033b66d0707086085b17c06db95" - dependencies: - body-parser "^1.16.0" - cors "^2.8.1" - express "^4.14.0" - request "^2.79.0" - xhr "^2.3.3" - -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - -set-immediate-shim@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" - -set-value@^2.0.0, set-value@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - -setimmediate@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - -setprototypeof@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" - -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" - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - dependencies: - shebang-regex "^1.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - -signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" - -simple-concat@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" - -simple-get@^2.7.0: - version "2.8.1" - resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.1.tgz#0e22e91d4575d87620620bc91308d57a77f44b5d" - dependencies: - decompress-response "^3.3.0" - once "^1.3.1" - simple-concat "^1.0.0" - -slash@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - -slash@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - -slice-ansi@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" - dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" - -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - -solc@0.7.3: - version "0.7.3" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.7.3.tgz#04646961bd867a744f63d2b4e3c0701ffdc7d78a" - dependencies: - command-exists "^1.2.8" - commander "3.0.2" - follow-redirects "^1.12.1" - fs-extra "^0.30.0" - js-sha3 "0.8.0" - memorystream "^0.3.1" - require-from-string "^2.0.0" - semver "^5.5.0" - tmp "0.0.33" - -solc@^0.4.20: - version "0.4.26" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.26.tgz#5390a62a99f40806b86258c737c1cf653cc35cb5" - dependencies: - fs-extra "^0.30.0" - memorystream "^0.3.1" - require-from-string "^1.1.0" - semver "^5.3.0" - yargs "^4.7.1" - -solc@^0.6.3: - version "0.6.12" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.6.12.tgz#48ac854e0c729361b22a7483645077f58cba080e" - 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" - -solhint-plugin-prettier@^0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/solhint-plugin-prettier/-/solhint-plugin-prettier-0.0.5.tgz#e3b22800ba435cd640a9eca805a7f8bc3e3e6a6b" - dependencies: - prettier-linter-helpers "^1.0.0" - -solhint@^3.2.1: - version "3.3.2" - resolved "https://registry.yarnpkg.com/solhint/-/solhint-3.3.2.tgz#ebd7270bb50fd378b427d7a6fc9f2a7fd00216c0" - dependencies: - "@solidity-parser/parser" "^0.8.2" - 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" - optionalDependencies: - prettier "^1.14.3" - -solidity-comments-extractor@^0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz#99d8f1361438f84019795d928b931f4e5c39ca19" - integrity sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw== - -source-map-resolve@^0.5.0: - version "0.5.3" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" - dependencies: - atob "^2.1.2" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-support@0.5.12: - version "0.5.12" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599" - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-support@^0.4.15: - version "0.4.18" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" - dependencies: - source-map "^0.5.6" - -source-map-support@^0.5.13, source-map-support@^0.5.17: - version "0.5.19" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - -source-map@^0.5.6, source-map@^0.5.7: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - -source-map@^0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - -spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - 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" - -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" - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.7" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz#e9c18a410e5ed7e12442a549fbd8afa767038d65" - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - dependencies: - extend-shallow "^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" - -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - 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" - -stack-utils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.3.tgz#cd5f030126ff116b78ccb3c027fe302713b61277" - dependencies: - escape-string-regexp "^2.0.0" - -stacktrace-parser@^0.1.10: - version "0.1.10" - resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" - dependencies: - type-fest "^0.7.1" - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -"statuses@>= 1.5.0 < 2", statuses@~1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - -stream-to-pull-stream@^1.7.1: - version "1.7.3" - resolved "https://registry.yarnpkg.com/stream-to-pull-stream/-/stream-to-pull-stream-1.7.3.tgz#4161aa2d2eb9964de60bfa1af7feaf917e874ece" - dependencies: - looper "^3.0.0" - pull-stream "^3.2.3" - -strict-uri-encode@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2", string-width@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - 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" - 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: - version "4.2.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.0" - -string-width@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" - integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.0" - -string.prototype.trim@~1.2.1: - version "1.2.3" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.3.tgz#d23a22fde01c1e6571a7fadcb9be11decd8061a7" - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - es-abstract "^1.18.0-next.1" - -string.prototype.trimend@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz#a22bd53cca5c7cf44d7c9d5c732118873d6cd18b" - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - -string.prototype.trimstart@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz#9b4cb590e123bb36564401d59824298de50fd5aa" - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - 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" - dependencies: - ansi-regex "^4.1.0" - -strip-ansi@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" - dependencies: - ansi-regex "^5.0.0" - -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - dependencies: - is-utf8 "^0.2.0" - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - -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" - dependencies: - is-hex-prefixed "1.0.0" - -strip-json-comments@2.0.1, strip-json-comments@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - -supports-color@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.0.0.tgz#76cfe742cf1f41bb9b1c29ad03068c05b4c0e40a" - dependencies: - has-flag "^3.0.0" - -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - dependencies: - has-flag "^3.0.0" - -supports-color@^7.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" - dependencies: - has-flag "^4.0.0" - -swarm-js@^0.1.40: - version "0.1.40" - resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.40.tgz#b1bc7b6dcc76061f6c772203e004c11997e06b99" - 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" - -table@^5.2.3: - version "5.4.6" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" - dependencies: - ajv "^6.10.2" - lodash "^4.17.14" - slice-ansi "^2.1.0" - string-width "^3.0.0" - -tape@^4.6.3: - version "4.13.3" - resolved "https://registry.yarnpkg.com/tape/-/tape-4.13.3.tgz#51b3d91c83668c7a45b1a594b607dee0a0b46278" - 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" - -tar@^4.0.2: - version "4.4.13" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" - 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" - -test-value@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/test-value/-/test-value-2.1.0.tgz#11da6ff670f3471a73b625ca4f3fdcf7bb748291" - dependencies: - array-back "^1.0.3" - typical "^2.6.0" - -testrpc@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/testrpc/-/testrpc-0.0.1.tgz#83e2195b1f5873aec7be1af8cbe6dcf39edb7aed" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - -through2@^2.0.3: - version "2.0.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" - dependencies: - readable-stream "~2.3.6" - xtend "~4.0.1" - -through@^2.3.6, through@~2.3.4, through@~2.3.8: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - -timed-out@^4.0.0, timed-out@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" - -tmp@0.0.33, tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - dependencies: - os-tmpdir "~1.0.2" - -tmp@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877" - dependencies: - rimraf "^2.6.3" - -tmpl@1.0.x: - version "1.0.4" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" - -to-fast-properties@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" - -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" - -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - dependencies: - kind-of "^3.0.2" - -to-readable-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - dependencies: - is-number "^7.0.0" - -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - -toidentifier@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" - -tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -trim-right@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" - -"true-case-path@^2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-2.2.1.tgz#c5bf04a5bbec3fd118be4084461b3a27c4d796bf" - -ts-essentials@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-1.0.4.tgz#ce3b5dade5f5d97cf69889c11bf7d2da8555b15a" - -ts-essentials@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-7.0.1.tgz#d205508cae0cdadfb73c89503140cf2228389e2d" - -ts-generator@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ts-generator/-/ts-generator-0.1.1.tgz#af46f2fb88a6db1f9785977e9590e7bcd79220ab" - dependencies: - "@types/mkdirp" "^0.5.2" - "@types/prettier" "^2.1.1" - "@types/resolve" "^0.0.8" - chalk "^2.4.1" - glob "^7.1.2" - mkdirp "^0.5.1" - prettier "^2.1.2" - resolve "^1.8.1" - ts-essentials "^1.0.0" - -ts-node@^8.5.4: - version "8.10.2" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.10.2.tgz#eee03764633b1234ddd37f8db9ec10b75ec7fb8d" - dependencies: - arg "^4.1.0" - diff "^4.0.1" - make-error "^1.1.1" - source-map-support "^0.5.17" - yn "3.1.1" - -tslib@^1.9.0, tslib@^1.9.3: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - -tsort@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/tsort/-/tsort-0.0.1.tgz#e2280f5e817f8bf4275657fd0f9aebd44f5a2786" - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - dependencies: - safe-buffer "^5.0.1" - -tweetnacl-util@^0.15.0: - version "0.15.1" - resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - -tweetnacl@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - 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" - -type-fest@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" - -type-fest@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" - -type-fest@^0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" - -type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" - -type-is@~1.6.17, type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -type@^1.0.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" - -type@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/type/-/type-2.1.0.tgz#9bdc22c648cf8cf86dd23d32336a41cfb6475e3f" - -typechain@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/typechain/-/typechain-4.0.1.tgz#b40eaf5ede15588d97a4b9a5f85120f7ea1cf262" - 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 "^7.0.1" - ts-generator "^0.1.1" - -typedarray-to-buffer@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" - dependencies: - is-typedarray "^1.0.0" - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - -typescript@^3.7.3: - version "3.9.7" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.7.tgz#98d600a5ebdc38f40cb277522f12dc800e9e25fa" - -typewise-core@^1.2, typewise-core@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/typewise-core/-/typewise-core-1.2.0.tgz#97eb91805c7f55d2f941748fa50d315d991ef195" - -typewise@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/typewise/-/typewise-1.0.3.tgz#1067936540af97937cc5dcf9922486e9fa284651" - dependencies: - typewise-core "^1.2.0" - -typewiselite@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typewiselite/-/typewiselite-1.0.0.tgz#c8882fa1bb1092c06005a97f34ef5c8508e3664e" - -typical@^2.6.0, typical@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/typical/-/typical-2.6.1.tgz#5c080e5d661cbbe38259d2e70a3c7253e873881d" - -ultron@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" - -underscore@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961" - -union-value@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^2.0.1" - -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - -unorm@^1.3.3: - version "1.6.0" - resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.6.0.tgz#029b289661fba714f1a9af439eb51d9b16c205af" - -unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -uri-js@^4.2.2: - version "4.4.0" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.0.tgz#aa714261de793e8a82347a7bcc9ce74e86f28602" - dependencies: - punycode "^2.1.0" - -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - -url-parse-lax@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" - dependencies: - prepend-http "^1.0.1" - -url-parse-lax@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" - dependencies: - prepend-http "^2.0.0" - -url-set-query@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339" - -url-to-options@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" - -url@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" - dependencies: - punycode "1.3.2" - querystring "0.2.0" - -use@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - -utf-8-validate@^5.0.2: - version "5.0.3" - resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.3.tgz#3b64e418ad2ff829809025fdfef595eab2f03a27" - dependencies: - node-gyp-build "^4.2.0" - -utf8@3.0.0, utf8@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" - -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" - -util.promisify@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.2" - has-symbols "^1.0.1" - object.getownpropertydescriptors "^2.1.0" - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - -uuid@3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" - -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - -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" - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -varint@^5.0.0: - version "5.0.2" - resolved "https://registry.yarnpkg.com/varint/-/varint-5.0.2.tgz#5b47f8a947eb668b848e034dcfa87d0ff8a7f7a4" - -vary@^1, vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -walker@^1.0.7, walker@~1.0.5: - version "1.0.7" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" - dependencies: - makeerror "1.0.x" - -web3-bzz@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.2.11.tgz#41bc19a77444bd5365744596d778b811880f707f" - dependencies: - "@types/node" "^12.12.6" - got "9.6.0" - swarm-js "^0.1.40" - underscore "1.9.1" - -web3-core-helpers@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.2.11.tgz#84c681ed0b942c0203f3b324a245a127e8c67a99" - dependencies: - underscore "1.9.1" - web3-eth-iban "1.2.11" - web3-utils "1.2.11" - -web3-core-method@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.2.11.tgz#f880137d1507a0124912bf052534f168b8d8fbb6" - dependencies: - "@ethersproject/transactions" "^5.0.0-beta.135" - underscore "1.9.1" - web3-core-helpers "1.2.11" - web3-core-promievent "1.2.11" - web3-core-subscriptions "1.2.11" - web3-utils "1.2.11" - -web3-core-promievent@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.2.11.tgz#51fe97ca0ddec2f99bf8c3306a7a8e4b094ea3cf" - dependencies: - eventemitter3 "4.0.4" - -web3-core-requestmanager@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.2.11.tgz#fe6eb603fbaee18530293a91f8cf26d8ae28c45a" - dependencies: - underscore "1.9.1" - web3-core-helpers "1.2.11" - web3-providers-http "1.2.11" - web3-providers-ipc "1.2.11" - web3-providers-ws "1.2.11" - -web3-core-subscriptions@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.2.11.tgz#beca908fbfcb050c16f45f3f0f4c205e8505accd" - dependencies: - eventemitter3 "4.0.4" - underscore "1.9.1" - web3-core-helpers "1.2.11" - -web3-core@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.2.11.tgz#1043cacc1becb80638453cc5b2a14be9050288a7" - dependencies: - "@types/bn.js" "^4.11.5" - "@types/node" "^12.12.6" - bignumber.js "^9.0.0" - web3-core-helpers "1.2.11" - web3-core-method "1.2.11" - web3-core-requestmanager "1.2.11" - web3-utils "1.2.11" - -web3-eth-abi@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.2.11.tgz#a887494e5d447c2926d557a3834edd66e17af9b0" - dependencies: - "@ethersproject/abi" "5.0.0-beta.153" - underscore "1.9.1" - web3-utils "1.2.11" - -web3-eth-accounts@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.2.11.tgz#a9e3044da442d31903a7ce035a86d8fa33f90520" - dependencies: - crypto-browserify "3.12.0" - eth-lib "0.2.8" - ethereumjs-common "^1.3.2" - ethereumjs-tx "^2.1.1" - scrypt-js "^3.0.1" - underscore "1.9.1" - uuid "3.3.2" - web3-core "1.2.11" - web3-core-helpers "1.2.11" - web3-core-method "1.2.11" - web3-utils "1.2.11" - -web3-eth-contract@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.2.11.tgz#917065902bc27ce89da9a1da26e62ef663663b90" - dependencies: - "@types/bn.js" "^4.11.5" - underscore "1.9.1" - web3-core "1.2.11" - web3-core-helpers "1.2.11" - web3-core-method "1.2.11" - web3-core-promievent "1.2.11" - web3-core-subscriptions "1.2.11" - web3-eth-abi "1.2.11" - web3-utils "1.2.11" - -web3-eth-ens@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.2.11.tgz#26d4d7f16d6cbcfff918e39832b939edc3162532" - dependencies: - content-hash "^2.5.2" - eth-ens-namehash "2.0.8" - underscore "1.9.1" - web3-core "1.2.11" - web3-core-helpers "1.2.11" - web3-core-promievent "1.2.11" - web3-eth-abi "1.2.11" - web3-eth-contract "1.2.11" - web3-utils "1.2.11" - -web3-eth-iban@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.2.11.tgz#f5f73298305bc7392e2f188bf38a7362b42144ef" - dependencies: - bn.js "^4.11.9" - web3-utils "1.2.11" - -web3-eth-personal@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.2.11.tgz#a38b3942a1d87a62070ce0622a941553c3d5aa70" - dependencies: - "@types/node" "^12.12.6" - web3-core "1.2.11" - web3-core-helpers "1.2.11" - web3-core-method "1.2.11" - web3-net "1.2.11" - web3-utils "1.2.11" - -web3-eth@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.2.11.tgz#4c81fcb6285b8caf544058fba3ae802968fdc793" - dependencies: - underscore "1.9.1" - web3-core "1.2.11" - web3-core-helpers "1.2.11" - web3-core-method "1.2.11" - web3-core-subscriptions "1.2.11" - web3-eth-abi "1.2.11" - web3-eth-accounts "1.2.11" - web3-eth-contract "1.2.11" - web3-eth-ens "1.2.11" - web3-eth-iban "1.2.11" - web3-eth-personal "1.2.11" - web3-net "1.2.11" - web3-utils "1.2.11" - -web3-net@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.2.11.tgz#eda68ef25e5cdb64c96c39085cdb74669aabbe1b" - dependencies: - web3-core "1.2.11" - web3-core-method "1.2.11" - web3-utils "1.2.11" - -web3-provider-engine@14.2.1: - version "14.2.1" - resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-14.2.1.tgz#ef351578797bf170e08d529cb5b02f8751329b95" - dependencies: - async "^2.5.0" - backoff "^2.5.0" - clone "^2.0.0" - cross-fetch "^2.1.0" - eth-block-tracker "^3.0.0" - eth-json-rpc-infura "^3.1.0" - eth-sig-util "^1.4.2" - ethereumjs-block "^1.2.2" - ethereumjs-tx "^1.2.0" - ethereumjs-util "^5.1.5" - ethereumjs-vm "^2.3.4" - json-rpc-error "^2.0.0" - json-stable-stringify "^1.0.1" - promise-to-callback "^1.0.0" - readable-stream "^2.2.9" - request "^2.85.0" - semaphore "^1.0.3" - ws "^5.1.1" - xhr "^2.2.0" - xtend "^4.0.1" - -web3-providers-http@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.2.11.tgz#1cd03442c61670572d40e4dcdf1faff8bd91e7c6" - dependencies: - web3-core-helpers "1.2.11" - xhr2-cookies "1.1.0" - -web3-providers-ipc@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.2.11.tgz#d16d6c9be1be6e0b4f4536c4acc16b0f4f27ef21" - dependencies: - oboe "2.1.4" - underscore "1.9.1" - web3-core-helpers "1.2.11" - -web3-providers-ws@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.2.11.tgz#a1dfd6d9778d840561d9ec13dd453046451a96bb" - dependencies: - eventemitter3 "4.0.4" - underscore "1.9.1" - web3-core-helpers "1.2.11" - websocket "^1.0.31" - -web3-shh@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.2.11.tgz#f5d086f9621c9a47e98d438010385b5f059fd88f" - dependencies: - web3-core "1.2.11" - web3-core-method "1.2.11" - web3-core-subscriptions "1.2.11" - web3-net "1.2.11" - -web3-utils@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.2.11.tgz#af1942aead3fb166ae851a985bed8ef2c2d95a82" - dependencies: - bn.js "^4.11.9" - eth-lib "0.2.8" - ethereum-bloom-filters "^1.0.6" - ethjs-unit "0.1.6" - number-to-bn "1.7.0" - randombytes "^2.1.0" - underscore "1.9.1" - utf8 "3.0.0" - -web3-utils@^1.0.0-beta.31: - version "1.3.1" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.3.1.tgz#9aa880dd8c9463fe5c099107889f86a085370c2e" - dependencies: - bn.js "^4.11.9" - eth-lib "0.2.8" - ethereum-bloom-filters "^1.0.6" - ethjs-unit "0.1.6" - number-to-bn "1.7.0" - randombytes "^2.1.0" - underscore "1.9.1" - utf8 "3.0.0" - -web3@1.2.11: - version "1.2.11" - resolved "https://registry.yarnpkg.com/web3/-/web3-1.2.11.tgz#50f458b2e8b11aa37302071c170ed61cff332975" - 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" - -websocket@1.0.32: - version "1.0.32" - resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.32.tgz#1f16ddab3a21a2d929dec1687ab21cfdc6d3dbb1" - dependencies: - bufferutil "^4.0.1" - debug "^2.2.0" - es5-ext "^0.10.50" - typedarray-to-buffer "^3.1.5" - utf-8-validate "^5.0.2" - yaeti "^0.0.6" - -websocket@^1.0.31: - version "1.0.33" - resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.33.tgz#407f763fc58e74a3fa41ca3ae5d78d3f5e3b82a5" - dependencies: - bufferutil "^4.0.1" - debug "^2.2.0" - es5-ext "^0.10.50" - typedarray-to-buffer "^3.1.5" - utf-8-validate "^5.0.2" - yaeti "^0.0.6" - -whatwg-fetch@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" - -which-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - -which@1.3.1, which@^1.2.9: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - 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" - dependencies: - string-width "^1.0.2 || 2" - -window-size@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" - -word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - 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" - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - -write@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" - dependencies: - mkdirp "^0.5.1" - -ws@7.2.3: - version "7.2.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.3.tgz#a5411e1fb04d5ed0efee76d26d5c46d830c39b46" - -ws@^3.0.0: - version "3.3.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" - dependencies: - async-limiter "~1.0.0" - safe-buffer "~5.1.0" - ultron "~1.1.0" - -ws@^5.1.1: - version "5.2.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" - dependencies: - async-limiter "~1.0.0" - -ws@^7.4.6: - version "7.5.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.6.tgz#e59fc509fb15ddfb65487ee9765c5a51dec5fe7b" - integrity sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA== - -xhr-request-promise@^0.1.2: - version "0.1.3" - resolved "https://registry.yarnpkg.com/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz#2d5f4b16d8c6c893be97f1a62b0ed4cf3ca5f96c" - dependencies: - xhr-request "^1.1.0" - -xhr-request@^1.0.1, xhr-request@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/xhr-request/-/xhr-request-1.1.0.tgz#f4a7c1868b9f198723444d82dcae317643f2e2ed" - dependencies: - buffer-to-arraybuffer "^0.0.5" - object-assign "^4.1.1" - query-string "^5.0.1" - simple-get "^2.7.0" - timed-out "^4.0.1" - url-set-query "^1.0.0" - xhr "^2.0.4" - -xhr2-cookies@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz#7d77449d0999197f155cb73b23df72505ed89d48" - dependencies: - cookiejar "^2.1.1" - -xhr@^2.0.4, xhr@^2.2.0, xhr@^2.3.3: - version "2.6.0" - resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.6.0.tgz#b69d4395e792b4173d6b7df077f0fc5e4e2b249d" - dependencies: - global "~4.4.0" - is-function "^1.0.1" - parse-headers "^2.0.0" - xtend "^4.0.0" - -xtend@^4.0.0, xtend@^4.0.1, xtend@^4.0.2, xtend@~4.0.0, xtend@~4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - -xtend@~2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b" - dependencies: - object-keys "~0.4.0" - -y18n@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" - -y18n@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" - -y18n@^5.0.5: - version "5.0.5" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.5.tgz#8769ec08d03b1ea2df2500acef561743bbb9ab18" - -yaeti@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" - -yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - -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" - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-parser@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4" - dependencies: - camelcase "^3.0.0" - lodash.assign "^4.0.6" - -yargs-parser@^20.2.2: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - -yargs-unparser@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.6.0.tgz#ef25c2c769ff6bd09e4b0f9d7c605fb27846ea9f" - dependencies: - flat "^4.1.0" - lodash "^4.17.15" - yargs "^13.3.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" - 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.0.3: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yargs@^4.7.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0" - dependencies: - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - lodash.assign "^4.0.3" - os-locale "^1.4.0" - read-pkg-up "^1.0.1" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^1.0.1" - which-module "^1.0.0" - window-size "^0.2.0" - y18n "^3.2.1" - yargs-parser "^2.4.1" - -yn@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"

-$WgL!e-|r8HI7P;KyyEbR%Df-4FgsY{+mL}O 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�CIST&ua(9Xjw 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%0A6&AGu;f$dU?9nRA#3uvai87M1S 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°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 z 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 z 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%0A#m1Wfqh5KMGc@*yd(}U^@Y02nIBgwi@LGs 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�W9Q1bBzskQ`d z)QB4+pzX>R&n-WihEfh`uL(bCi_|ztU2pS^b}G8wVs0VfSZCCW$O7%l=P~f#RtWWs zrB7tR#Y5KdHA_$`^||OJ)l;!6Sts-?lA15{Vwih)<{SD#&N{&GLg*?~LWWg<^98&F ztdqHp>5dImP=FT0zGnuWn^IpTI(x2ay-kA)ktz7Asu)@W5K3@4N{6hM!j9xmrptfOuc+><4zf5v^I$=6A(7!cqn*}G< zF>fIqcKRd}5Dsz{8>=F~UBot~LkbeE-rg!^Q%vXcHg^i#72nyPo+>0Q<|zy(b#;#~ zE1?!Oot-vJ@M36k=5-oTWC+ywocTXup2eu}d2c!Rc*>t)I|a{ROdr>x5SiG+WQ`&X zI_MQM4JzsrG(h4&<7So+`P$1~8RMi!n5<{7*1W@d5~-um!GS$Nu@H)b@x#gDvZ7et zKKArJV4=YsTogru>reO~K${*7n#0*y!g{oNhhDeqW5H&Fiine^rt1oD>nwuUY=GK| z9(!xlB{la{st-2C*zI6*DuKMFQSyiP#IX~TV*_nM$PHX#qG0RDxk$22Kx~Y7=CSZ~;LoV*cN%Mt}QwVW?o_c_SJr;S(q(`k!WAdMTSS)$tA%0L=m zLz)N5p%c3{L6XHh!-Opw(|)W_j*hFJIGhvf039X0Ki&k3*8wP8HBn$7Au;_T#BY(J zf98djFi^bn=4+4@F1uhh-Vg#Ek{s(6z*ZEP5+mYToao4XYOYDaaUp^5`rLHjozY5W~AH!#N(Ez$D7w{&#x{MS%AvY z`NF&sJ_%}(3M0rlp8qivjb}(ifrb5igigz+h$``r{=9Dka|4Erjr3o9aBh+Yb%v?t z#c~M#&A}78W&Tz!vF*V=$vBBRGzwBq`-;3PWLF$h9E7&arA54bKF)Of`P27;Y@L}x z=I>ZryFTp!iM_i{6tdVXQj=KZ6+ehRPde0UIm zrGw6Rag`oAnLdO|)~N5TYzGJvFrNO*?DSlK=$Q-=Y^eCccSf0plEn_@74y%Mi<2WC zIXJ_HgVtm~owMz0a+q0xaS{L4FMglE9^K;c3yJ_iwhVgK>{0NR@5Z&tdeX}3i)(6K zqDoxbNnO-{y^80MfT%oas+*K}U+(X+Jp_+n5G?|Ha+5YRvEvB4h#@^><&9fLPrCRY z`%0q%%3QC;4{j}dB$2hboe|6hbD*;JVerQwBj=zH!oZ%C0hFwB#7==>GZ~bN_<|2w zTZGG^3&cDogZl{(S&3jR49T@@0^vDRj12cJ{kFVN4Sy7Q>;@)Y@ijf^b`9Mi7k6#s zkD0FB-ZY#0j9s&iW@mD`2pd{b01m?SbnAc$f*E2dI#*Kma`LlTC0#}qG|@!dg6#TA zV`!5@%G~AG8?v+WO6dPoKdPxWjw-HH2iaC$Rf!>39=Vt&KBjN%e*PP9a}dRlJWiX1I@F?@rm>#R|>b~wJ&PR+a_ zed3Wx%eMLGJM?aaVXxFqrgJN234FgSF>b>UE_yT8g_oRTym2?> z!5|J5tT9N^0Rro@hckbt3uPq>RxpLbo#{Rcb32^lI$IPi_!G##vK{Oyx_vtD{%UsB z%hp106OF-e;_h!R)yiU_x^!*r2~%s;U|~51$s)Eb_UqzVTt$ zH&M^iyOh@t1?ZmjirqyKSCG2-BsZ;V^X+u0agEo5PTP>3NWeRHg2n9_ReCD1J%Otd zRe2Ms*LY)W-M^ED4eHG}`dXelICQgbBVe1L{8}HIaSjb!CdF>RnZUC(soudhL%3X~ zGZG^0NQ8qr5M*l4I#2cPAtbw@dOCp`$5xTL4on!cSv+c`ndOtMNvA>Twunq{y>||? zk#h7T(z9Rn&=4hmp^R7)^q8x|t&usYNt8?*AS9?_NGGo36D~;);J5@Qy+4MoLHZpDpD^`)UhGX&L!@t)r`Wx6nY`C0oN*iDkr1 z{5pd#`x!mr9}0SlRNPN|hb|hblG4&nUGo(+X4$`7qa4D0rz)(pnNhTtjzQ!iicjm& zS3}GR?F0&HP+TPI@^O3>{g7B|dhxmjr#zc=3{*^hi8F)YJ9eQR>P0}aOlf_YA9Ogo zU~+<50XP+6xqEgQ5Cn?H68SI$hd8=q`FkyTgVOavidWMOIZk-0w=wBw!sUXvOFncq zg0q)fp8z_z*1iw9F0F_vF@NN(yv$#y?9{{SjhaPcuwoX=6yHqS!`lwq;T@&GUHkh^2HF=2_i{z>|1AAzkw(6 z=CR0seE4NN1(S_m=+~6SE})@yn{iLS!-);B8o7~JwO!ye9Dm~$ z82%);TpdS{@VgC^+?h())_-tRu9yk9pl^Nze9z;5k`H&_T z<}WM;_o;b>GiiJ?l*^Z^f*Q$}v#o4eaEujt>Sp4**VLY&H(GVoW=^W@iF=CwX)9l` zdGpmCeMw3hRQkJpFpit28cerq3~OPSGd&(gA=?&yZ)IvBoUqdLGjgXoDqlPruXt2u zZwo;DBO!y5uivD_OO$ubZ0-5024uQs+T3$_YK8f$h#xHYr8uN3k>yl z@uPD0L0$azMY?=V8z#FOXv;30sIFADpiawFn;lqXOk2Cq0NFFr+V0#~6q-u?``oMR zvLx=rOt{tMi?B$D5j^z!83nQUM@hVe5?;U0&^RR2nsf>)Fc0#MdJtArHa4Y&5SyF| zN>$PCl9haxe`7e}Rgk&dN;Cb=>qyKL1&}0Yvp~CtxM>Of2ZI@ApRQ08c2(P%<+^y$ zgbAA6^WsoPp*_iup?0H|$=7JO1bJN#zipqN1K6F33tgNgE@3^IB|)r<$*z^BjJQeo z6QzJRL7tEMjJGS=>6;$a^&R_mjBjDy)+TF?DwnBBX&5d>k%1HXB-2(*KDIJQ+NUgy zXrgag4|{a6aqbO)iSxdR4qcFrfAr@|S%^~;<8qEay9}GU+#66Kz~Kqa_6NB^?3DLazA=fgw3@y+g7C1ynSHK(>2;1lL+st zNJWid;uCeRe%G_=m^=h8lLQ$Aejj#*#@`EK=qP#Y5#&~B*>ze78K85_pZQpn?z)RYw=t7L>8WcMEaX#6(u4+GCf_HTGwMG` z7gmv`aBk~}N)hBT9{s1dwK{dKx7!ct=-q7X?XPu8leV#0wZ#kmUuGk?;+&eDXgirU z%IDbt20$iEXP8}kX)HTj=+E*7^B>fNq`jLl1AOqq8G5`y&kS*i=T z6Xn?hw9x)L4b@s?8PAQsdoS2+R8%taK-@2f9?OhyYXtQAtPWMhG@=;Jv^8k|gRy&P z5{8G`1l+c5+qR#!ZQHhO+qP}nwr$%z@3)znshY+7fNYX1PLey<0aSr4VU!drXYV*O z#oq)i`jByfY<6XRU)XOcLhkjCf@unEuUXWt17nn6Fhlpy#A7%fR*5lP7OQ$^y-nTm!nDf)Bv72UpnWhe8qu3ZuGTw1oz5STmXMy=5W9fatefwe zoa%xj)=Cl$P>bS2(%QN#`lNWX$*GFk57IHt%RSP^#%|wFQj18Sjr0A|g@q%^t&1wU zNyun0au4X~8eIYAWMpF|_VPS18Xw?LTP9((_p4tTpaN!GA2MZuybQG}7ZFYo`;$~0 zN1;0neOk~J*xS(kOkLPkKc@W+@E}%h(xsCrsYZ%F1+8Ev;A2Vh@?qH!**##8}v0Q#Qly5TuEZ6 zmB#KT-*H!nDaU8r9xO2MNWJ zn|sNY#={)r3o;C)H-X~%zQ+4mC=x<^AFsthg*{TEi|)v<+rytNIzjsqCz@z|IbWNX zT+%U=pm9BMNCsyUBw^9Qt#_h!px84MR!YgdW@Tr-jV!`>5h&L~l5?mhNBY#-EVZWZ zux=}+u2q^j$u=4MupEXH3_~^fD`BWvQBg1Uv^I30-}!EQO>f zcnljzfH^%=_#lnbUadWvA-gk6>X?g}C*?I9=+q7Qf(5%j4i>0V#FHFiQ7( zMKh#&{gky;jk@XI*9Y3UdoAL>BbfFJ&j+surywvNr zZ@(YhjDQBe#dsJCZP*2OD2*k}eO;Ec`xRZAbf9IxpN2bn4o8tl#XKj0*_Ns8juK0) zI(PdZPhDg|_Wq=z!Exo@RrL(awga6y2?yt5r(_h^@2I3la^^Q2Yf6>iG@!?RG!tXu z)+yNo8(O4gw(=v>$X1%7i}pVQxtKF?&Hs+v29>)rC=b6l%IEz;S<+7zp6hOKJnV&W z{BOy72$q;XNQ`Xo&tK&J%e^EMK#7+;8~^((Tt*`T_RGi{)A#2+uMhaGmhWUAiCc57H2}KSJ4xWt(hvra)$RYCWev z2}WlQNGXEx`D#fBS|{L4wVbZ_uM3l1xxqPNv5KFaZXNFe<1)bv$H9_Gbr(B*`tcJv zN9B3MRZ-Zf`n9uTF-16mdULB}Un&??(R#?l$a8d5_G0uv!U*J76?7)Xv^{A9jolMn zl$9Y8nh%4YM4gW$pv$^V`ehx+9_zLX2-U89h270P$p{Y6r7|7T!RTzz)hGSjXA&wzx zxJ>q0>?2JHI!o=X4t~{PN)r)gwpd|>>A%&+eI6Fh(2m-3ns+nX#|MBA7UU?RtocR=DNK4D=AHsco9zxx6`|kDXQ! z4oDv_6Im8B?G?Ci78bKIy!v{0ufLp*lzd#nZGlV4z#-6#=+)T`MTcioVz(u<+PRmW zT`6Tk?%1tg>9q^b1nuMP;&-bcC^Oh_k!5Tb%-vJR>JLe-yONyZe@f@Mf#DDeIR79N($;9+$cQN%yA#>m*ap85ELn##txQ-XLTUF2 z8pjg`MNuw*t3no{dhS z?Z|~Q;Kf3zb+iVb&Wv21I(MUy!x@wwBxXo^;v@$8dG_`BKa6n=IL=duKc6+3O`<`% zKdvaBRKmm$4(TYNq1XhxXvx`X}88xEzj07)LaKfG?2%32fe&&$W{h! zv7)39SLa+`x%qZ@Kfi#j`gS%?$Jx){QlK(p!S#!Hu`{AB8L+MfE=75t{L!zRgv5Cg z@+RF54wg)Rc8xfaaUjRwTDRC>+);kMF4*KeG#k{*`>gLp^Ew4Jc5rWhT}x_he}F^c z@$(`(IFwe=LrocMvkY?jP8h@e@^DFdcmpU)V2Z_It@NqO^v?CPDbL{(mAvGnrty?@ zFY#hQZO6Dt$?aA^Vz+MT06VX5*M>Gw-d}B@mkj*yiI#;{Fj`P|2Cv`ZS<<$5f%+_Q zkszcam$9`;G9XbZ)|9FXtg(tg28gOh6Z-5-r+c4C8+&(kCYay_2CPcuH_NQ0!?1S? zvh}j^9$Qh1-U`=CrZEq9fq9uc;c7~k>{s30Mv+kBkD}lw0I`9;kkPmalNc!3ogksf zhl6Uv&?3L$7a;zDBn?Q#{a}ni^;KAE8okK9i?s_6~IvT@^qJ<7o%h z-U(?Iab?Jx75yaMD&vNOOHN8661K6FRu`G2FF9Ji(k>>rk#n-4Rp+V7LnZ!9^*tJhy77+cP zg?@U^152Af1Bx9-R%Zf6Nwa6~5E!QT(q8 z@i7cu=(OW$Vi2df5eoc~A2eXBcJ|9MmSpS|>uwpV2lGKS8W>!jl6o7h z!@i3^$yw9eK|^!Nc> z%_&tZxV|=E|Fr1b3*@q@qrf3{Rx{HO{;#NIj4w6MOe(SjCuw;->2Na<*|;co7;G%9 zFb{cWk=&-nxd}8;giG$lN4G3bFF7oMJb3k7TZT0MQ|eCAi){G~IYGE0OLn_5d>%qD(Y(wXGlf0KX~bGHp^- zo8^lF0uJ8e>@&1-YM7XoESm{d)JGFWeUe#iC3#v`_Y&fYIn2^3^^>{-2o$AE2+LJ1 z)|0}n-+Z?q>0T4~O6XQe$KcIIeWJICvuqsCIEPuY(-ekMqG^B7bwgLHzB=5#?=3+Y zYokaS%r_`_`grWK0dpC3R;tmM!MAi~l?JhP70MfLE!do>aSp_u3@s1w!FQ`r&CM3B z83;w^4#Skou1szw*^_f812f6}Ln@;$l@|G3)Y<~21k=d3Vj1~U zkVkQHZ`j~6*pt(n6igwVpent07(w<_qjODuMKDHlsHDnV`zcp_J_j9P;LeB&CsndCwW;J zo!;;ycsrFE7k(=b$R$++4&GO~1DxPcdPd$$>%a!ir)EVuvT;LH6D-|zA!=5&+01d- zh4P}B&PQ!u$&rxn5gn9#)NGkX&09Zav$Fx_J#vAGX0&>LJ(hl7y!Z&QYWPzTixk9* zxoE#p!uXCAPF^1cWFxiwm>_;qt1f1Trw?_#UV%Pkuinxq?5_dsn;;Q7Ht(+qRnwux zZ<6~?F>n_K`O!(|wHVcl4(p}h&I@NgL-L`@lo+<{bVgNpS63>*$6d4xy;ygFc3OTe zJU!W?u)Mdibg{%9J+QaD5$B^Sis0uPj&7LP9TF==+kjf1p&-L=7p_%yRk~r=w5^2V zj}Dp(=^(6}ZK@>nE?6|GSKcR`)Fm5`kYF6eF6YPj$Sp~$CqfKZO^yl_^QvT{uoEOt zBma-fkv-uhIQ4q<%%g*}?Cuffo~|`mR`uYW(i(b#UfYb;`p@+G>^ZI|@p0GNr%gq4 zR5QQ1nn};)88ZN(Z}~QMHUgIXP?nH_e$GAv8*-qwccUM;jJCo_HavzLmXBNCH`Fc!#mJ9Hz#WfS=n0+Z7Rbzd1GLa~?mE?v!MQ zGuG*;aRy_J&dhVyZzyYlVS`a08|hKDLp?Kk08*2b)nIQ8tf*PS9LEs7r%1;>Ly)9p zc+Oi_-X?W(M!9MM1>(TUwXCNVhYFsHb=y}qlda@&M#WoxSd^#TNe;-=PZGaFFrXbr z2GkXP*=s662S4=lzW&u9vhB8y{y zd!~ZOQ-2q0I!!j)fSmG9aMEdpTWY9ev7H{w3DQ7U$BD(gu;|9o+x4nmy?5LWJuj()LHF9+IQn1EHvCbgG&aVKXy0JSC(O(ZF8 zC-SaHa)_Lsmwd8|+X^3)KH>TvxTU^e%TW2HI;6mk*@QwS*h5c{1Z*0Ym-z*FsIoou z8s6M@i3BO8mnmUzz64rwL;V z!?I4E{z{9%+7s|y4GR4!ZO`MAn-bqz&#fl*q>EM^m-_Wp%8qyy(FR6Nie}LQ@=_5J zD7z=|7mCX`{>6_gij>u0=||KZ7&%3t+Ky9%^f-vN>E#o!SxsfX6YQRk0;aWPSMb*c zxl+%-ZxLJH^5TAoC0+4FVOTxyB}0$2lx}0V#CI4?rwz* z+KGg^#P_gZ5Q)L=h&YddE7n?DWf+;yQ5mk);cBgDW0S7?rMef9J`fWL9=kz%@ z=>`saxqcNk=?WXF9om(Oo(PQ)9G_OwI1)`=jzwYlszG*KnLDf7B z0qPUS9vS=X8x`)o`{lY4M@j`16K>)VoTXiGZtktgq)cpm1D4>iuw@SWLCu|M=EN5j z1R8~)GMt>p8fef`I=CMbd|r0)-E$TQh^Dt|*l!uF@1mv%dc_0C~LjuYbHLv(PKo) z23n%r2zZYt64fu4rlGF=Quylg^=$)gB@-PBU>A^+q7)Fa5<6*ewFGt4pEu{lzeOjM+~ok=zxlFX>6eG((A2h>(q z4hv@?4C9d&+pEoEes$UAF)TKlA6Vn-598E?U>^nB;Tkg)Hrf&mD?^`xPrU;R) zdF@@0=6(fPqQgDN4c~9!tsWRKDCr?RUkueJ;3@j?{i}>F@yzn~tz(w>ouEJViLXLd zgMCHQL7zha3>UnNW&x7Mj1NP40d|`rvNKbm`*unz)_873ac3Z1gQt;hsRCU)E%n*G+2xvMDgGMof=Un>C?Wh=7*E zUXWCgkZvIQ7aYyG%0Ygn!s(0`Uq{KU)M~xa3>+4@`q|AAOOJDLfF?U1ZO~0?2hS$J zZCduG*R>j_tN;RCD1$bAF&Jm08FqJ~xVT9uUL{vRLid1vLw5#I41lx<+{KbAH0}Xv zSq53!eQ3AoabyF8r8~F%@@oL^*Bob-fIqPr?Pa1fF4ZMb*{Q zn6GLZ7hbK5dxVa05-!BnpUZ)lPe3`5g1joloi7OAS=DjuEGDiH5wj?o7V-5!MdVkL zokL{vGJvv-=lJQgd4x6LXQ^8v*F*)!Y6Gs@KGi!4szIWu=yHkJidu<}c(p)SZjT9V zqAfUT>TgfwxXeUWniP`$X#eP{vHNe+zDXW@8p>9a+jnnx0v2vzv^PNa2F^UjgS5Zc z39>tp$bG5l?+|L!Tfa>Z>OK<tvI7{5ePyx+_U5Z~C@+^r`o2DKgR?|Ml9 zDr-hhnz6EzdXQ1tYq5O=5zgIgDhT+2-ImA5gqD3r7bvplPhRzs{>W5V(mXxtwN1>a z_+*)H15vxY<->!vTg27x)-o59hP;`VQdc|`-?^;!li?~1MKhHj=-3#M0 z#Zfz=Q8VJ;&U?bX>w3Uo5SdmYM3EvRtS)RX@Tmbx*@xjzRvUl^ecyPl44Rfxg#~m| z%>*94F;kZdf(bZL(*-s00HVdo@vmg?DS}0kOrw$@Cg4p`lbwYpo29W6VFA$ZkpOIJ z`Tz^zmR=Y>>GuG0R)2!{`Jrej;o}I2F^L5uX6wX_Ux9Fmlw?S?V#wa;xh!J?rbpi2 z$T)u!JJ_H%z7I#k2mX-JZv-s~E!yEm@4s5slUS<5C_B})p2g4o*<$L5={9ijc`ff~<0fHx!>aqpgr%V=kUM}G z`#6sP(3oEUa-ok5Sz2pW!@1=?^bg*okUg8(>!z~{`)7c;UT)@0j(1((j0ld6un=6y zebBsz`usM3qi>bWMvAD1n%<{l5L@$Znh&JEubAW*c*%@G-Jk4aji34L=4;vRoc8nr zPG8`uUk6knt=OZ3NL4ScCsdbdr);i!cm>r+&DoGA-rmLp7($yD&ry>=JVkh->@sCF zHAd*`eQ{l6p^mOtB5z+H;Eur=rW|tNaq1OZt4PDUxAUt$orVw9b|F)~%k7NzWn0r7pe~xSceWsbC<$z| z4;?29EUU;q+%i1LQ2E?WEYO;z6Eiq^uoPuVc5a#)HJT1elJLGsCVV*hgra1dpw71Q z3?>SL@cH|Z;cN&Q#5;d+0U+j)a(Z$6cL~*w%fNIez3@C*oUHIU#(}xd(Qmb01vZZ{ zq_+q2vqvR^hYFmtfwgSrmZe^{?^;u2%Tf0_aSxh{tt+e-g+}!A8I+}S+sI+%k4?hs zajA8&J!lTgN?&9zV-M*uJ({gHvB+5$@&jD^Tpd#nB}jvU8x5gK_HD$`JoDzw7w9ec z3*z}Jb6O*k?KVLm8v1OGuO>@POz7h1u>jg<6#99WseP#4KhDS<#@maYRXlg%ex`hGarsPGDM z!sDJ_u)a(H1vO8*30m;tpRD+XAh6BB!HMO$vRqZ)fO)eP!;%Fq(LqH}>d+2HOSh?9 z+}8&XGT{vvL2pD4@dPxW(e>^_e?VJ@l?Tz(f-LEP@PqafM=52S0*c{Qz5#;mkHO~n zNPGt+2O6{t!tNpJc=k3=D1HmcwwS={_F`=54cX#yRBy+JIa`EdhSd=vM<=ic$hgf6 zaAeNr)ocb&EeHD{-`4pCN>RPdVLXQ_^wqKxCgOL3=A|(NgQggku`INLI~OFSs>6K` zc&?U6@PSH%OtFP|F96<~Rcfz!^qQ>oQ~X@Z032ubhlF#8?`Tg#u;_%Ls`jbWIJ~A7 zaSx)x2h{P%L!9?dAfTw-XdF0|br)vz3Gd-Y+Y5gpow!a)7Wgov`x+c2cZ(C_5r z?YO>>f6aQarEwAU?=riJxyMVREWA?t0Oy^UE{`32|D^c=g39BpgApDq4s&B)5BNXZ z@=c9@KIm4e9V=?R!HotZndOMChz(UvV7q9jA8eQ^@uo54SQKdG>XXgPLL_L?$Vb@Za(=FH=Ty`B(ijrl=r_O#}Ut4 zAf!8IZEDhao%;?SA|p6F#g{|W!@N@1`E-7jgI-@o+I|ZeLeQ%rjY5cG5TU{NN?51` zl)N^c$UT#Pdn*gM%i1{XJX!MxYC2cPhEz=e!G*>;-6d?1(|UcKu?!Y{`e2}OYMy_z>N2UGu)SZk9A zo*nI+&FDg{5>)Y2)h!-&!)hR*XZ*Ibp|)WbH#YU0-bJTYN30!Hy8MdwLmL*--p80F9lir#~7_(jKMgY-R5@l zTnwcy78*HYVDUiI`s%BOB@K~I%`SOy>u-&1T874;7UU>Sr2*YO z{|Vf3ilM}u8e=1FdK+05-*&Xlx>r8w=PM)~!jPs#&b3}ca8->|Y@Xu$L=`e@8wu+ltxOGWXrIC{H6fc@ z1H|~wumpcmJvnWQ&+v>WZa*p1zCSCoMR^)L&xVCzhQ#AdX>fjMufQcaO{&U9{y>4x z>B$p|hr~eqkKD9ppKQeqIe6PBJnKWy1qg@TR%)0<6dA@1XXk3{FfLL(4xYSc=gogh zU5K{ ztsvt_tI8+o#~qGp<+dV_mYBakb@7q3_AeYF?nfUbQh8!M_LBGseS}TVvTa`Cx<$#> zU{5eartRw;C5jCKuZHl-SK`t*@B0l+bbU!g9z@^BYoY-{|_g1^QGXBT^e6^gQIS4z&JzSvJw-5ofG+X2*nvq7PK@pwG z7qXGi(Ef!)v?0W4`}b!`tusC642PIKSG3n;Ks2Yfb@#h8tCL;-aB*kE{K*)b4H$rJ-B9i4{)wjOCfJ&wk|4@F?;6n=S9h1&b61 z`#GuNytr#m&e=ie@n7($)Ka#CKAElJk*`rs7xO5oU*a%ZqH$M2(zDgbK}$3coPu8b z1jRgC2#nRGA~C~h*|RYQPK^45ZkEJBSt<4;XmoCW>}xji`_lYRlK=aYcw5&HE~>K3 z)&R*dwqxmtmm$17M3hWR6nk~`zdT2%7rIWoQzrVa(3KU)GN838nF$(LX05-A_MgZj zW^MC{okWPEA+MuKACc6%PZ#_tQ=vG&A?d*?I*DEKjt488@n4-%9!4}>HAou6am&Y0u43y;_sz$9G zPi~i~{DO;&`gWyWQI|#9;rEV|Y@N}qhG|U_w^(3hD7uOCV2g9Oi>$0Kor4ZscJ2|CSq>IsOm1k(Ghr ze?yM{m)yw8#_(T+ix0}l+0n$n2Fg9#x*gcQR0oX}tISBtZn=T$cHMQc;pRBzKe=(C z;eYtXBVXpHxo;P{9nVW;n^j$}9G#bCzT@G-R<_tlTh~!(XX)qYK0wJrNlWSI=x6{@ zPg8YAN5cGu-lC40nEKwL2Rr}D21J30b-4a#==-RI1jtkz0%NN)Fcx-JClGlo#h)#R zccT(JV_O?Ikne_;Mi(}A7GQgBZtf>;ZjJ@u9QTVq2}LG0Fpf-2VCm_aXh0#y$4jI} zLjXxe4OIX1h8RZqJt%@ZV|^1_i1`1;wmLAB0;R750jmBf0ED)(iJtxq{*T`Xz&1N7 zFy`l<0bo-D$V4;=ROr|^34lllW8KVfWauJ+$5ZcYEAKN9Mn zKMAnEq~9~p&R?;@FcU){j0|ipAed;G85@1f-;u1~mCwORXk7e{MBC@ zHP+ubm7l74zs5gG(D$>*7;BsA?O(Y8zt2xMPB0BjPE<~d%s-joz8xaA&{ok?wo(An zF~9K@aIBxXd%L#o-VeXgi$3{ZZe4)VzpANoZlD<*z|839zfAN|KcByp=0CgS{QR0K z@Ev+nRRCOOW^Dh6qzuISxra}`0aj-qpcosRKOf+~=SRJty(AOsYfEd0u1;gCaa8k! zMHKB*T15sWI0KsAuy2qW;KSpcF|E2)$P2Ezdi`(|YeY0}L z)@t}>Y~x2$-o#nEnWm`ui8J9I_b(`aQ$|rxDeaOXhjSk zlXF=2m&T?qkH$X3=l>K|@?~T%LLVVRNbqt_WflGNhAz+rl6Dld_-RJk)2wETJDht0dm9)&+80X7NPYd}pTG%9|9~PJ zw@`%UIHaJBZ;744xJMPdqzISI2ZiEDKH<0IKW4TS-fKo08`ee{!k1f#1#(G1o#TtT zfxo`v{K#=!YP|!bEX8dk6(Rm6Ro;u1qRi@tH#RPMm7b8ficxdm$^-z;lCsjce!6$T z%%FohCDuD`ChCxQG6B!>nn#!$9PEKIG0lo|;;fRjiA;2c94_LnJ1_5wxQ-k`XqbJK zzw`NgHieq|@2NQIM`EYcd`ru3pLjMHoBxyD*>7|K`?}dZ^g08h1Bmh8Tn;;#cAPZ! zwBp!}SINH!+tI!3e^q4!UxZR7GJ=*~>FZuiTfE9WiL? zdY!Ux0yd3|4r>n#XvK%sRO&R2KU{>c!L}T*auMiy<5RYYpxrz)(Uz?TJIw;@3)V-y z&i#Nm-H8@<$HVmYdl)(aEAOw;JqSN6oW{l1|LN57g$2Pxcp-v~v3UvB_WB;rn-EK!O%9GO1Z>{W#+F2V;_u?jmF z^&}n;B3RN3uWKMtzHvhuAWr}_3hHZ^yHH@IChNXWZ4QgzJ@<3Hqb#PTNbKP$B|y9- z(6P!{?CS_k?871nt>L!|ctG_|W1nsI!T1BH3qB{jc?no5 z9rV1C|0NuztKsiVPcdeslp;DDK6Yyhhf%jmH9k>qN6$<~9*q}wqwWWv^m*Mex|%@K z=-`YuMh6@Cu!CE?jm4Kte~(U>K;@G}Yk7X~ekx@GOP13kwre-CaB8d*^gRHnpmaqO zrJ+?-^ZQN{H%vQ`ydmU3z4G35aN6(oF5OTGGd?`mx7bRFv6a85hcKw!LQ8`VBK~2+ zztM3*PQ%2ve0cvyUXif4ttk3Zf38&Vh$?Oewt^t*|4Y}{$bmkuG`5Lq=jnoC@t>&5 ze5jZYkeS$vm6}P-(Kos>W;UxiDB0vyK)YyJR_q}-mHd2dvkNxgPonlT|G6=MzCQ-i zIyHkiNtogqYgbo=Ux?!GnKsVH)Q{i6M*3@qoE=TEw&@eoOYt$zVm*!V#7c)8F-$G7=me8A?8a_+xt>!su@|4=Na!|h3XhAwS2_3KkgaIs zAZ9Fz;6hQ%6EyheRQ2lP&-hre2OH&+PhO4uA+g3yE$VszeGBf7?;_?exNKr)T_@U) z9Cs0V3_CIq*t_4MgaYPK8Y_t5Uv-+Cw~gF>q0|u2#Eo=L$dlpd?<`83(RNytnWzQP z5SOB@WbltHXzHjPKa6RYh0~n8N`r**P8AI@(3O6DiXN9+F@pKt(u^Ea)d)6=KjvnQ zWbhX-JLWxsT)NNF=f}7U1G$T@dJ7{ZNEvV_-S`2$>7POpE1+tl7+S+mx-xOO5Xc4u zG?pf16?~u(FJ_wD;$2Xw%uQ3rxKFVbl(a;tajo{{_+Hr85|X?MW}5W|%v+Zm@CZ5o zcdWWOk?o_hzr=zsS_I(x;tLW*Ayp zDXM+z+ppUgBIiX^*;tg;9EMZngckuEUBC2SayMR%IJcP7a>}3g#%$r{X-_fxUsd*m z+1p_{kMM36b{7(MMmN_0sPNFDYiEzu8k>jp;m`ahah0bi=UO^uCQDq>!p{^%i}1Sh zhqlQTc&5=A`5mMyzv1lc-qt$A8L+lu6M3CKcj87{rRBG^yW=xI!*M zGK*P>AhG$muJy4aJ@2QUWV!KB7`>)G51!XAFl!K*;n|(W?}FFLVs9a4 z)=W5r4jlTxfb0te$4xvo_E)0ZKpM5fa9XF42&?y#_Yqmbu)qkLNe=K0%2 z^sD)H@35X%ek_Rp!voOrJTYD@*z*r|^O;!Ps1iMXckNYCeu3X-SinNwzdE*|IJEh=V7*DRy$`qUq;TI zI^Fy#Y375MojRO|U!ZUe4qx6%m_KrWL>r6_0Qm%lB}LZU6Yl9y_@>;7uxHx1O7qO7yQ})oE>>(Xo)0MOOIqOWU`wY;Bl7{j}| zm-WB7?N>L7vLr^jFBEsCEHH@t3pTap@x&~rfe}_mubsURyLvzPJ-NeSu#Bk;!60KO zkE5Xn+gV5dc{0Pe0>y&i)Q?6}t3DR3m~1EQl!@jLFm|Uwj^h@4tf}ZTfYzq;JDq{8 zz-LnieH%z)MNp;Be76sXZrXTAc&#-YT4i5Cj3>GR%%fg6^(RIjcHmf7t~&ya&U`%& zb7j8+&kXAKEHoawKzl`%dKS5AYK4mzO^rbNVh}??&P62>{&5#Em{P|$w+sD@h?k4-%`5J+{lv5BWYeP zsg+>wyycLsjs|#0HFc+*;T4Kg=aS_B1fr2N@VM1tw)K)d> z9Im|Yz46=Pxd_XI1bbB)r0jm<5H-*TWN)DHN~JYhua?BOOy< z2rB&9qJYu6f@G#NS6iQC#-u$03~%V6M%*oOlW6Yub)zHV`mUEOeEX>-tsu{5r})F5 z@WY-xaqHcPz-=4PV>NU(8C4X8FT-LB_#7{y;FEXoya8jK!yuUU+mUN%l+*;U@qZ0Pk6U{}s zOs5;O<+;(XjNywC>B7p&NIueUTOV&xitZt-<7f&-{u|xZriw;{1)h@6?I$g)r)q6= z0P6CTzUprG`EFJfxatocG*J*9)pA74oF5BEhF^rq#<~G>$Itm>* zmALGjlfa$6?%Om`f2V1Gob}9lqs(KxA9q;9j+Da7d*+Kt;6c)uDk>Mh2fZDFsTn0O z5dB2tdSrlUpl$B7d+(}VNrn_{3Q>j(4S*xS_$Uo3%NDbmDeFGtuGSUCVtdUYWW_G9 zL&LHcAOdW?A|m7HB&xh8!;2KeVhW{ORi2qO{!F!VPU>ivWVhoa<59X)7Qi7ZgGzEp zqP+F9nn9XIMBQQ4qQuNrzfTZs9bvrT{wt6=2zEIoK8g zjm9aVnUretlqVRTV$Zg|t3h)og-C~i%&6SU&s)7GIBUQM?XObjjyITeDtX^Eph>k5 zZ?#$8R#xa*B#C7)z4oB`cE?GgONrdlPsgVl82VfDnqo`8M}y9WM0krQM=&)F$J@~h zk>7)2m3!;2XLc0>Jd}Kto^8LiyMHj?{;PplfDO~T6ZqR#5y``lyd1Ucf9?}s`G$3M zSH+P1fq+TgB^w)%snnA+%5_Uu4~6SM<5ZPEWi78nrQ{+kn9SJsG3itAEv(Z}x|{KY zke-P5oyLL`?(@yYh{PMfDM7mmeWHPi(Bhq{+~zT>N-M*Xu8l9ig$k*?_|<9qrsmyE zsjd;Ly#~cK?uqmarVXP0NEU`0e=)BgO{<}hGw7&I2gY&p`Y3gkO;yXm9>WVXZ8;=d zTHbppgPm^>_{o1?S|92JuV&cEH>0`q`#*8bI$5fYBdpbD-Y1u?@uf6%qCz;iy|K78 zBxOzjTns*WEq@jeVLBNy7g+@OsgVu*CYddJHjt=LFa&{xPo*v?Cjz<-<`8a+BAwv~ zi3~MX3~V3^gYy7I&)p00vbdv9F{|yw$39iaZ$y~q=-3>4GHEG#CbIE(c%dpvXZC*V zw?;uyyUZpL3DKe+2)OL@6uS#vTIcV7SYz5lD&^=c9JT7s-CBp#r}v_!;h4|33w+Y5 zo2!y$gVI4Rhc$2ShcI#|C|kMBSJBZeey~4^r))qiB4IRcx$Ek=@1t z7PSNyOE_60)xs!F&@*twE`GVzu*+VTujm~xx;5cpwRCT6ycT|d6{GrGu=0f_sNx-QoyGq(D^;G~? zWzOr1JN?I7F>w<36zO$lrKio|8Sx{m0FSC?%b;QeJ-d-{&Tt!0yt7Wn>W=Hh3JJYJXY)`xthtGg=}h9dJPcpwzlvV* z7{TPZ;J5o*Z!Mkia1Dn3v#U&uP-V{NI2Ew&LPQC*Fd8TMWy_KP_$GDX@oE%_k;;E|WA|N_E2;PqL>?w%O3-<4? zR84NW$^m1VVnG^K;T7Y-<=9d9!PBIlSmVYq_u`N5>6vNN8rbW~Xq&eS zUb--DP2eQko(47*I1e%Wn_MInLLo{fISMdPHH;08*~*5SI0lI&T#HK+SHd?JA> z!c5O&=DMYs=C)!ipTdQt%BmDemmK6?;AxQW?6hwnpn)nURvu?_9!_Ulvd(5kz})>W z%=`YrUvAeSP}x;#8-aeJ^}(pqb!mKNq=7$R6C1u3E<6Gg>;dI`rM7CEO6Y_zaPR>M zdm~qvzh1`8cga9abj*b1>qEMeP1fs`;w~0eDWY-L8o^})e$q)_)flo;)d_d-p?Ktw z*41Y`k!Ga^2QaXqY)ydSm7SDY3}aR3XK?H{vfhB6GL%#O`~sLN3q9r; zJOV$NX<3R%(^|_g0W3eR5vqHvI?*SOY55><7!oMUnLj4-Kt5i$) zj4A>xOb7fi^AIq&A-ppRjY-enHq-UQ8+XQhMzBB^{Nk`xLHKR7MeOsW>Kv}91Q1dQ zdJcq`0vsT_9$BvaZd7w&MGRTTc_R?tNy{C!CFL=5a>X#$r-E-Ovq*`deS;){7Ud$J z?{~YW&QT7l>@&hFA-P)D8G6>-ec~J=*UZ5$r7M)){{lxqxWCG0-}UFZshypK z$YC4X5h=@>Ck}aQ=+^Nwf=&t5MX&UQS`8M=`aK*Tt84Jh`z{2+;cwOwKIl^ zo$9fYL9sjPY%h(5iulMLeU3=WDkl-#5K~2f!E<;*%ZacJbs>pjD8nDneq!dKRs1ig z91ezF40!wYDxul=`a%E!r=wW7<}a!O(q@R@co5krO+ql6jq)IqnlNuIJaVw5fKIT3 zxon6qY{a4yst6mdpz}BxMq2Y%hnx^BqWo%21j2@<=jjF*ZH4&|Vm86vTZ>ZbZE)PN zJf8eYc#(PWyd(TVZ51ETI9NoeOr@r}3~p||P*&_&X871$tzZbRZf%@`P|R9(Q- zpVN2C1g3q2yCX%D&>8pjDeBmmKa5kg46R#q$kGQ%mT(BX_8!G8!-2ll+<5*A>UPEH zR`oIfh?#}ESN4<>e8&%i#A%L$a?^;?+!#MBxmSIB6g1*H_w;uSyRWFvKg$RGD}_{gd%Z@?f5v z8Pgf~Q*#@H?-cQh_5HYrpHBtb7HDnlu~=agt1!c8=Kjm*W3fG}NIjb~kBzvelZu{?8@FNu%=_VxJ9EfndPhptu+spk~?OB;x2yTN^X4kcc3+Xv<=@66iTAQoE4}rNud5P`qE4QiPN(z!?j5k(nwNJ z+fp3|`WxxBYyMQ7;3BPYJBaYj()WGViIBoNC`EOE_LZ<2If@_c!*T%rYU5t-@ir9L zI@$-6I9yYl7?f6Lx8SHt&y~KEHkzcW(y;?6{&C6^lJhq2;lPH^Q`7ShE>5+s=odXo z_Z$5rdqa@Jl0nJ6ZyZ=uo7GmSCzE02Xo=oaltY1oRP^Wy_*@6v|ND)^&FM!#pQNTd zjvv`_6}%oXqp)=1h9ZJ`N@%HVY;x{>CY3w#u8!swR6A*l-;+n6<)#FDzjw(aIfUTJ z>7v0Xj0nH9I#2&!dvOn`gxAxf&m9j;I{csj&rQZqnGO2Ir=8e`NKJx35N3e9V9149 z--NXR=TXug1_P$`IQM~qzWF=6*?#4+ES5U)U76>>(TzqkXoo+r*p@W+8)}ey-q|ZYM_N93FJJUo&xf0{X+WStUjn?(t=|H4 zf@gzQ&l%sAUmW0MXMpC1rjc=>Myy^!}jLg4dvaPs3DOqXYgj>){zek#vsUl+4nN&4xAAvIme0?MJMDd$KXID^WAU{#gf8u=#{#WJxpt01#)a$Es9*c$tfrL! z^Y{q-O+Q7oO<_Of=^o$kVJzPjEQ2mcY017f<0%lHb3rD96eB8o=oOtY z3F)$m{2*`(vkrE1xEZl8{+V?OX}saE4f>zYiDj8lSnQA?v%7xF*TfeTY;4?*lVS2$5V84mEG?ImUugBPx|{Bxrrs6@n*=2qwG63T;5%^UAY!-mBYjUmMs7A-yK3rn;jv^tQh~_lda|!7WDDUc2gxl3N#TeH86=B&_?iASsP;QrcT`xwgYSQigEn z9>&`E3rNKRT+vTmDi+pWx+5BPN=X$@{cP6?Kd-2*ZEgDHOAlaa8fS>}5vmOs{R(n9 zeXIDuj>s2K@JOd;o59MlbaUiPiT|%BQb>_t7EYSR`vdA=9VBUv$_PK5cVy& zw0L7R@%Y1Ln-P&kTDRBYWR-jFsnki#P&z95qN%~Dx=k@{B6T!uKiO8JQJkmjh%NaU zHGL*Y3~Fa)s_YK=$pBBl-3fZAq4(mDptLm-y4%vE&uSrU z1gq1R7PDUN)OS&4De=$BA|HzY%OAlJA5ib}TL#osAkzmB9VQ{odo+B>uj^SCs;Am9 zwuw4+$7Mu-aK7bCo7YE!C#v4V1_dpQj=ZRE?iPsbD(O5-Zs*8rD}V z&!d!4+HcsNhcg~;;oWm6cnZm>Ku(G|r1!HorTB4tMrCbm{NNC!-&(7*k~~!qdN_KW z*bN(2gf{0h3qNd5?VIUoajqi2afaaZZyPW~^?!;_jU-bk2<0oPg{t^iaVS3B;Dm=| z1x!9}z@hy9z@t_k=?#U&0(s{sK5Oa@HDs#=c{Bme&mrR`#()G%L#r1Ph`H%aqCxrI zpZ@M7V2p$=J$iT<@SbOx8f!2~GP+0?C8-~Q#n82ctBDBSKRcoC4SLI=2N@>(bzHL3 zTY736gwsmQ9{4mE+(zkIVS;Z^%_Co5Ei~D(x z-?i_s9W_v_Y{I@ad$RTtekd=KGpbRFRuswj%Bt`bftfX>{2OXJiSs^$7zMokIjKB< z)N;-)olH};=+Q6)ZJs>MoBibWBvwMsP8zy+5Z>hqlwhzSe(7vY>$1QUVtf63Jr6rn z>#ByVPP3#I5=rlp9?Ix2JGkKvWTmHXLOyKLB}_#%Y=kGB(+>G2Sc7b-%Uv$hDbA+w zXrPmX-0r_*E-noj4KQ%mX;Z4ETR`cG7F?(Wo49GZ4VrfvH~6~L{lU}vvj;YPNG{?F zy`7nISJu3Y1mru_^X6fkq*MFq_cW^qMJ$V7p*%F?`tb(I)UT?#M?(VkmM){1i#*Cd z;im-W(tJS~S+ZF+9vP{4ZyrVDP>9hSBWfa(Fwat^8R-I9Ir)zJf+9qS%9}Y8yuza# z=r3Otp!Nd+l%@-Oay+o#cPQvUT$=Bhb`Z4`cXl{=HcqiF{cH49T55=dFZ6`Z;vnns znX6v$Z}Gt2fvWaA3Qzn9t3ovJhf+xQf`{O7*^&Tkrf2+G!!XWtmOp!OTt;ThEBjAD zHXHhTtod-zbO*J~YVQL&VHd>adF99cdD0BGyuQdNiCGLzZl9FxuUi7j?(g@d(zfNs!p@cLrN~SG)#$U2LuTMT#mz*gCLgDI|Qm>NWHs15Mnhrw>8-SvctCS+=dbx zo1bFkoQ`W&RyPPJY?dfDod(=$?84$&)NKfFy_TPG9iJV14niw&bD9 z;=b;*;*UIgEqir-1=kohR;3nJKXXlh$LXpE9AvD^<*{H^lCmoqCH^c^$`3)}Wj(2I zsjQoq?CVGF%}J+TDDezZo)dBEI|0_tp33~rZXgX@uXAQ@=~BH9p&MImZpo!Q1&-4hTs8^<(L7g{xJqrz<;Vtcp?eKQgArAVGa7c7@xs+QEn zaP}q& zH5Gu$xNIvG!G=adzeZ-o)?tuB&#%N6CMpa+Yuq>ooa}9arW2+)*}KTMMAtY?<6148 zk2vpuEl6rTzGX6 z+8%t2=qJOVOz-8!7vzcr+z+p?El+&v*PEC5g~$L(W{ZdYH@j6dS}c5|+~3bt4Z0eSlru2bdXiSI{~vWtl>=W)cq` z!inLz*bZ<^rK-E3Uc-8%(NvRJ;2rz|M}d36YsDRK;nI^Riqj#W@;^yNe*XP=e)m&^ znE#_WuZ)4}S6~f!dqXm_ilbfy@bqUlSrYn;+9dS-J2y4i@=)aEW~%HX{PP`t}gOwcM%gnJBJ&fYB97lJJDC&Jv7zb6HbB~?u?IqP)B3*l^%|7e*Q2dIP=+neMiY>LtVU=(on&cMKr}jt;xKq6LwdxScHdTxSKz1 zU?~{A%&CBYtMXzW_H%k@$PjTu4Mc!tiTlC2vitu3voy+*(-z5QsKrUWAfiL=Ps)am zJM)^ZUt_MEz_vnb_FEHK;nuTeuN_}~Fr6|an-Dt<(yK&SiA3THp{~b=7NnO=t%U+J z_%r8=w9-B=a6>5%nHKPs4Bry|2^nK?QM6ui2l0v#F$}NcUM7AG} zxoh1cXditApE|Als)W zXNsTO@eZ@&%ROKH7`8s#_cH!p+#DV7R%qW)G zSppb`G(8GMoE;kdja#HZvxD8w%@WoHm?;i~S$A{S=1!$fNvqEk62&tpaX#v1FetAMEJ8Y!PCoM>6(y_vj05x0 z{4;yLPjz~8$(P{UX=wOC7VagG1b7BcPDsCNn!G1AV9Ce;o#sKxfo{aH1c8S zs7PPb*h&-q>?=rtRTR=6LA(u){t6^7?YEE5&bvTs;$Jjms(~Ur8~i>cws;Zr3s?&g zWX%+gsXFmR0EY~Gjj72_A_h&Y(7gWXil9$6eJM!m4<}&+?4ny=TZjeP?%imk#M3gz zE(PV#@Pxq^vGOx=ENfrjvgyMjbDOa%00-H9$%X@ly(w=-jle3amD|HeJRyAIB}d=NM37yS<)eo;hBkaAr>>!R?yOj z9o25?ns2uaTKV5LfzKLwrAo8udT+r?+qr&|K0 zc;92T$vIus#Zuvy;VS>4mPeDub~3vnK6Ei*OP_`0eW;o!m`|yliR)trB?Gl3P-Xly zk;9l5F?U(e3iSZLEb!?}t=?L)kZZp7T1cb6B#T(eEVkO-a|Uo05FCsi_uoogButgN z$FI_2ko%-5SK6~LfUNuq&dP9n);Ns*2zu3N-L;{ob=u?-MUB`GF=Kg_)<9!T9}|TUOU(*p)A8`E72mrjjPWM* zNKUr|K@p(WBPRRh$CNr-qmi=K6(%C^v$tR-935>$_}EAC{oOQc0PU^g&Csk->fWW1-f> z;KE;aBjfR#+l_lCBGMu4=Bm#4J>{N@tEke7b&{QQMVx7g%SLE7BqkEYC(cXryH5!Qg9CmMcF}_a`88Nx*z>Dp z!nq={*G@_Es-st-eCC@t(nBE)K9qSs>sUHC3A6fxwnUe2;oLa+I%kX9mFQqwW{5qB zgF$}{8mFfy2ea8`0NE8&d3u78znR&vBAlbu*b6^amHM>?OubMu|_;|g85jdjs zU$zPg*Niba6`_rghdyT9;QTfU$28tu3ZcQhD2>}EuV4+Y%ekr%sf-;xRS)f1g*%z@ zHai)it}@;T?6BBwh&5#gd|Cw7My2${qGt`3scBqUni$4aM=&>d4|JU-*Pcp{K-&uN(O&b{2ocw(o9wl$jG*I^jJ2#_mbm+3HCnV+n6g_4EeDTVmiyRgEck-YMgmf>zL!c`d${GF6sRfu02ZvpB z9a)=y86#AZWB@-W-mVJ0G4iLuX84&q4W%`?5V82r-wEFu>G>8+qlLlg7I z^3PB5zu!g378Ky+n+_cj<3WQ!0t!*Nai+Mzu7Z_+EN}cyfc-(Ha6-5d(PDzSU_ER5t?;uXm5_2m`%;;lnSRylNViiW`E`uV=TT_xgezzv(5XVwTWQT;kvGS zn~r;KC%}u?dpuUH3|w{b%kAGQR!i=yIHE8>k3GEJ2)Od%v|d0ceSuK|_UPbi2fckY z^PDpG5{cNM1~&V|Euyby)f{THR5aqopl~xsdx&dp%0Mi|a=Gt+U1n_j73=f=>vYW& zH4oFhLU{ZAM{eYJJYPew5yyI^0Hi&AaWfo_FM8f#!l<9}DdY!}79~S`r~4X+b0+yo z_tyPG=m5NU`!z^%X6on>tf8M~Eb-{meWq&nwBe(PV;!afw_{lEO=mhNQ$}?CwD#dC$U*V!X|#QmL)?1Netc}{ zI5PQ(53s$@vsng=&NaE%hR0a>T+lIOcs5GZWKE^KOMi)00@|pp&>tJ|46VmJFnx1J zh)EMB{SJS0c@U^ybTXlZzJ5V=H`x;*|13sZoB?&HPU>DfZgTZ@GQNc6@YH+pR z!+z+%UMfTLLmaDyafDCNr>nOE<%~G3DG~#Mzg=`GDFarZ)n|XNGFD5ttxctRYB^Mo z=Whe3U~%32?}JpdLC`PR3Z#P+2krk3_hGfO$q1Y>gWUAHrfsFPZ#t4nYh&#?(|OTe z-_ZVQX~pkjOlgwnqU%mJG<*!W`0^y0ZMP57NKIiQkKIQFA$gG&uW=_-6QSy}Sz6*6 z|HePIl!7sAc}`1neNBX|<-j(s?^TASe?d0mHU#0_G2BGHlTEg7_3|Hh-k%es<@2F)H%(q!=J zR^pR0IU}!<3{a57B=cKpZMJ1gs;TWELQvIW!6|okF6bwDms&)U)&Zgxgoad3wNNd) z*P+XX@X^hCPUtQ9%hj(|>Jh0RM7vKqxq+gK(*wW)%?7>))P!789+fsMq2$T7WrGv- zsa=w0?mWar)Zm;fyI@m5iEC~xIF8a3a+Kxn)M^6HsXeGF?e`*6p4%G&tN33>PbIq* zH*+e;L}M0Ko!#|6?92-Y1Y`IaX7G_0WCO3}NH>?fVKLkvzLwON(6z{_}ornwPfj{HK6LpfBkv9bgUx{bq?SU!j zc{(4v#6dPTRQlOT7JVi5xw((yZN+88FY-dy3;QfBdttlgc(AMjWtjah^Be>Juib(( zb7K9U2VA7HM)^AMPB`{Fhl}B@6k+Zby_btBtYI-LH1&OBtUsXO%4#Uc0!&AA{W$*E z{FVPiX!gyHE>%c4Kd3@TuSC)i7iEybwimHGp~NEcT1mU3mu>wEjVC40^X05d{ZeN_ z(KT+Mq;j;$lg31hLGN+?PWjI3Vq(*Z$4(Hqb?C@#%0Ev$=?laIg$gKKAsel;JP-+H zF7bocNGuy^dCqpIkoT;Z-9C!=n^#}cB;p_>{_R}Dj}s_-fK`2x6JQNgKTz89h0E zN|Iq`F;+x)s(}mkvUGUM38~wZ{Mwd4K(5e>UEDt?p9xX2zK^Ble-|$AmR4;wc_n+@ z^6k(n$~8q%`S68tKoP(TBY<L&Y;K!#*g%w%^(v6DkYoH0R61jz@{WD_fL1W9O%SGMbTh*lX8Z ze%-8+BfDj+E3;S^ZPpsh*QTUK(pq0N6EFc=%Uq^B4Wx(#ek}j_$-7~S>>DgTP^nk5OcvT!x~MJ#y5>x z*^iA=+0^7_3v>S4C*G;(yRk}GIK@A^ETXD`%p5*}aJlprqop>eJXxZ&y(!3Am@Mu= z;1Z*r-W;5!8i%4eqQ3*5w^6V0=C6G%k^(m?HoNBvNXbZ-o<4@(OBl6az2~@qpp&ez?s>t`T0NII5>g@YeP! zAw0)JqV6rPy0f0@K)0lO2DZ}(p@?SdwrTz_*78qS4TSw&NMd=K_4+xUCtrCkSyohn znm-~et9^RGcc%n&h9+9!(F$2W$Pzg}2-CRH&FnB3j1Eupx@OX` z#vAWibIeW~n$QA?5hi`7Vqz8YWEvud^oTTxp=GtIh*aE&+3}xdkNmW(B1E+!CCI}> zYsvnSUC%s;(7?b2fX~$)Jzjn!@|AD;ilxn~Ja|FdxGXg9+#B3nWJU^Q(u2eqahqTw z&im`X#>mh1X~L1xYlA**@W9ku5xGieh+rJ}J%Q6%Z#Xqb5i?O*JVm8804<}AyOPAN zI)83Ta?7k=J@8}0i`_xDz!^(R+cgG{Y-jldvT;;EugRqr!^;4v!!A~RCv071N8FAx z3weoxKkw$yFMUE9^!u@ZQ^=W2!!%cp{iHjgI2~{^=rl;iQ~gUBo%_3(Ip+6y!qp}; zLQP-7&HI@b>FAk@;C%(hc4t+Dp!yor<_L0Wy$#Gs+qjNN=frmGJ_I9RkGGXeFwn2@ zq=yCvDxmPYzBU_1@n9HuHEk$Fw|#o}a5fs0!xN!$tD(a5utu0YiX8lfL!6B996P1% z12Iy%4f+I}=0tGM3wrNwCJJhyO+C1)!I(|_=V5-4>F&fI4vlI$Og-veLgtO(T?t2U z8tS7bnS}BKKQB+AP(*PZsB=x7`K?IB-fdeGH;1s%4gIIl-@7j~mWf2w$ktZoQIG|G zpQb=YwZQJz_ZL}Bl|9t&V;wRVZLIc{zT}EV9N@e1&^C9h*#3MWV~P%`Gf(B?4c_?q z_ab9V{c#n6>?pReTLP(hM*$J6Ij0;1hMfg&Uqy~PU-t=3hPL@^SPQeTZ7iE-sR zyUCO7F!412Oj)SlkFxXax|&qYvOL0v4pRnQtDruFtC(%^y@;Kcbs}j>q{hXYrhvC@ z3RN09xI@5|-h?O^9-(^5pdbRDz46A^l=mCW+?7cz0)a$vBhR{-0S@Go+ zx79DV{*L%Iy;3g=d7>jA&MeKPUi+mGP^@RzZ7C!bUJ=CdkZA6H&t)?xBDQzQqNn7; zqm96CFfTw%x)vsmugPLR^sdoq_snr;T8NtaW2yJ*_OPszgxa;A;7eGrKOy?l!-95n z1`b1&APviVw4g@@OH*3PBCfKk0E!)Pl}O{|tFvDwwtcOiO3Zl@Uix67`G_R%3P~#8 zdhifu2@uXc%#1WP;W;{9q~E1t>w&>L1D;`v#-+Q)$VrWcPOUPL{*u5wMc|&RXBw1p z692_dTVSo|0n16%+Lt1)CM?zufjj1T}bi@5P4vd53ftAE2jaG!5D1&0)};Qt9$BdOeI21yb` zRaUMPjs3IWMP-=w^qV7EiTAl>?iV^gqUEnMM2n=A!)cL^QuZ#V5LlI4MOT9+O-c4x zIso18LJ|Y=o$`s$bz7KX*Wu%$`79RAxc<3aV4nhi5oLHA%LSQh7>A%K8&sDJ0oG<6 zc9_t)Rmga*5zO{36?$(%rAhMfD9QsIXeQz~kqBl#z9S^pXsx6jwD;GiUFz0S!xvx! zaJD!&Wxz&W5u=j{%Z#%{IKhF6<#ui)15CZ}al3^149n~w)xTmwMutE)6ZN!ZLQLNA z(LTyD>s#v8#LzPjf4H=Wrs;{AjW0mMtIo1M4<58>L7o~6<~v@Vc2x|RTyeXG1W7+i zo160Sk^B_Ta?32Z#ZM6!s4f+ns7LQjPG&bvY?$zvHI~*kVj3s7b=lORtTKh)*S1gp z3NlkaQ!e(tt;Wd_>(5uVnV_b+)W@=3DfR!8w;9bBzH8A$U6{AoGLT%**AFrpW)gEv zw>h!{$t}tIu#49jD>kJbjv7{cfz8y}0-gZHcN$x-^Uley1CV^+9N&4LjJ)c1um;+0>x zgiM=wA?H91V765H5M2d&N-QjDS{qmZ#FzK&V6WW?3iO&;6EivChCqb!VL&rV5Pje| zn{=17P1)j)=I+bC-{j<5xM3}5*C;v3VuyG@^eRKd%SW6QDskLP)3|ARo9X@wB z0YThhUO(RzZZP%rEna(2eMTcfFyLm|mxkOsNK8^{y={bwJxv)qa-4|0{6#AifH113 z5KL1h%&9_9F?u9^1p!7Mb^+%H z^x;|S!spKHgU9l9Rjo;CZ_4}@pikyC-?YxrR0DMzu4Sa#0A11SoUAvG5xh>GA=WYy zNiKL8)&Q<__+l#BeG@cwUZpyS*W%E}8Wvwt8(>rfLzdKdB@cnOI@6c$i`1~6Azb_4 zU9t>8_L)nv<$AO z*LGuHv$Fw;OVJf7sc?REy-fTT38BAh2ay72Cu$-hO`q08Tb%zNGl7djb8Y~42F<^- z6khMpo#N@w11CXe>211$lI_kKi(`?ZS*!dCApKNRE_Ux}G!n%`<>>zY7MtnF6*e~K zys>gF_-hSoh>5-GgbV-H0nw-I;dr%WVVP;F3~z_f%g>xegekb;HN6rm!4dcMnalK(j{ zRl!;UQNq@nb|(NM`C2HURk6&h*)*7?1Bjv9WKiaCEdb;X%B|70e4C4~kx8o~>s=cizxBo%d2Jd3S`xs0i zq9OgQ=##|hs1YESysS1g*Mw7hMTy;O)W&#tL5Wl3?w7jFKe$YDoU_VZk=@&pb9s#fdh)z|g$LO$YP@VW9D2ss z=)n5FBYePaxK;O|p4_n{C~0~Yu5(H-eOeLq!(GVN<4YsP^h7W8QqLERA+{*OD86t= z=lR-~JXXgeqD1iMc0w5(tJhSk!9PUdkQ7+*Uy*)CUV_bfscV++qmczjdq1#uTTeFj zn5WR-+0ezX7{B9zf6Xv<%NO^OU}syhi7RncRjYO}T!JLvhrxpnYBV;v+lV`+yVw02`p0(C(HS2B7bowU4{;wzn0)uIo#=*! z>C@csU(GQ{p;AOUO%MLAR_{m}zSc^!(S|qgea~HcvK-x$A{H%Mj0U47TDL@;>z8B0 zo2z1(FCJpa%EP07dQWUz0wZ3dM(SzDl1{A3Nts*rW`!XD#c5l4tVX~({54-%79Ev- zK+<#_=m`S2tYgsze<~{NR0wVJhDDpyvBXt;x(~iCdc1Y&p2w)I5f(#%nuLOMTPqsp8@Ct2BGDQ}@y+S!bVMFy4NTQRfDuNf{JQ z9vFi1G}T`C=0bG9U8A7&Tr4qOa$3iI{E~3ANc^&d8kF9AeIY)SlG<-YsWP|ZMWHGn zY~F!vN81ax3q;#|EZixjQUC!m6kj&Rda^KT9@WUj=2 z^YbnE_&cQcqC!zYw!Wd@U5rYSwTH_@tdrHP#wL=}`U&)apa!cLKk}0`(9HFgZ;0AA(yeC|n!}i4CuGcnl ztFh?55Z~5KQzy&S%YUmrhaGgTwOAh2+*dXgl1=fz&pW<<5RuA_0H4vSGA1%{NmGOy zPYjL}x#&9gukXDk3yI3nB_);cS|y1ofkDePa^PD)o`PewN17eW(`dS=D|LVE(D%W_ zM_A{w66|&R!WgTjXmzs3yH)Ay5Wkff_{aNkKJ()OZGAdWGl;MYtMBbhrOp zh!0J&zKEPH+zkk?GGYWb;Ad#0BB~rN=3e;z-Cksv+7MaEqU3GABD`0ybz@f2Y97D2 zG=Fq#jH$&fsrtI+BeXmhj^?fv?`CwU=Wj9}W$9ACGUfQaQnm+mn!P6me7naUscQ_N zrs>q2CMm>L^w=@jBZRl#4IOluQeL#zz70t_L(x*-M46178a-eGVjM*u%1wYo$Znw7 zK`n~Uy8@1C$?Sul<_Or;Z-AtkZ#R#jix#!<^fjLEqB-;(T;K=oAhj)6FGZ=g5Tl$R z_xtCD6#?~+rhunhKfuH6O*MYc^oJOV&Fp;K|0LWT3&s4FH~TW@+TiEkX$0NoN&MXki5Op|L;77n#0NjYyKd9;lJ@-Lc<_PA zyvPfzZ^*bOdz;Z-Zo+>e^&;V6j4?>Thg4Pw}aHatj~$SO6Ya&j3)s zsBt|z8X)-S>bET`Vh8U=WJf$WQP&Iq(7$lmq!KFAr7mu|aF_1mXVjv*tO0mHBH3 ztfb?W|J%gJAM$vV%%`llO_e0gsN?6|BggK+_y{VZVNe8E$LL6VrY5v zgT~Ph^y249Mbt8Y84ApIT?MLA$+BgW-FmG$2m)^}H)lh%tB5gIT~Ek8CIFtu@yLOd zEuwzP#>{?Ie_8u?bze&+Y>GkRA*klrU+o8s5Ms8?7*DGl2Luvq8IOgmu+br+DzXAR zQ0%WBmhES~9yq!j@!)QNM8#6!emBX!$y!bYwK=VlrQ!4yo#OXY?ijk)Q5~~HTOJf{ zl?u?Z_Pk4|p&`SB$CjhjrSAck-;A#Gha2?k^hR*-1qyB!x4rcQi45qEb)b_o4S0CQ zvdGAqkSdio5tr{!nR;LLUO!9fU{-iZ)I$!d!RVuwY1%0CJUq%Xru4i{0L7y3*j==1NPcnm1&Cc0bu1Eu)9+ya0H}! z29Fr-DXO8y7NNXd2gX#+)J)pZuKm~37{OIeEx{6*cu1d}ZSnN0d3bV=*Hr3(sXMZC zn`y&`lKCWWmT!x1Z=ySFd|%3`{8zOsM%Wv}I&K%fmn?UJywfuU(e8R1{MSkqlOXSZ zLIz(-Qrdwsd^B=v?J6BgYp2}Jf_-yfbkSa9&&`Dr3}k_%93r0!AQrd=DbfW(f+^M4 zbf(>E+;N&NCzE)Y7#I0V4PDcN%A#_jr2j-r!$}KQNb34+fo)?DM&U&q(j4Ltm&9X|_Xw_}kbOMYhEpM-)qF!jZNl~YYFQA?n0(fq@kQ7kzkGwaZ!d+i;6?JFTYK9RI6-=UKeiSW{5c9eT-CC239 z{t@iV1TZ1CZp5qnMU)kD!c_ESSyc{uT&KFM-O_+RqN9LAbiHgECwZS}EiD3SEG}qu zwRZk;|H?)TZe56d2X;QXhV$}PY#-;)@ABPYl7=tThjD}Atn*v+-(RhjPI_yCj%cRD zLA;bi>ML=}VWubas^j_i$$F()+f}H`Q4jKaADoX&y**+p{Mo5jPzMK8=9nF+wAwOa zS}+}8yd1e!NdZI9W7LR{VNNmGY(^J=<+=F^J~r0IJaqLsmliVN==Ln^k$Kmu;9;5Z z$=OceQ-nMj)cUkbZ zEZ27WG4Vciq=lT8txy+NxJUv%!}XDnGV{`&elQv*6HEbf#oT*?-vDd;8)p?O?>zQD z`L2?GQi(%OIdU2`TCie$NzJntYeXWtJ+lxz+Y1w%LwWxJe&qw-sv1(bogMs>03^~w ziaVppd}$^Idpf6@7vnMdZ&?M+q`OI{$(h$n?^n_>wkyQyYZ$GyTCyEe6@3BSC|fU? z+x0VRo5+hjL3;BAg7X3%qN!#F#I2N9`)^3yOJAdkLA|zb^MIHC6?7vsbiu$o0FCJv z`6>@V(!W$w$~Ys9Y*is#(#Qxq`US#`cR-@yGL$YFQXMe_*6`KhaoDEgkJHwP^lXVS zX*GakM@L#t`K!E8LGeBT+9hd>zz3uH?wV2oN@9)ze#=8-Q18|-R?ckG1^3RYEeY~Z znk|hdTa?#LjGjwaQCQDkNbh|K99Mp-VK)b7uZbm@d0v`zDY1l!P2{i;*4CPB zW4pTG0_1sQa!#d(N`1$~Ju<`5zrBLYg<~j!N$sxsF*+s`-MZJW>tszKirR8p3119; zwB3RFl{0@DDrBQF>94{@m7IUD6Hddy%xrVDNL6IQjF1rQUk;Yu&aC@WGcjUK|6*+# z5%W;~R(Q`y%yS1^P1_@Zp9)I)2lRS?4iAfIHJKW#LA!nMI=Dq5oSdh~xD_2D*P z#5okD^DqtQ$$10%l1cFRCX`HUNQ+gBsCWd2P8!b}oGR6!o8^1G>rL8CN0)Oj$rmZ^ z0|DP59wi)Auko(8h}J;XT*RcA7PdL2OM$_*W%MjT6<==?O*Lunfj7i92r!nY8ouAP zc1r4;OUL$y=RqQ@$*69)#R(F$poG+<_qGUE=8Tf$X%fXk{EA=inL<(l=u)r{rSOSh zn#^CPf{?N;6~2f!7riBGPi6SNb(J-)FTK64y+f5@qB|M;aG*qM2bE!u`Y}#1 zT~$~m!K(@(L%HB^)H<)H-O^qEK4@Fh+=_<_Q~P|!Z3I7O!|_~dGKFcy?6$uf{leu9 zFP75(e&Sdjz0*eHHpE6<{?G)7n7vicn+}9Vh0P|fDTW+dR4gie@3M zOCk`=mV+nsJ5bWsSLTzRGaQqe2EAf)yhX0f)&h*$K)^=GYx5y*kgdI1&^lAha<=-j z#4tJfgf;qlU4(Vx2wZ>_a90+VvR-+2xy2+E4%D!fUTwqiPT9E8mQn_j>T5r9xdW&? zCnf3MR=(+|M6J5mrVyQv)RMZqY282Kg4X+4UpehI@RRu|n$EG1A6$K%(VI|V`@ zYBhC&vxc4DY|LP&!pt=kkJRridSeg(PyJ;Vo0jg*woVu~6eFJ)NfKjdh$r`(#u0G5`~tHmbg<2f=KBv5FV#(>5PJE6|}D zM7p9{b*-1|J%^sjy_IT?iehP!%MT!vV-|*x`G%lz2d9=k;#SQFQ9TYQ2y8jDjk5OO zo-q&|QzbOS_CZT7>T8k_{J=jOpP6Q+{C+B0!?nP;*vBns)XpA(8W%gY?^<<_DbZK6 z13DTk+=pxD#AM z@L<6$fkA_Z;O_1_`91IR)^6?Y|N94B-M72?o_p@;PgQr-J>7l37B@G$9y;i6 zCx{+aimNVCc9A$dB(TOBzp2UvMJ5Sme2DQi*7!iP{em4JCtI>RQUtn+dL5y9DeK&} zJmkwKE|u_D*!x{%P5Rb%YiH~Aj#BgVa-sTHHl>-@+! zV$L9KtqBM8*s2BXWsmaail@URaNXVKOF!;lDk@~tD_>~XKVWY7rMM zXh8uWG>pt)lP`pG@!#tft78&dW+Lb!WYHw_3!;rxn-=xWkb?5+^PUi)?-M-}RbwjX z?ru=kXik zs*^*AUrCc;V?RZ4nR&N zvYrE{S@^~q#q(a+_c+~|Ptf7=K&J-er-G)s2Zk3#$^(W5Q2!ZzmrV;#6{vInwnqM3 z=|NvFzG-U_&-4M)piNsQbx^WyjAl3xPoGUO%R-o9V* z!{BA*F>ha4-bEee(!XF+)BeeT=^(hFy4hwV5g87P&{2)N^UUn#8_%>s2CC6w*Swn| zZawvkG%7x5ME$Jb-**+qC~5d<=1I|?FY~xfmIgm24=-iJcI8a&SKcHqGQ?5?DhFoJ zpyUjGJiuNO+F1XIgJqwfDLSgB!XYGVn{RlP3&W{q%#WO}9BbsqZ zz8d*Ohn*p19jRgmsS*2C-@^oo+Y?7j%r8R}KJCH$aoGLi<3zgAeG}ElQP)A(^q8x~ zyy<8sT`}@?F0SFHBXb`VjoiQ6zk3-?_G-7R{<1DPf!xL&Tm)_6JUgq{6er`a^0`|ZT(XR zr&D!Yz(!8vO^;);;UjCIA$gf_#+YYt4L!#$(ras0CO%@&I@v0f&o;~DWFfMm|H|!- zvU_3-Tn*r0#w{U;i*z)G%_FpZVQ;mPU+6D$^-Ea}lZrnVI-<_=;x)9U*5-Yfj6(n` zhh=MkAGW4X;5u_dioCb4&`9B4mZIGbvVP8ar||ZV+!rOI`(II~i^4Wkx7k9JibuV% zugzvogTpazPL0c&uFnO|Qpl)RFNi#F98Rlf!6x>~uLv*E(iV`-4a*ZJ5U-3MvS?Wp zBCA)NV?Je%&EY|_TH%3LZWqMYdz;>Zid-^1ZIQ-$+}d^@>Z^?{4oK%;(KG6&(B~e& zxK@R!#QTn>o<+&+MT2&NGX>gSb-K7`K5vNhQ36cb^;;CRCM(@?huY=%`L@bbAum#< zI>h!a4%)9-;$eTYDYfsFe@DXZRh)uqe3aU2nzm)lKBuqSGaV-BH@AOpGmA_<9L?(s zs@fo#gap(=znDSPvJ3ZdY*`&@Z6okIuAS&FiH2PKat4CPYInqX&gy7x+;plKHnc&* zs`-Y$vZ9|_wlibg$O(8EJ#+Km1iq+VbuZ^sZQq65x}7XN`zTJRn;~v_;wh@}IckY_ z$s`NCtv^7~vAMPC;hb4xSDn=#zFo6fCtPSk#;OUUqwf(A3bT3VzB^lGgC$f;9wtA~xmdo) z-uT_mURzEmyPeh#vpcOHlT_9yiqib)_()Z4Z9y5VLPl>6_p1z$uiEyRC2rY!lgVFR zOxTUzhHn}4gIa6{_}>M=^<93r$B7P^=cD{gt+S__p-zAjl9KMR3$Cxq!H?{Aypis_=C4lE z{XAaKr3b1eCzLe9y7Cs_#4eiT#?vT?_ed_EVrfh0kPXP3NjB?vUOrfyAP?Py)*=L; zf_R(CU3E%*;*wNtXYoWCC)K;Yb$+Cc#05ynHRk9aw*;QUGvI5`pxxmp59&2wN>3LU)$`-NbR(3M*prC~$oHWo!FJ>fSJni`v zY!VskLh=I);gZiOf5uOV?Q2r#uxQcr4=Q_YhWkwbUh#y{Z?70s41$EB_qB+5^mAhK zOi+6v4($AH#bEy2vE;IFKXVi6(uKnH65Qo3P0CxmLBF(8my)OVBH(EBu-4q?^-nF9 z4GQV*V23(zn;jCX6$g@Ix(%alri^>!x0`u%8LP%5pMGS&Y8bkXqMBcF^lBKZAG%>R zv%@C!3%bGMAkFF@!Dj0;j_aZsC$TTTw`7QT=hSYK>xOPE^rA2nQ+HA9I7Qk|4OzXt zHGdym~$U4?Y@pAF9YYVLx+d2M}9Yhh~+6lV!iVXLh7Cn3f;98I>*G19l)K ztkD#)tM_N%1SFKCs9)i>ana3r2Ra$h9J5`YgAMOH;{5=73}~(L%kIO;`gMWY*-X z@tNA_t=(*hPT(8NZxF0_?qya5w!4EW?dQ?UuNMRxaYUG!ZD)6?SPP@!>b8gR8&~w8 ziWwhErNvW?Nl6$!&*F)BgTmPAB6r5+@cf<@A77%ZeE#O^sm9n434hNlQ-eF&-&nJa zEi&9H;+4~2pN0b@J8lgP2MMH9O-A=yT4em-k7HSxhaCTt>Im0=QXSFofI)#A$`EUH zXWM@(i~zX>5i%kiGFCRuP)Eex#?%=q1vRrbM_9fE3iAA|a&&SA3i1p57qO8j14TGh z1J1&Q_D?W-EJZ6w;dQL0D_fIgvNZ8q2pak^2(s~z9Ln92MdrBPY(!cO`Y22h!BpU}KcA|`JNSIR@o-^Zc|#}U>u z{E(_(8`0iAkN&0vt%4&{_r`szCLk0PIv#Xt%Wgor0%DsNGS6)Z8{?ErS}tMCX^Jct zDyWYf)IkU{8M-J#qH||~Miy#zJW0BrqSJrSC)O50!IIbP5rqj=K(VJB>DR)p4MKKmtoNWI29q|RQXc~r?`84_UAUrpL*-h*6L4aK`H)_Dn97Z z%j#TamS1Ug+DRoE?WCfr&EQ_N(I-ii;9T6vMSMFK-Z6YNecmYFhIrZme7iRWSZ{Q{ z@}e}*vhb?9 zh#M7u5|ES&lg+bMXB^RZ4ZF;$vg?`8dTvT!XE>wHI<6l8smc`E!VMA&+Yo=k*>=hC zus3I)Y=3`s)DV*`#`a*?c6~O!vG{Pk*N5jTYVD)(!EMtDZ~q{PCdvN(?7ji-2o@g| zo8(IaT2qCR4;TrnZwC^9dQ^in2^CJ9f>1=Or%kM{3Z2~JB5K~!u|fVDhEyjZsjg1mcKa6jy?!E;6$EQ2|ojX@qiYf z{`;j)=GhaKt+*KU_iMwn4M*|rl;gJ`Smjnv+;hTO;Y>GX%weI-0S#Q;DyA=8Z@RON z0T^73l(b`chUi2TF=6iO`ZOMX%anKtm{_kA2!}8jJOd+$(85m+-?U}j01nMrvqx3G zNj2ae%m7{z`Th7UCxP6!Yb!-A=Xu0PfMt@5!PmXB7VJKD9k|}Cu56$D=hxE028xop zxQI<|aSnC8iiQfFK8S#=8P1yS-rBaDa!Xp|2d252<(OJ(y%qoxP1jy$G9k(jB!pNR znysb1W)ifbPwbY@v7!>5ep?WJNwqyKdO z-XfS6YQf{ceTlBpB6y{WWamC@hC?zQ3{XKbZL)0nIK|J@_>^C>&`?=>s;Rv`df%S} zQ@Y>?BZ!X6-@Bdw%QekyxpIFr-YG`2K55g|#E`$U?Zx{^3RHbr{_O8fcIoTm+EcdU z@#9j9^-=0l%IS0&9ektis9rH;!q*OEF3d(8FZ%g1PzB4hx-wb?G|NmW-B1+Jd-Mx! zorHHah1of}<)2rc`>9AXcw>y$A zyHRp5Fsb;pZxo3ZNTK$anq`i874*pG0d8vM7^zMG%ux}Q)dwB&tH;hY zQSV&w8?AXecWKKvl+V|AKat`#dT%bZQHRMmX4w!#YeO*cO7>zx{b{AWvy(9zFuVG2 z7@o;d=Se9fSasPCr`8x2y=62in!1oHK{@%7LL`)A*P)s@;rf$RVTkw<9Jac_%j?E|pdT-ZCw0PFv z)Ogm4^fh`wc}dyloPH|fJR&?hMkmSqG;5m*LG*^I;Ru3X_Cwf zn}3h4jg<9F(wu~6RGa2qc2Z0`CkZe^n=`8US;A#sdJbuBTJ0ihv^t1Hj=t}?6Ecx? z)`fpD+g5LUhVc{})%CgYOPVKMR}Vzl^97yvdG(atB;lF30j1k4MW=|HQ&}8L0ORmC z<(sow65J=MG@dWE??&eVMNd?Oeo8z)34vSL8S8W7P<{V6H zZAVim;-&P-OP zv?}g|Ljul>`Tkjm(yQ^`#q@e<9tT*(AJ zXeYf|`V-hVnf8cM9Z@Np!=Gw1zauV{%r{UE zKV_VlsxSXg84f*+kc16Cy~CcI_MslG|3-<0TJ>`+YAB-kVyjCzTkQVm<^_T3X3y9r z-~Pe-0n@mZnKH~@?1@>edh~}Sgf0QzRkIEpD{7g1SOXX1#$uumR{}j53yqHPPd*cI z-<#q<7f=E!C6L9Fw~=%GVX0QGk}Qo`LSxJ)8KET2KCj*o+KN^<>f5i z+RJ#^26=(X@mnj{3C0GMgc9j08ybNGZ_nYg8qY|Yj^^IWXFcyDX_i`yi1qq9eurP} z#%~a?gNI!`qy%snL%+^T(6bszv{B`g$D5Q9 z&tk3J+2mHJY`}@HU*fXzBd-bYd4xHKJ|naML=}WK5R(H!17{@6wmPCE%$6ECnNP_u z1iySg$VPX2dhF%4#U#fQR#!ID)=fTAYYcgAdC!rH8_OcINvR14_>lVJZQfm>@M8H5 zX0=!Ga;dZ=&H|Y%ac&PCe?c&=VI4|Dp0Z}acXA)tw4h6!7eI55I5f4?HDX0cv$@9~ zeM`7MJEwSInRG&9>kE3Wmas}2>g51D@23^R;LK|*+?e}87Ys3YA$-?s8o6^${SJJyYAB2i8#;Q{nC7Pza;M%|ETrH$W6pHJR2QU~+2ChsKk$Mt=! zOki_MEH^rI0D;)A1&D}9d?>%=`l#VXl`aMe&R$%rrf`T+QS~+%>Kwe(q4bt`v$J6l zeXI7J-)YrYt}^Py4zP|ddLDJGZpSlwMMt~ow?v>r=Q5@Ix2S%B{vtM3z1TPUDa3J# zC9+;Hua^5;80EIYFIVla5P>rc2n+f?TK2ze5(Tmpe!}c$DPr6Rp+UBD0HvyfnuC0@@9sL$W zt3xSjqJw^V*H!dm`bL_+N|{KU4QLeg1S{{ni^Xg+*DVu>#%6 z=FXPfTZ4;pSl3t4`>RiSUfN!!0->@F-b>H2x*a5c5(R4;5OGV}`Ry3v z+HU}<$KTJS8_w|V53+l!J-2i6?xHTyL(HpZF5u1o+-?#1BxsIg%)yt<8&BIcs<|4_ zB{;v1x{g^xW3=wrsCWc+tA+7;F#(j5@a=1-hCPPuPAd6EX$YjQGa6TL4u%d%-Ginq z2>Dxm52A;@lN00 z=g|F+m7PM(pQ#J=;{~G?9luC_amHooZ(Opk0V2FsOSCt#-toU)KypE?g)&;D7_=@P zPq17{_Felg9`R@_sJKY>6k76q%bJ{c0vC!AR>b&(Lqq}MQ?VJeAl$i{7P8QN3t~na zK(`{zH;oM``GC+WI?NOaCF~_@f^$lB;p0g1D2;aIr(NuG#~jdquk>ieJ~k-IO$)Im zFSTmQVw{Pj+H7CzP7V1bk8Fm@k28PX(U!mWs*aQY5upTj+*;aHoL;E;1ft*5P>F2Hx9Yn+Sgv^h(mkJrph9nl@g$yTJ#7)vK^M z2VTp`9L+$jH+z%xWerA9c$u3$EquO|wlt)e{Im67C8H|9VC&TKYj8>$tz}3KS%5{8 zEu%bua^rM5JWwF#d-I|e=Rk!4NQ-@XNAYgJ`)BZ7X!=>#QEKKSSul1$BA{n57_ugj z+b;4}>9%j4c-QAH^`XgvUquT{#6lLHh+Xg$*AcQjoXi{ao>z7YeYi9PqAB^cG#B=V z*?#`v48L5HDi|m2Ic^VDC?r^Nsom*T_k;GmkX=X^PTX^xp70QebXPJzmwj@wsfP*N zq*}yb;5?sUjxfnaS<8{^f?xlQ{c_#6Z7t2shomaraNg}!huhLc-%I+gQ!%Y}rL8+L2NQa?|7oBO z{!asSaTjMxdq*IM8OR}t5chPpvbU2$jLU%_DIqW?n2VDe%+1Bi&Bw#5_iu~8)=H)t zP#vI~m9r(#5;4+ubc9+UsuiIgZuXAmPXBm&V{iVyJ5te*)?t@%v9W=e+SwtJ0U!-a zD<>dgg_&C*JhK9|ppH(6P=MU*Ts&O7f?z&gHZVIM8y7ndCp(x6XaM@#zmk#dhZ7gYT<6>*)1myi2AJp8+%o#zI3ykOt$e|6?2XXK1puR94RL~5<58>lA=d}QX5n#Zkyqr81{7^24IiCesP*j+U(_Da$pG$yG zfYY3d4`Rl{!_Q^P4S^ygTm>w6_;^GO|4VXZFG0kT(1En~AkXbW8Pbhm+aXuXqsU}M z{JcA0WHR?jC~Vvay*Pe%cRUNy4-CIXPn}sp}LT{v6DSn^*b*5zM#CF z@LgM3qLt4ra2>Ax8+b5U7c;pceT+5qP5C~!G84F%GpsoTU>E`zrisbk>xsDK+_lJl zM~HyXsEH|G*hYKZ!f#G?nyq=hD_mh1ocFnT9?CWn!$$*~b|6)yKFe0sw?U?Zjs<1zbL!%@WS^ojWDG>D%uvd!O}T@`IVkZDWZMmp$*G7~@PUC_Japt@?9LROmZ zPV{9-_Cs#+wS7EXS;pZdoS*z5*_7puo3uvaLHha~r$ul*o6H>X3fI08(?4fDyGU*I zBkS3EC(c)){}`NWaovlUA#B7Bp8~Di<^TI_4}4r62|N;bB=AV!k-#H?M*@!o9tk`W zcqH&h;E}*1fky(51Re=I5_lx=NZ^scBY{T(j|3hGJQ8>$@PC~EmXouoqq95W69g')) -``` - -### E2E_swap: retrieving the used priceLimit of a swap - -The priceLimit depends on the state of the pool contract, it is therefore easiest to retrieve by using hardhat's `console.sol`. - -Uncomment the following lines: - -- at the top of `E2E_swap.sol`: `// import 'hardhat/console.sol';` -- inside the swap functions: `// console.log('sqrtPriceLimitX96 = %s', sqrtPriceLimitX96); ` - -Instead of just one swap call, imagine Echidna reports two swap calls, and the second one causes an assertion failure. - -```js -// to get pool params + created positions -console.log(await E2E_swap.viewRandomInit('')) - -// execute the swap, which will create the above and log the used priceLimit to the console -await E2E_swap.test_swap_exactOut_oneForZero('') - -// execute the swap, logs the used priceLimit to the console -await E2E_swap.test_swap_exactIn_oneForZero('') -``` - -### E2E_mint_burn: retrieving the pool initialisation params - -The pool initialisation params creation is deterministic and there is a `view` function that will return whatever a specific `_amount` (used as `_seed`) will create. - -Write a js unit test: - -```js -console.log(await E2E_mint_burn.viewInitRandomPoolParams('')) -``` - -### E2E_mint_burn: retrieving a mint's created random position - -```js -const poolInitParams = await E2E_mint_burn.viewInitRandomPoolParams('') - -const positionParams = await E2E_mint_burn.viewMintRandomNewPosition( - '', - poolInitParams.tickSpacing, - poolInitParams.tickCount, - poolInitParams.maxTick -) - -console.log(positionParams) -``` - -### E2E_mint_burn: retrieving a burn's used position - -Uncomment the following lines: - -- at the top of `E2E_mint_burn.sol`: `// import 'hardhat/console.sol';` -- inside the particular burn function: `// console.log('burn posIdx = %s', posIdx);` -- if this is a partial burn, also want to see the burned amount. inside the `test_burn_partial` function: `// console.log('burn amount = %s', burnAmount);` - -Then execute the burn in a js test. - -```js -// show pool init params -const poolInitParams = await E2E_mint_burn.viewInitRandomPoolParams('') -console.log(positionParams) - -// show pool mint position params -const positionParams = await E2E_mint_burn.viewMintRandomNewPosition( - '', - poolInitParams.tickSpacing, - poolInitParams.tickCount, - poolInitParams.maxTick -) -console.log(positionParams) - -// execute the first mint -await E2E_mint_burn.test_mint('') - -// execute the burn -await E2E_mint_burn.test_burn_partial('') -// this should log the index of the position that was burned to the console -// as well as the amount that was burned. -// together with the above output this should make it clear which exact position -// was burned and how much -``` - -# Verification with Manticore - -The verification was performed with the experimental branch [dev-evm-experiments](https://github.com/trailofbits/manticore/tree/dev-evm-experiments), which contains new optimizations and is a work in progress. Trail of Bits will ensure that the following properties hold once the branch has stabilized and been included in a Manticore release. - -For conveniance, we followed the pattern "if there is reacheable path, there is a bug". - -To verify a property, run: - -``` -manticore . --contract CONTRACT_NAME --txlimit 1 --smt.solver all --quick-mode --lazy-evaluation --core.procs 1 -``` - -> The command might change once `dev-evm-experiments` has stabilized - -Manticore will create a `mcore_X` directory. If no `X.tx` file is generated, it means that Manticore did not find a path violating the property. - -| ID | Description | Contract | Status | -| --- | ---------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- | -------- | -| 01 | `BitMath.mostSignificantBit returns a value in x >= 2**msb && (msb == 255 or x < 2**(msb+1)).` | [`VerifyBitMathMsb`](./contracts/crytic/manticore/001.sol) | Verified | -| 02 | `BitMath.leastSignificantBit returns a value in ((x & 2** lsb) != 0) && ((x & (2**(lsb -1))) == 0).` | [`VerifyBitMathLsb`](./contracts/crytic/manticore/002.sol) | Verified | -| 03 | `If LiquidityMath.addDelta returns, the value will be equal to x + uint128(y).` | [`VerifyLiquidityMathAddDelta`](./contracts/crytic/manticore/003.sol) | Verified | diff --git a/lib/v3-core/audits/tob/audit.pdf b/lib/v3-core/audits/tob/audit.pdf deleted file mode 100644 index 7a7f0dc49436abdd9f8966ba2e274aa9dade6335..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 573061 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 Xi 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 =W+W( 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®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